mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Added connect and disconnect scripts
This commit is contained in:
@@ -9,7 +9,7 @@ ocserv_SOURCES = main.c main-auth.c worker-vpn.c worker-auth.c tlslib.c \
|
||||
cookies.c http-parser/http_parser.c \
|
||||
vpn.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
|
||||
config.c worker-auth.h pam.c pam.h worker-resume.c worker.h hash.h \
|
||||
hashtable.h main-resume.c main.h
|
||||
hashtable.h main-resume.c main.h main-script.c
|
||||
|
||||
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@ unsigned j;
|
||||
READ_STRING("crl", config->crl, 0);
|
||||
READ_STRING("cert-user-oid", config->cert_user_oid, 0);
|
||||
|
||||
READ_STRING("connect-script", config->connect_script, 0);
|
||||
READ_STRING("disconnect-script", config->disconnect_script, 0);
|
||||
|
||||
READ_STRING("tls-priorities", config->priorities, 0);
|
||||
READ_STRING("chroot-dir", config->chroot_dir, 0);
|
||||
|
||||
|
||||
@@ -296,6 +296,13 @@ int handle_commands(main_server_st *s, struct proc_list_st* proc)
|
||||
ret = handle_auth_cookie_req(s, proc, &cmd_data.cauth, &lease);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = call_connect_script(s, proc);
|
||||
if (ret < 0) {
|
||||
syslog(LOG_INFO, "User '%s' disconnected due to script", proc->username);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
if (cmd == AUTH_REQ) {
|
||||
/* generate and store cookie */
|
||||
@@ -303,6 +310,7 @@ int handle_commands(main_server_st *s, struct proc_list_st* proc)
|
||||
if (ret < 0)
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
syslog(LOG_INFO, "User '%s' authenticated", proc->username);
|
||||
ret = send_auth_reply(s, proc, REP_AUTH_OK, lease);
|
||||
|
||||
138
src/main-script.c
Normal file
138
src/main-script.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#include <tlslib.h>
|
||||
|
||||
#include <vpn.h>
|
||||
#include <cookies.h>
|
||||
#include <tun.h>
|
||||
#include <main.h>
|
||||
#include <list.h>
|
||||
|
||||
void call_disconnect_script(main_server_st *s, struct proc_list_st* proc)
|
||||
{
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
if (s->config->disconnect_script == NULL)
|
||||
return;
|
||||
|
||||
/* XXX: close fds */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
char real[64];
|
||||
char local[64];
|
||||
char remote[64];
|
||||
|
||||
if (getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, real, sizeof(real), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
|
||||
if (proc->lease->lip4_len > 0) {
|
||||
if (getnameinfo((void*)&proc->lease->lip4, proc->lease->lip4_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (getnameinfo((void*)&proc->lease->lip6, proc->lease->lip6_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (proc->lease->rip4_len > 0) {
|
||||
if (getnameinfo((void*)&proc->lease->rip4, proc->lease->rip4_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (getnameinfo((void*)&proc->lease->rip6, proc->lease->rip6_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = execlp(s->config->disconnect_script, s->config->disconnect_script,
|
||||
proc->username, proc->lease->name, real, local, remote, NULL);
|
||||
if (ret == -1)
|
||||
exit(1);
|
||||
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
syslog(LOG_ERR, "Could not fork()");
|
||||
}
|
||||
}
|
||||
|
||||
int call_connect_script(main_server_st *s, struct proc_list_st* proc)
|
||||
{
|
||||
pid_t pid;
|
||||
int ret, status;
|
||||
|
||||
if (s->config->connect_script == NULL)
|
||||
return 0;
|
||||
|
||||
/* XXX: close fds */
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
char real[64];
|
||||
char local[64];
|
||||
char remote[64];
|
||||
|
||||
if (getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, real, sizeof(real), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
|
||||
if (proc->lease->lip4_len > 0) {
|
||||
if (getnameinfo((void*)&proc->lease->lip4, proc->lease->lip4_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (getnameinfo((void*)&proc->lease->lip6, proc->lease->lip6_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (proc->lease->rip4_len > 0) {
|
||||
if (getnameinfo((void*)&proc->lease->rip4, proc->lease->rip4_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
} else {
|
||||
if (getnameinfo((void*)&proc->lease->rip6, proc->lease->rip6_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = execlp(s->config->connect_script, s->config->connect_script,
|
||||
proc->username, proc->lease->name, real, local, remote, NULL);
|
||||
if (ret == -1)
|
||||
exit(1);
|
||||
|
||||
exit(0);
|
||||
} else if (pid == -1) {
|
||||
syslog(LOG_ERR, "Could not fork()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = waitpid(pid, &status, 0);
|
||||
if (WEXITSTATUS(status) == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
15
src/main.c
15
src/main.c
@@ -45,6 +45,7 @@
|
||||
int syslog_open = 0;
|
||||
static unsigned int terminate = 0;
|
||||
static unsigned int need_maintainance = 0;
|
||||
static unsigned int need_children_cleanup = 0;
|
||||
|
||||
struct listen_list_st {
|
||||
struct list_head list;
|
||||
@@ -159,7 +160,7 @@ listen_ports(struct cfg_st* config, struct listen_list_st *list, const char *nod
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_children(int signo)
|
||||
static void cleanup_children(main_server_st *s)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
@@ -174,6 +175,12 @@ pid_t pid;
|
||||
} else
|
||||
syslog(LOG_DEBUG, "Child %u died peacefully\n", (unsigned)pid);
|
||||
}
|
||||
need_children_cleanup = 0;
|
||||
}
|
||||
|
||||
static void handle_children(int signo)
|
||||
{
|
||||
need_children_cleanup = 1;
|
||||
}
|
||||
|
||||
static void handle_alarm(int signo)
|
||||
@@ -579,6 +586,7 @@ fork_failed:
|
||||
/* received a bad command from worker */
|
||||
kill(ctmp->pid, SIGTERM);
|
||||
}
|
||||
call_disconnect_script(&s, ctmp);
|
||||
remove_proc(ctmp);
|
||||
active_clients--;
|
||||
}
|
||||
@@ -601,6 +609,11 @@ fork_failed:
|
||||
}
|
||||
alarm(MAINTAINANCE_TIME);
|
||||
}
|
||||
|
||||
if (need_children_cleanup != 0) {
|
||||
cleanup_children(&s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
#include "ipc.h"
|
||||
|
||||
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
||||
|
||||
@@ -17,7 +18,7 @@ struct proc_list_st {
|
||||
struct sockaddr_storage remote_addr; /* peer address */
|
||||
socklen_t remote_addr_len;
|
||||
char username[MAX_USERNAME_SIZE]; /* the owner */
|
||||
uint8_t cookie[COOKIE_SIZE]; /* the cookie associate with the session */
|
||||
uint8_t cookie[COOKIE_SIZE]; /* the cookie associated with the session */
|
||||
uint8_t session_id[GNUTLS_MAX_SESSION_ID];
|
||||
|
||||
/* the tun lease this process has */
|
||||
@@ -32,6 +33,9 @@ typedef struct main_server_st {
|
||||
|
||||
int handle_commands(main_server_st *s, struct proc_list_st* cur);
|
||||
|
||||
int call_connect_script(main_server_st *s, struct proc_list_st* cur);
|
||||
void call_disconnect_script(main_server_st *s, struct proc_list_st* cur);
|
||||
|
||||
void expire_tls_sessions(main_server_st *s);
|
||||
|
||||
int send_resume_fetch_reply(main_server_st* s, struct proc_list_st* proc,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.c)
|
||||
*
|
||||
* It has been AutoGen-ed January 31, 2013 at 12:25:38 AM by AutoGen 5.16
|
||||
* It has been AutoGen-ed February 4, 2013 at 08:41:20 PM by AutoGen 5.16
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
|
||||
@@ -92,6 +92,14 @@ auth-timeout = 40
|
||||
# of that cookie.
|
||||
cookie-validity = 14400
|
||||
|
||||
# Script to call when a client connects and obtains an IP
|
||||
# Parameters: username device IP-REAL IP-LOCAL IP-REMOTE
|
||||
# IP-REAL is the remote IP of the client,
|
||||
# IP-LOCAL is the local IP in the P-t-P connection and IP-REMOTE
|
||||
# is the VPN client IP.
|
||||
connect-script = /bin/echo
|
||||
disconnect-script = /bin/echo
|
||||
|
||||
# Cookie database file. Where to store the cookies.
|
||||
cookie-db = /path/to/db
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.h)
|
||||
*
|
||||
* It has been AutoGen-ed January 31, 2013 at 12:25:38 AM by AutoGen 5.16
|
||||
* It has been AutoGen-ed February 4, 2013 at 08:41:20 PM by AutoGen 5.16
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
|
||||
@@ -46,7 +46,7 @@ tls-priorities = "PERFORMANCE:%SERVER_PRECEDENCE:%COMPAT"
|
||||
# Once a client is authenticated he's provided a cookie with
|
||||
# which he can reconnect. This option sets the maximum lifetime
|
||||
# of that cookie.
|
||||
cookie-validity = 30
|
||||
cookie-validity = 14400
|
||||
|
||||
# Cookie database file. Where to store the cookies.
|
||||
cookie-db = /var/tmp/ocserv-cookie.db
|
||||
@@ -58,6 +58,14 @@ run-as-group = nogroup
|
||||
|
||||
device = vpns
|
||||
|
||||
# Script to call when a client connects and obtains an IP
|
||||
# Parameters: username device IP-REAL IP-LOCAL IP-REMOTE
|
||||
# IP-REAL is the remote IP of the client,
|
||||
# IP-LOCAL is the local IP in the P-t-P connection and IP-REMOTE
|
||||
# is the VPN client IP.
|
||||
connect-script = /bin/echo
|
||||
disconnect-script = /bin/echo
|
||||
|
||||
# The pool from which the VPN user IPs will be drawn from.
|
||||
ipv4-network = 192.168.1.0
|
||||
ipv4-netmask = 255.255.255.0
|
||||
|
||||
Reference in New Issue
Block a user