Do not let scripts block the server operation.

This commit is contained in:
Nikos Mavrogiannopoulos
2013-03-13 18:45:48 +01:00
parent 0c4b013b3f
commit b552f27ddb
13 changed files with 260 additions and 151 deletions

View File

@@ -266,6 +266,13 @@ static void check_cfg( struct cfg_st *config)
else
config->cert_req = GNUTLS_CERT_REQUEST;
}
if (config->plain_passwd != NULL) {
if (access(config->plain_passwd, R_OK) != 0) {
fprintf(stderr, "cannot access password file %s\n", config->plain_passwd);
exit(1);
}
}
#ifdef ANYCONNECT_CLIENT_COMPAT
if (config->cert) {

View File

@@ -122,3 +122,24 @@ void __attribute__ ((format(printf, 4, 5)))
return;
}
void mslog_hex(const main_server_st * s, const struct proc_st* proc,
int priority, const char *prefix, uint8_t* bin, unsigned bin_size)
{
char buf[512];
int ret;
size_t buf_size;
gnutls_datum_t data = {bin, bin_size};
if (priority == LOG_DEBUG && s->config->debug == 0)
return;
buf_size = sizeof(buf);
ret = gnutls_hex_encode(&data, buf, &buf_size);
if (ret < 0)
return;
mslog(s, proc, priority, "%s %s", prefix, buf);
return;
}

View File

@@ -45,7 +45,7 @@
#include "plain.h"
int send_auth_reply(main_server_st* s, struct proc_st* proc,
cmd_auth_reply_t r, struct lease_st* lease)
cmd_auth_reply_t r)
{
struct iovec iov[2];
uint8_t cmd[2];
@@ -62,7 +62,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc,
hdr.msg_iov = iov;
if (r == REP_AUTH_OK && lease != NULL) {
if (r == REP_AUTH_OK && proc->lease != NULL) {
cmd[0] = AUTH_REP;
iov[0].iov_base = cmd;
@@ -72,7 +72,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc,
resp.reply = r;
memcpy(resp.cookie, proc->cookie, COOKIE_SIZE);
memcpy(resp.session_id, proc->session_id, sizeof(resp.session_id));
memcpy(resp.vname, lease->name, sizeof(resp.vname));
memcpy(resp.vname, proc->lease->name, sizeof(resp.vname));
memcpy(resp.user, proc->username, sizeof(resp.user));
iov[1].iov_base = &resp;
@@ -87,7 +87,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc,
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(cmptr), &lease->fd, sizeof(int));
memcpy(CMSG_DATA(cmptr), &proc->lease->fd, sizeof(int));
} else {
cmd[0] = AUTH_REP;
cmd[1] = REP_AUTH_FAILED;
@@ -101,7 +101,7 @@ int send_auth_reply(main_server_st* s, struct proc_st* proc,
}
int handle_auth_cookie_req(main_server_st* s, struct proc_st* proc,
const struct cmd_auth_cookie_req_st * req, struct lease_st **lease)
const struct cmd_auth_cookie_req_st * req)
{
int ret;
struct stored_cookie_st *sc;
@@ -146,7 +146,7 @@ time_t now = time(0);
}
}
ret = open_tun(s, lease);
ret = open_tun(s, &proc->lease);
if (ret < 0) {
ret = -1; /* sorry */
goto cleanup;
@@ -177,7 +177,7 @@ struct stored_cookie_st *sc;
ret = gnutls_rnd(GNUTLS_RND_NONCE, proc->session_id, sizeof(proc->session_id));
if (ret < 0)
return -2;
proc->session_id_size = sizeof( proc->session_id);
proc->session_id_size = sizeof(proc->session_id);
sc = calloc(1, sizeof(*sc));
if (sc == NULL)
@@ -202,7 +202,7 @@ struct stored_cookie_st *sc;
}
int handle_auth_req(main_server_st *s, struct proc_st* proc,
const struct cmd_auth_req_st * req, struct lease_st **lease)
const struct cmd_auth_req_st * req)
{
int ret = -1;
unsigned username_set = 0;
@@ -256,7 +256,7 @@ unsigned username_set = 0;
proc->groupname[sizeof(proc->groupname)-1] = 0;
proc->hostname[sizeof(proc->hostname)-1] = 0;
ret = open_tun(s, lease);
ret = open_tun(s, &proc->lease);
if (ret < 0)
ret = -1; /* sorry */
}

View File

@@ -108,12 +108,47 @@ int send_udp_fd(main_server_st* s, struct proc_st * proc, int fd)
return(sendmsg(proc->fd, &hdr, 0));
}
int handle_script_exit(main_server_st *s, struct proc_st* proc, int code)
{
int ret;
if (code == 0) {
ret = send_auth_reply(s, proc, REP_AUTH_OK);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not send reply auth cmd.");
ret = ERR_BAD_COMMAND;
goto fail;
}
} else {
mslog(s, proc, LOG_INFO, "failed authentication attempt for user '%s'", proc->username);
ret = send_auth_reply( s, proc, REP_AUTH_FAILED);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not send reply auth cmd.");
ret = ERR_BAD_COMMAND;
goto fail;
}
}
ret = 0;
fail:
/* we close the lease tun fd both on success and failure.
* The parent doesn't need to keep the tunfd.
*/
if (proc->lease) {
if (proc->lease->fd >= 0)
close(proc->lease->fd);
proc->lease->fd = -1;
}
return ret;
}
int handle_commands(main_server_st *s, struct proc_st* proc)
{
struct iovec iov[2];
uint8_t cmd;
struct msghdr hdr;
struct lease_st *lease;
union {
struct cmd_auth_req_st auth;
struct cmd_auth_cookie_req_st cauth;
@@ -153,16 +188,15 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
case CMD_TUN_MTU:
if (cmd_data_len != sizeof(cmd_data.tmtu)) {
mslog(s, proc, LOG_ERR, "error in received message (cmd %u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
set_tun_mtu(s, proc, cmd_data.tmtu.mtu);
break;
case RESUME_STORE_REQ:
if (cmd_data_len <= sizeof(cmd_data.sresume)-MAX_SESSION_DATA_SIZE) {
mslog(s, proc, LOG_ERR, "error in received message (cmd %u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
ret = handle_resume_store_req(s, proc, &cmd_data.sresume);
if (ret < 0) {
@@ -174,7 +208,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
case RESUME_DELETE_REQ:
if (cmd_data_len != sizeof(cmd_data.fresume)) {
mslog(s, proc, LOG_ERR, "error in received message (cmd %u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
ret = handle_resume_delete_req(s, proc, &cmd_data.fresume);
if (ret < 0) {
@@ -187,7 +221,7 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
if (cmd_data_len != sizeof(cmd_data.fresume)) {
mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
ret = handle_resume_fetch_req(s, proc, &cmd_data.fresume, &reply);
if (ret < 0) {
@@ -199,29 +233,27 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not send reply cmd %d.", (unsigned) cmd);
return -2;
return ERR_BAD_COMMAND;
}
break;
case AUTH_REQ:
case AUTH_COOKIE_REQ:
lease = NULL;
if (cmd == AUTH_REQ) {
if (cmd_data_len != sizeof(cmd_data.auth)) {
mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
ret = handle_auth_req(s, proc, &cmd_data.auth, &lease);
ret = handle_auth_req(s, proc, &cmd_data.auth);
} else {
if (cmd_data_len != sizeof(cmd_data.cauth)) {
mslog(s, proc, LOG_ERR, "error in received message (%u) length.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
ret = handle_auth_cookie_req(s, proc, &cmd_data.cauth, &lease);
ret = handle_auth_cookie_req(s, proc, &cmd_data.cauth);
}
if (ret == 0) {
@@ -231,9 +263,32 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
mslog(s, proc, LOG_INFO, "user '%s' tried to connect more than %u times", proc->username, s->config->max_same_clients);
}
if (ret == 0) {
if (proc->groupname[0] == 0)
group = "[unknown]";
else
group = proc->groupname;
if (cmd == AUTH_REQ) {
/* generate and store cookie */
ret = generate_and_store_vals(s, proc);
if (ret < 0) {
ret = ERR_BAD_COMMAND;
goto cleanup;
}
mslog(s, proc, LOG_INFO, "user '%s' of group '%s' authenticated", proc->username, group);
} else {
mslog(s, proc, LOG_INFO, "user '%s' of group '%s' re-authenticated (using cookie)", proc->username, group);
}
}
/* do scripts and utmp */
if (ret == 0) {
ret = user_connected(s, proc, lease);
ret = user_connected(s, proc);
if (ret == ERR_WAIT_FOR_SCRIPT) {
return 0;
}
if (ret < 0) {
mslog(s, proc, LOG_INFO, "user '%s' disconnected due to script", proc->username);
}
@@ -242,60 +297,13 @@ int handle_commands(main_server_st *s, struct proc_st* proc)
add_to_ip_ban_list(s, &proc->remote_addr, proc->remote_addr_len);
}
if (ret == 0) {
if (proc->groupname[0] == 0)
group = "[unknown]";
else
group = proc->groupname;
cleanup:
/* no script was called. Handle it as a successful script call. */
return handle_script_exit(s, proc, ret);
if (cmd == AUTH_REQ) {
/* generate and store cookie */
ret = generate_and_store_vals(s, proc);
if (ret < 0) {
ret = -2;
goto lease_cleanup;
}
mslog(s, proc, LOG_INFO, "user '%s' of group '%s' authenticated", proc->username, group);
} else {
mslog(s, proc, LOG_INFO, "user '%s' of group '%s' re-authenticated (using cookie)", proc->username, group);
}
ret = send_auth_reply(s, proc, REP_AUTH_OK, lease);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not send reply cmd %d.", (unsigned)cmd);
ret = -2;
goto lease_cleanup;
}
proc->lease = lease;
proc->lease->in_use = 1;
ret = 0;
} else {
mslog(s, proc, LOG_INFO, "failed authentication attempt for user '%s'", proc->username);
ret = send_auth_reply( s, proc, REP_AUTH_FAILED, NULL);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "could not send reply cmd.");
ret = -2;
goto lease_cleanup;
}
ret = 0;
}
lease_cleanup:
/* we close the lease tun fd both on success and failure.
* The parent doesn't need to know the tunfd.
*/
if (lease) {
if (lease->fd >= 0)
close(lease->fd);
lease->fd = -1;
}
return ret;
break;
default:
mslog(s, proc, LOG_ERR, "unknown CMD 0x%x.", (unsigned)cmd);
return -2;
return ERR_BAD_COMMAND;
}
return 0;

View File

@@ -43,14 +43,14 @@
#include <cookies.h>
#include <tun.h>
#include <main.h>
#include <script-list.h>
#include <ccan/list/list.h>
static
int call_script(main_server_st *s, struct proc_st* proc, struct lease_st* lease, unsigned up)
int call_script(main_server_st *s, struct proc_st* proc, unsigned up)
{
pid_t pid;
int ret, status;
unsigned estatus;
int ret;
const char* script;
if (up != 0)
@@ -67,34 +67,36 @@ const char* script;
char local[64];
char remote[64];
/* 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);
if (lease->lip4_len > 0) {
if (getnameinfo((void*)&lease->lip4, lease->lip4_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
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*)&lease->lip6, lease->lip6_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
if (getnameinfo((void*)&proc->lease->lip6, proc->lease->lip6_len, local, sizeof(local), NULL, 0, NI_NUMERICHOST) != 0)
exit(1);
}
if (lease->rip4_len > 0) {
if (getnameinfo((void*)&lease->rip4, lease->rip4_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
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*)&lease->rip6, lease->rip6_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
if (getnameinfo((void*)&proc->lease->rip6, proc->lease->rip6_len, remote, sizeof(remote), NULL, 0, NI_NUMERICHOST) != 0)
exit(1);
}
setenv("USERNAME", proc->username, 1);
setenv("GROUPNAME", proc->groupname, 1);
setenv("HOSTNAME", proc->hostname, 1);
setenv("DEVICE", lease->name, 1);
setenv("DEVICE", proc->lease->name, 1);
setenv("IP_REAL", real, 1);
setenv("IP_LOCAL", local, 1);
setenv("IP_REMOTE", remote, 1);
if (up)
setenv("REASON", "connect", 1);
else
setenv("REASON", "disconnect", 1);
mslog(s, proc, LOG_DEBUG, "executing script %s", script);
ret = execl(script, script, NULL);
@@ -109,21 +111,16 @@ const char* script;
return -1;
}
ret = waitpid(pid, &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;
if (up) {
add_to_script_list(s, pid, up, proc);
return ERR_WAIT_FOR_SCRIPT;
} else {
if (WIFSIGNALED(status))
mslog(s, proc, LOG_DEBUG, "%s-script exit due to signal", (up!=0)?"connect":"disconnect");
return -1;
return 0;
}
}
static void
add_utmp_entry(main_server_st *s, struct proc_st* proc, struct lease_st* lease)
add_utmp_entry(main_server_st *s, struct proc_st* proc)
{
#ifdef HAVE_LIBUTIL
struct utmpx entry;
@@ -135,7 +132,7 @@ add_utmp_entry(main_server_st *s, struct proc_st* proc, struct lease_st* lease)
memset(&entry, 0, sizeof(entry));
entry.ut_type = USER_PROCESS;
entry.ut_pid = proc->pid;
snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", lease->name);
snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->lease->name);
snprintf(entry.ut_user, sizeof(entry.ut_user), "%s", proc->username);
if (proc->remote_addr_len == sizeof(struct sockaddr_in))
memcpy(entry.ut_addr_v6, SA_IN_P(&proc->remote_addr), sizeof(struct in_addr));
@@ -188,13 +185,13 @@ static void remove_utmp_entry(main_server_st *s, struct proc_st* proc)
#endif
}
int user_connected(main_server_st *s, struct proc_st* proc, struct lease_st* lease)
int user_connected(main_server_st *s, struct proc_st* proc)
{
int ret;
add_utmp_entry(s, proc, lease);
add_utmp_entry(s, proc);
ret = call_script(s, proc, lease, 1);
ret = call_script(s, proc, 1);
if (ret < 0)
return ret;
@@ -204,6 +201,6 @@ int ret;
void user_disconnected(main_server_st *s, struct proc_st* proc)
{
remove_utmp_entry(s, proc);
call_script(s, proc, proc->lease, 0);
call_script(s, proc, 0);
}

View File

@@ -32,6 +32,7 @@
#include <errno.h>
#include <sys/ioctl.h>
#include <cloexec.h>
#include <script-list.h>
#include <gnutls/x509.h>
#include <tlslib.h>
@@ -285,14 +286,48 @@ int s, y, e;
return 0;
}
static void remove_proc(main_server_st* s, struct proc_st *proc, unsigned k)
{
if (k)
kill(proc->pid, SIGTERM);
user_disconnected(s, proc);
/* close the intercomm fd */
if (proc->fd >= 0)
close(proc->fd);
proc->fd = -1;
proc->pid = -1;
if (proc->lease)
proc->lease->in_use = 0;
list_del(&proc->list);
free(proc);
}
static void cleanup_children(main_server_st *s)
{
int status;
int status, estatus, ret;
pid_t pid;
struct script_wait_st *stmp, *spos;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (WEXITSTATUS(status) != 0 ||
estatus = WEXITSTATUS(status);
/* check if someone was waiting for that pid */
list_for_each_safe(&s->script_list.head, stmp, spos, list) {
if (stmp->pid == pid) {
mslog(s, stmp->proc, LOG_DEBUG, "%s-script exit status: %u", stmp->up?"connect":"disconnect", estatus);
ret = handle_script_exit(s, stmp->proc, estatus);
if (ret < 0)
remove_proc(s, stmp->proc, 0);
list_del(&stmp->list);
free(stmp);
break;
}
}
if (estatus != 0 ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)) {
if (WIFSIGNALED(status))
mslog(s, NULL, LOG_ERR, "Child %u died with sigsegv\n", (unsigned)pid);
@@ -311,8 +346,6 @@ static void handle_alarm(int signo)
need_maintainance = 1;
}
static void drop_privileges(main_server_st* s)
{
int ret, e;
@@ -357,6 +390,7 @@ void clear_lists(main_server_st *s)
{
struct listener_st *ltmp, *lpos;
struct proc_st *ctmp, *cpos;
struct script_wait_st *script_tmp, *script_pos;
struct banned_st *btmp, *bpos;
list_for_each_safe(&s->llist.head, ltmp, lpos, list) {
@@ -379,6 +413,11 @@ void clear_lists(main_server_st *s)
free(btmp);
}
list_for_each_safe(&s->script_list.head, script_tmp, script_pos, list) {
list_del(&script_tmp->list);
free(script_tmp);
}
tls_cache_deinit(s->tls_db);
}
@@ -394,20 +433,6 @@ static void kill_children(main_server_st* s)
}
}
static void remove_proc(struct proc_st *ctmp)
{
/* close the intercomm fd */
if (ctmp->fd >= 0)
close(ctmp->fd);
ctmp->fd = -1;
ctmp->pid = -1;
if (ctmp->lease)
ctmp->lease->in_use = 0;
list_del(&ctmp->list);
free(ctmp);
}
static void handle_term(int signo)
{
/* kill all children */
@@ -438,7 +463,7 @@ int connected = 0;
cli_addr_size = sizeof(cli_addr);
ret = recvfrom(listener->fd, buffer, sizeof(buffer), MSG_PEEK, (void*)&cli_addr, &cli_addr_size);
if (ret < 0) {
mslog(s, NULL, LOG_INFO, "Error receiving in UDP socket");
mslog(s, NULL, LOG_INFO, "error receiving in UDP socket");
return -1;
}
@@ -453,11 +478,11 @@ int connected = 0;
mslog(s, NULL, LOG_DEBUG, "DTLS hello version: %u.%u", (unsigned int)buffer[RECORD_PAYLOAD_POS], (unsigned int)buffer[RECORD_PAYLOAD_POS+1]);
if (buffer[1] != 254 && (buffer[1] != 1 && buffer[2] != 0) &&
buffer[RECORD_PAYLOAD_POS] != 254 && (buffer[RECORD_PAYLOAD_POS] != 0 && buffer[RECORD_PAYLOAD_POS+1] != 0)) {
mslog(s, NULL, LOG_INFO, "Unknown DTLS version: %u.%u", (unsigned)buffer[1], (unsigned)buffer[2]);
mslog(s, NULL, LOG_INFO, "unknown DTLS version: %u.%u", (unsigned)buffer[1], (unsigned)buffer[2]);
goto fail;
}
if (buffer[0] != 22) {
mslog(s, NULL, LOG_INFO, "Unexpected DTLS content type: %u", (unsigned int)buffer[0]);
mslog(s, NULL, LOG_INFO, "unexpected DTLS content type: %u", (unsigned int)buffer[0]);
goto fail;
}
@@ -466,8 +491,8 @@ int connected = 0;
session_id = &buffer[RECORD_PAYLOAD_POS+HANDSHAKE_SESSION_ID_POS+1];
/* search for the IP and the session ID in all procs */
list_for_each(&s->clist.head, ctmp, list) {
list_for_each(&s->clist.head, ctmp, list) {
if (session_id_size == ctmp->session_id_size &&
memcmp(session_id, ctmp->session_id, session_id_size) == 0) {
@@ -480,15 +505,14 @@ int connected = 0;
ret = send_udp_fd(s, ctmp, listener->fd);
if (ret < 0) {
mslog(s, ctmp, LOG_ERR, "Error passing UDP socket");
mslog(s, ctmp, LOG_ERR, "error passing UDP socket");
return -1;
}
mslog(s, ctmp, LOG_DEBUG, "Passed UDP socket");
mslog(s, ctmp, LOG_DEBUG, "passed UDP socket");
ctmp->udp_fd_received = 1;
connected = 1;
reopen_udp_port(listener);
break;
}
}
@@ -569,13 +593,14 @@ int main(int argc, char** argv)
int cmd_fd[2];
struct worker_st ws;
struct cfg_st config;
unsigned active_clients = 0, set;
unsigned set;
main_server_st s;
memset(&s, 0, sizeof(s));
list_head_init(&s.clist.head);
list_head_init(&s.ban_list.head);
list_head_init(&s.script_list.head);
tun_st_init(&tun);
tls_cache_init(&s.tls_db);
@@ -711,9 +736,9 @@ int main(int argc, char** argv)
break;
}
if (config.max_clients > 0 && active_clients >= config.max_clients) {
if (config.max_clients > 0 && s.active_clients >= config.max_clients) {
close(fd);
mslog(&s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", active_clients);
mslog(&s, NULL, LOG_INFO, "Reached maximum client limit (active: %u)", s.active_clients);
break;
}
@@ -762,6 +787,7 @@ int main(int argc, char** argv)
fork_failed:
close(cmd_fd[0]);
} else { /* parent */
/* add_proc */
ctmp = calloc(1, sizeof(struct proc_st));
if (ctmp == NULL) {
kill(pid, SIGTERM);
@@ -775,7 +801,7 @@ fork_failed:
set_cloexec_flag (cmd_fd[0], 1);
list_add(&s.clist.head, &(ctmp->list));
active_clients++;
s.active_clients++;
}
close(cmd_fd[1]);
close(fd);
@@ -786,7 +812,7 @@ fork_failed:
/* connection on UDP port */
ret = forward_udp_to_owner(&s, ltmp);
if (ret < 0) {
mslog(&s, NULL, LOG_INFO, "Could not determine the owner of received UDP packet");
mslog(&s, NULL, LOG_INFO, "could not determine the owner of received UDP packet");
}
if (config.rate_limit_ms > 0)
@@ -799,13 +825,8 @@ fork_failed:
if (FD_ISSET(ctmp->fd, &rd)) {
ret = handle_commands(&s, ctmp);
if (ret < 0) {
if (ret == -2) {
/* received a bad command from worker */
kill(ctmp->pid, SIGTERM);
}
user_disconnected(&s, ctmp);
remove_proc(ctmp);
active_clients--;
remove_from_script_list(&s, ctmp);
remove_proc(&s, ctmp, (ret==ERR_BAD_COMMAND)?1:0);
}
}
}

View File

@@ -9,6 +9,9 @@
#include <tlslib.h>
#include "ipc.h"
#define ERR_WAIT_FOR_SCRIPT -5
#define ERR_BAD_COMMAND -2
int cmd_parser (int argc, char **argv, struct cfg_st* config);
void reload_cfg_file(struct cfg_st* config);
void write_pid_file(void);
@@ -32,12 +35,20 @@ struct listen_list_st {
unsigned int total;
};
struct script_wait_st {
struct list_node list;
pid_t pid;
unsigned int up; /* connect or disconnect script */
struct proc_st* proc;
};
struct proc_st {
struct list_node list;
int fd;
pid_t pid;
unsigned udp_fd_received; /* if the corresponding process has received a UDP fd */
/* the tun lease this process has */
struct lease_st* lease;
@@ -62,6 +73,10 @@ struct proc_list_st {
unsigned int total;
};
struct script_list_st {
struct list_head head;
};
struct banned_st {
struct list_node list;
time_t failed_time; /* The time authentication failed */
@@ -84,14 +99,17 @@ typedef struct main_server_st {
struct listen_list_st llist;
struct proc_list_st clist;
struct script_list_st script_list;
struct ban_list_st ban_list;
unsigned active_clients;
} main_server_st;
void clear_lists(main_server_st *s);
int handle_commands(main_server_st *s, struct proc_st* cur);
int user_connected(main_server_st *s, struct proc_st* cur, struct lease_st*);
int user_connected(main_server_st *s, struct proc_st* cur);
void user_disconnected(main_server_st *s, struct proc_st* cur);
void expire_tls_sessions(main_server_st *s);
@@ -115,17 +133,19 @@ void
__attribute__ ((format(printf, 4, 5)))
mslog(const main_server_st * s, const struct proc_st* proc,
int priority, const char *fmt, ...);
void mslog_hex(const main_server_st * s, const struct proc_st* proc,
int priority, const char *prefix, uint8_t* bin, unsigned bin_size);
int open_tun(main_server_st* s, struct lease_st** l);
int set_tun_mtu(main_server_st* s, struct proc_st * proc, unsigned mtu);
int send_auth_reply(main_server_st* s, struct proc_st* proc,
cmd_auth_reply_t r, struct lease_st* lease);
cmd_auth_reply_t r);
int handle_auth_cookie_req(main_server_st* s, struct proc_st* proc,
const struct cmd_auth_cookie_req_st * req, struct lease_st **lease);
const struct cmd_auth_cookie_req_st * req);
int generate_and_store_vals(main_server_st *s, struct proc_st* proc);
int handle_auth_req(main_server_st *s, struct proc_st* proc,
const struct cmd_auth_req_st * req, struct lease_st **lease);
const struct cmd_auth_req_st * req);
int check_multiple_users(main_server_st *s, struct proc_st* proc);
@@ -133,4 +153,6 @@ void add_to_ip_ban_list(main_server_st* s, struct sockaddr_storage *addr, sockle
void expire_banned(main_server_st* s);
int check_if_banned(main_server_st* s, struct sockaddr_storage *addr, socklen_t addr_len);
int handle_script_exit(main_server_st *s, struct proc_st* proc, int code);
#endif

View File

@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.c)
*
* It has been AutoGen-ed March 12, 2013 at 11:39:41 PM by AutoGen 5.16
* It has been AutoGen-ed March 13, 2013 at 06:29:47 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*

View File

@@ -191,9 +191,10 @@ cookie-validity = 43200
# Script to call when a client connects and obtains an IP
# Parameters are passed on the environment.
# USERNAME, GROUPNAME, HOSTNAME (the hostname selected by client),
# REASON, 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 connection), IP_REMOTE (the VPN IP of the client).
# in the P-t-P connection), IP_REMOTE (the VPN IP of the client). REASON
# may be "connect" or "disconnect".
#connect-script = /usr/bin/myscript
#disconnect-script = /usr/bin/myscript

View File

@@ -2,7 +2,7 @@
*
* DO NOT EDIT THIS FILE (ocserv-args.h)
*
* It has been AutoGen-ed March 12, 2013 at 11:39:41 PM by AutoGen 5.16
* It has been AutoGen-ed March 13, 2013 at 06:29:46 PM by AutoGen 5.16
* From the definitions ocserv-args.def
* and the template file options
*

35
src/script-list.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef SCRIPT_LIST_H
# define SCRIPT_LIST_H
#include <main.h>
inline static
void add_to_script_list(main_server_st* s, pid_t pid, unsigned up, struct proc_st* proc)
{
struct script_wait_st *stmp;
stmp = malloc(sizeof(*stmp));
if (stmp == NULL)
return;
stmp->proc = proc;
stmp->pid = pid;
stmp->up = up;
list_add(&s->script_list.head, &(stmp->list));
}
inline static void remove_from_script_list(main_server_st* s, struct proc_st* proc)
{
struct script_wait_st *stmp, *spos;
list_for_each_safe(&s->script_list.head, stmp, spos, list) {
if (stmp->proc == proc) {
list_del(&stmp->list);
free(stmp);
break;
}
}
}
#endif

View File

@@ -406,6 +406,7 @@ int open_tun(main_server_st* s, struct lease_st** l)
goto fail;
}
lease->in_use = 1;
lease->fd = tunfd;
*l = lease;

View File

@@ -527,10 +527,6 @@ struct cmd_auth_req_st areq;
ret = auth_user(ws, &areq);
if (ret < 0) {
if (username)
oclog(ws, LOG_INFO, "Failed authentication attempt for '%s'", username);
else
oclog(ws, LOG_INFO, "Failed authentication attempt");
goto auth_fail;
}