From 64a91f2b44ef50b3031a89f3979981223c3417ff Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 12 Feb 2013 18:55:40 +0100 Subject: [PATCH] Simplify script calling by using the environment --- doc/ocserv.1 | 15 ++++---- src/main-auth.c | 10 ++++- src/main-user.c | 93 +++++++++++++++++---------------------------- src/ocserv-args.c | 2 +- src/ocserv-args.def | 13 +++---- src/ocserv-args.h | 2 +- 6 files changed, 58 insertions(+), 77 deletions(-) diff --git a/doc/ocserv.1 b/doc/ocserv.1 index 0314ee96..47e45ed7 100644 --- a/doc/ocserv.1 +++ b/doc/ocserv.1 @@ -2,7 +2,7 @@ .\" .\" DO NOT EDIT THIS FILE (ocserv-args.man) .\" -.\" It has been AutoGen-ed February 12, 2013 at 04:34:58 PM by AutoGen 5.16 +.\" It has been AutoGen-ed February 12, 2013 at 06:56:01 PM by AutoGen 5.16 .\" From the definitions ../src/ocserv-args.def.tmp .\" and the template file agman-cmd.tpl .\" @@ -215,13 +215,12 @@ cookie\-validity = 14400 #cookie\-db = /var/tmp/cookies.db .sp # Script to call when a client connects and obtains an IP -# Parameters: username groupname hostname device IP\-REAL IP\-LOCAL IP\-REMOTE -# hostname is the hostname selected by the client -# 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 +# Parameters are passed on the environment. +# USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client), +# DEVICE, IP_REAL (the real IP of the client), IP_LOCAL (the local IP +# in the P\-t\-P connect), IP_REMOTE (the VPN IP of the client). +#connect\-script = /usr/bin/myscript +#disconnect\-script = /usr/bin/myscript .sp # UTMP use\-utmp = true diff --git a/src/main-auth.c b/src/main-auth.c index d45054ed..028eb56e 100644 --- a/src/main-auth.c +++ b/src/main-auth.c @@ -116,6 +116,10 @@ struct stored_cookie_st sc; memcpy(proc->hostname, sc.hostname, sizeof(proc->hostname)); memcpy(proc->session_id, sc.session_id, sizeof(proc->session_id)); proc->session_id_size = sizeof(proc->session_id); + + proc->username[sizeof(proc->username)-1] = 0; + proc->groupname[sizeof(proc->groupname)-1] = 0; + proc->hostname[sizeof(proc->hostname)-1] = 0; if (req->tls_auth_ok != 0) { if (strcmp(proc->username, req->cert_user) != 0) { @@ -206,11 +210,15 @@ unsigned username_set = 0; } } } - + if (ret == 0) { /* open tun */ if (req->hostname[0] != 0) memcpy(proc->hostname, req->hostname, MAX_HOSTNAME_SIZE); + proc->username[sizeof(proc->username)-1] = 0; + proc->groupname[sizeof(proc->groupname)-1] = 0; + proc->hostname[sizeof(proc->hostname)-1] = 0; + ret = open_tun(s, lease); if (ret < 0) ret = -1; /* sorry */ diff --git a/src/main-user.c b/src/main-user.c index bc9d9705..99f47540 100644 --- a/src/main-user.c +++ b/src/main-user.c @@ -46,60 +46,19 @@ #include static -void call_disconnect_script(main_server_st *s, struct proc_st* proc) -{ -pid_t pid; -int ret; - - if (s->config->disconnect_script == NULL) - return; - - pid = fork(); - if (pid == 0) { - char real[64]; - char local[64]; - char remote[64]; - - if (proc->lease == NULL) - exit(1); - - 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->hostname, proc->lease->name, real, local, remote, NULL); - if (ret == -1) - exit(1); - - exit(0); - } else if (pid == -1) { - mslog(s, proc, LOG_ERR, "Could not fork()"); - } -} - -static -int call_connect_script(main_server_st *s, struct proc_st* proc, struct lease_st* lease) +int call_script(main_server_st *s, struct proc_st* proc, struct lease_st* lease, unsigned up) { pid_t pid; int ret, status; +unsigned estatus; +const char* script; - if (s->config->connect_script == NULL) + if (up != 0) + script = s->config->connect_script; + else + script = s->config->disconnect_script; + + if (script == NULL) return 0; pid = fork(); @@ -110,7 +69,6 @@ int ret, status; /* Note we don't use proc->lease and accept lease directly * because we are called before proc population is completed */ - if (getnameinfo((void*)&proc->remote_addr, proc->remote_addr_len, real, sizeof(real), NULL, 0, NI_NUMERICHOST) != 0) exit(1); @@ -130,21 +88,38 @@ int ret, status; exit(1); } - ret = execlp(s->config->connect_script, s->config->connect_script, - proc->username, proc->hostname, lease->name, real, local, remote, NULL); - if (ret == -1) + setenv("USERNAME", proc->username, 1); + setenv("GROUPNAME", proc->groupname, 1); + setenv("HOSTNAME", proc->hostname, 1); + setenv("DEVICE", lease->name, 1); + setenv("IP_REAL", real, 1); + setenv("IP_LOCAL", local, 1); + setenv("IP_REMOTE", remote, 1); + + mslog(s, proc, LOG_DEBUG, "executing script %s", script); + ret = execl(script, script, NULL); + if (ret == -1) { + mslog(s, proc, LOG_ERR, "Could execute script %s", script); exit(1); + } - exit(0); + exit(77); } else if (pid == -1) { mslog(s, proc, LOG_ERR, "Could not fork()"); return -1; } ret = waitpid(pid, &status, 0); - if (WEXITSTATUS(status) == 0) + estatus = WEXITSTATUS(status); + mslog(s, proc, LOG_DEBUG, "%s-script exit status: %u", (up!=0)?"connect":"disconnect", estatus); + + if (estatus == 0) { return 0; - return -1; + } else { + if (WIFSIGNALED(status)) + mslog(s, proc, LOG_DEBUG, "%s-script exit due to signal", (up!=0)?"connect":"disconnect"); + return -1; + } } static void @@ -219,7 +194,7 @@ int ret; add_utmp_entry(s, proc, lease); - ret = call_connect_script(s, proc, lease); + ret = call_script(s, proc, lease, 1); if (ret < 0) return ret; @@ -229,6 +204,6 @@ int ret; void user_disconnected(main_server_st *s, struct proc_st* proc) { remove_utmp_entry(s, proc); - call_disconnect_script(s, proc); + call_script(s, proc, proc->lease, 0); } diff --git a/src/ocserv-args.c b/src/ocserv-args.c index 2c153323..746aa993 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed February 12, 2013 at 04:34:56 PM by AutoGen 5.16 + * It has been AutoGen-ed February 12, 2013 at 06:56:00 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.def b/src/ocserv-args.def index 60644b79..3fdea7bd 100644 --- a/src/ocserv-args.def +++ b/src/ocserv-args.def @@ -140,13 +140,12 @@ cookie-validity = 14400 #cookie-db = /var/tmp/cookies.db # Script to call when a client connects and obtains an IP -# Parameters: username groupname hostname device IP-REAL IP-LOCAL IP-REMOTE -# hostname is the hostname selected by the client -# 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 +# Parameters are passed on the environment. +# USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client), +# DEVICE, IP_REAL (the real IP of the client), IP_LOCAL (the local IP +# in the P-t-P connect), IP_REMOTE (the VPN IP of the client). +#connect-script = /usr/bin/myscript +#disconnect-script = /usr/bin/myscript # UTMP use-utmp = true diff --git a/src/ocserv-args.h b/src/ocserv-args.h index 8dc4673e..949ba244 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed February 12, 2013 at 04:34:56 PM by AutoGen 5.16 + * It has been AutoGen-ed February 12, 2013 at 06:56:00 PM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options *