Added support for session control (relevant for PAM for now)

That in effect will utilize the pam_open_session() and pam_close_session().
It is disabled by default as it requires more resources from the security module.
This commit is contained in:
Nikos Mavrogiannopoulos
2014-06-10 14:47:27 +02:00
parent 01db3e5817
commit 28dca2aa0c
19 changed files with 307 additions and 22 deletions

View File

@@ -347,6 +347,33 @@ struct pam_ctx_st * pctx = ctx;
talloc_free(pctx); talloc_free(pctx);
} }
static int pam_auth_open_session(void* ctx)
{
struct pam_ctx_st * pctx = ctx;
int pret;
pret = pam_open_session(pctx->ph, PAM_SILENT);
if (pret != PAM_SUCCESS) {
syslog(LOG_AUTH, "PAM-auth: pam_open_session: %s", pam_strerror(pctx->ph, pret));
return -1;
}
return 0;
}
static void pam_auth_close_session(void* ctx)
{
struct pam_ctx_st * pctx = ctx;
int pret;
pret = pam_close_session(pctx->ph, PAM_SILENT);
if (pret != PAM_SUCCESS) {
syslog(LOG_AUTH, "PAM-auth: pam_close_session: %s", pam_strerror(pctx->ph, pret));
}
return;
}
static void pam_group_list(void *pool, void *_additional, char ***groupname, unsigned *groupname_size) static void pam_group_list(void *pool, void *_additional, char ***groupname, unsigned *groupname_size)
{ {
struct group *grp; struct group *grp;
@@ -392,6 +419,8 @@ const struct auth_mod_st pam_auth_funcs = {
.auth_pass = pam_auth_pass, .auth_pass = pam_auth_pass,
.auth_group = pam_auth_group, .auth_group = pam_auth_group,
.auth_user = pam_auth_user, .auth_user = pam_auth_user,
.open_session = pam_auth_open_session,
.close_session = pam_auth_close_session,
.group_list = pam_group_list .group_list = pam_group_list
}; };

View File

@@ -65,6 +65,10 @@ static char tmp[32];
return "sm: decrypt"; return "sm: decrypt";
case SM_CMD_SIGN: case SM_CMD_SIGN:
return "sm: sign"; return "sm: sign";
case SM_CMD_AUTH_SESSION_CLOSE:
return "sm: session close";
case SM_CMD_AUTH_SESSION_OPEN:
return "sm: session open";
default: default:
snprintf(tmp, sizeof(tmp), "unknown (%u)", _cmd); snprintf(tmp, sizeof(tmp), "unknown (%u)", _cmd);
return tmp; return tmp;

View File

@@ -85,6 +85,7 @@ static struct cfg_options available_options[] = {
{ .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 }, { .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "banner", .type = OPTION_STRING, .mandatory = 0 }, { .name = "banner", .type = OPTION_STRING, .mandatory = 0 },
{ .name = "predictable-ips", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "predictable-ips", .type = OPTION_BOOLEAN, .mandatory = 0 },
{ .name = "session-control", .type = OPTION_BOOLEAN, .mandatory = 0 },
{ .name = "auto-select-group", .type = OPTION_BOOLEAN, .mandatory = 0 }, { .name = "auto-select-group", .type = OPTION_BOOLEAN, .mandatory = 0 },
{ .name = "default-select-group", .type = OPTION_STRING, .mandatory = 0 }, { .name = "default-select-group", .type = OPTION_STRING, .mandatory = 0 },
/* this is alias for cisco-client-compat */ /* this is alias for cisco-client-compat */
@@ -439,6 +440,8 @@ unsigned force_cert_auth;
if (config->occtl_socket_file == NULL) if (config->occtl_socket_file == NULL)
config->occtl_socket_file = talloc_strdup(config, OCCTL_UNIX_SOCKET); config->occtl_socket_file = talloc_strdup(config, OCCTL_UNIX_SOCKET);
READ_TF("session-control", config->session_control, 0);
READ_STRING("banner", config->banner); READ_STRING("banner", config->banner);
READ_TF("cisco-client-compat", config->cisco_client_compat, 0); READ_TF("cisco-client-compat", config->cisco_client_compat, 0);
READ_TF("always-require-cert", force_cert_auth, 1); READ_TF("always-require-cert", force_cert_auth, 1);

View File

@@ -106,7 +106,7 @@ message session_info_msg
/* /*
* == Auth with username/password == * == Auth with username/password ==
* *
* main worker * sec-mod worker
* <------ AUTH_INIT (username) * <------ AUTH_INIT (username)
* AUTH_REP(MSG,SID) ------> * AUTH_REP(MSG,SID) ------>
* <------ AUTH_CONT (SID,password) * <------ AUTH_CONT (SID,password)
@@ -173,3 +173,22 @@ message cookie
required uint32 ipv4_seed = 7; required uint32 ipv4_seed = 7;
required bytes sid = 8; required bytes sid = 8;
} }
/*
* == Session Termination ==
*
* main sec-mod
* SESSION_OPEN/CLOSE ------>
*
*/
/* SEC_SESSION_CLOSE */
message sec_auth_session_msg
{
required bytes sid = 1;
}
message sec_auth_session_reply_msg
{
required AUTH_REP reply = 1;
}

View File

@@ -192,6 +192,7 @@ struct cookie_entry_st *old;
memcpy(proc->dtls_session_id, cmsg->session_id.data, cmsg->session_id.len); memcpy(proc->dtls_session_id, cmsg->session_id.data, cmsg->session_id.len);
proc->dtls_session_id_size = cmsg->session_id.len; proc->dtls_session_id_size = cmsg->session_id.len;
memcpy(proc->sid, cmsg->sid.data, cmsg->sid.len); memcpy(proc->sid, cmsg->sid.data, cmsg->sid.len);
proc->active_sid = 1;
/* cookie is good so far, now read config (in order to know /* cookie is good so far, now read config (in order to know
* whether roaming is allowed or not */ * whether roaming is allowed or not */
@@ -269,6 +270,12 @@ struct cookie_entry_st *old;
memcpy(proc->ipv4_seed, &cmsg->ipv4_seed, sizeof(proc->ipv4_seed)); memcpy(proc->ipv4_seed, &cmsg->ipv4_seed, sizeof(proc->ipv4_seed));
ret = session_openclose(s, proc, 1);
if (ret < 0) {
mslog(s, proc, LOG_INFO, "could not open session");
return -1;
}
return 0; return 0;
} }

View File

@@ -610,7 +610,7 @@ static void ctl_handle_commands(main_server_st * s)
goto cleanup; goto cleanup;
} }
ret = check_upeer_id("ctl", cfd, 0, 0); ret = check_upeer_id("ctl", cfd, 0, 0, NULL);
if (ret < 0) { if (ret < 0) {
mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection"); mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection");
goto cleanup; goto cleanup;

View File

@@ -163,6 +163,77 @@ struct proc_st *ctmp;
return ctmp; return ctmp;
} }
int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open)
{
int sd, ret, e;
SecAuthSessionMsg ireq = SEC_AUTH_SESSION_MSG__INIT;
SecAuthSessionReplyMsg *msg = NULL;
unsigned type;
if (s->config->session_control == 0)
return 0;
if (open)
type = SM_CMD_AUTH_SESSION_OPEN;
else
type = SM_CMD_AUTH_SESSION_CLOSE;
sd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sd == -1) {
e = errno;
mslog(s, proc, LOG_ERR, "error opening unix socket (for sec-mod) %s",
strerror(e));
return -1;
}
ret =
connect(sd, (struct sockaddr *)&s->secmod_addr,
s->secmod_addr_len);
if (ret < 0) {
e = errno;
close(sd);
mslog(s, proc, LOG_ERR,
"error connecting to sec-mod socket '%s': %s",
s->secmod_addr.sun_path, strerror(e));
return -1;
}
ireq.sid.data = proc->sid;
ireq.sid.len = sizeof(proc->sid);
mslog(s, proc, LOG_DEBUG, "sending msg %s to sec-mod", cmd_request_to_str(type));
ret = send_msg(proc, sd, type,
&ireq, (pack_size_func)sec_auth_session_msg__get_packed_size,
(pack_func)sec_auth_session_msg__pack);
if (ret < 0) {
close(sd);
mslog(s, proc, LOG_ERR,
"error sending message to sec-mod socket '%s'",
s->secmod_addr.sun_path);
return -1;
}
if (open) {
ret = recv_msg(proc, sd, SM_CMD_AUTH_SESSION_REPLY,
(void *)&msg, (unpack_func) sec_auth_session_reply_msg__unpack);
close(sd);
if (ret < 0) {
mslog(s, proc, LOG_ERR, "error receiving auth reply message");
return ret;
}
if (msg->reply != AUTH__REP__OK) {
mslog(s, proc, LOG_INFO, "could not initiate session for '%s'", proc->username);
return -1;
}
} else {
close(sd);
}
return 0;
}
/* k: whether to kill the process /* k: whether to kill the process
*/ */
void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k) void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
@@ -179,6 +250,11 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
if (proc->username[0] != 0) if (proc->username[0] != 0)
user_disconnected(s, proc); user_disconnected(s, proc);
/* close any pending sessions */
if (s->config->session_control != 0 && proc->active_sid) {
session_openclose(s, proc, 0);
}
/* close the intercomm fd */ /* close the intercomm fd */
if (proc->fd >= 0) if (proc->fd >= 0)
close(proc->fd); close(proc->fd);
@@ -197,8 +273,15 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
if (proc->cookie_ptr) { if (proc->cookie_ptr) {
unsigned timeout = s->config->cookie_timeout; unsigned timeout = s->config->cookie_timeout;
proc->cookie_ptr->expiration = time(0) + timeout;
proc->cookie_ptr->proc = NULL; proc->cookie_ptr->proc = NULL;
if (s->config->session_control != 0) {
/* if we use session control and we closed the session we
* need to invalidate the cookie, so that a new session is
* used on the next connection */
proc->cookie_ptr->expiration = 1;
} else {
proc->cookie_ptr->expiration = time(0) + timeout;
}
} }
close_tun(s, proc); close_tun(s, proc);

View File

@@ -956,6 +956,10 @@ int main(int argc, char** argv)
/* Initialize certificates */ /* Initialize certificates */
tls_load_certs(s, &creds); tls_load_certs(s, &creds);
s->secmod_addr.sun_family = AF_UNIX;
snprintf(s->secmod_addr.sun_path, sizeof(s->secmod_addr.sun_path), "%s", s->socket_file);
s->secmod_addr_len = SUN_LEN(&s->secmod_addr);
/* initialize memory for worker process */ /* initialize memory for worker process */
worker_pool = talloc_named(main_pool, 0, "worker"); worker_pool = talloc_named(main_pool, 0, "worker");
if (worker_pool == NULL) { if (worker_pool == NULL) {
@@ -1066,9 +1070,8 @@ int main(int argc, char** argv)
kill_on_parent_kill(SIGTERM); kill_on_parent_kill(SIGTERM);
/* write sec-mod's address */ /* write sec-mod's address */
ws->secmod_addr.sun_family = AF_UNIX; memcpy(&ws->secmod_addr, &s->secmod_addr, s->secmod_addr_len);
snprintf(ws->secmod_addr.sun_path, sizeof(ws->secmod_addr.sun_path), "%s", s->socket_file); ws->secmod_addr_len = s->secmod_addr_len;
ws->secmod_addr_len = SUN_LEN(&ws->secmod_addr);
ws->main_pool = main_pool; ws->main_pool = main_pool;
ws->config = s->config; ws->config = s->config;

View File

@@ -29,6 +29,8 @@
#include <tlslib.h> #include <tlslib.h>
#include "ipc.pb-c.h" #include "ipc.pb-c.h"
#include <common.h> #include <common.h>
#include <sys/un.h>
#include <sys/uio.h>
#ifdef __FreeBSD__ #ifdef __FreeBSD__
# include <limits.h> # include <limits.h>
@@ -111,6 +113,7 @@ typedef struct proc_st {
/* The SID present in the cookie. Used for session control only */ /* The SID present in the cookie. Used for session control only */
uint8_t sid[SID_SIZE]; uint8_t sid[SID_SIZE];
unsigned active_sid;
/* The DTLS session ID associated with the TLS session /* The DTLS session ID associated with the TLS session
* it is either generated or restored from a cookie. * it is either generated or restored from a cookie.
@@ -193,6 +196,9 @@ typedef struct main_server_st {
char socket_file[_POSIX_PATH_MAX]; char socket_file[_POSIX_PATH_MAX];
char full_socket_file[_POSIX_PATH_MAX]; char full_socket_file[_POSIX_PATH_MAX];
pid_t sec_mod_pid; pid_t sec_mod_pid;
struct sockaddr_un secmod_addr;
unsigned secmod_addr_len;
unsigned active_clients; unsigned active_clients;
time_t start_time; time_t start_time;
@@ -229,6 +235,8 @@ int handle_resume_fetch_req(main_server_st* s, struct proc_st * proc,
int handle_resume_store_req(main_server_st* s, struct proc_st *proc, int handle_resume_store_req(main_server_st* s, struct proc_st *proc,
const SessionResumeStoreReqMsg *); const SessionResumeStoreReqMsg *);
int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open);
void void
__attribute__ ((format(printf, 4, 5))) __attribute__ ((format(printf, 4, 5)))
_mslog(const main_server_st * s, const struct proc_st* proc, _mslog(const main_server_st * s, const struct proc_st* proc,

View File

@@ -89,8 +89,8 @@ An example configuration file follows.
#auth = "plain[/etc/ocserv/ocpasswd]" #auth = "plain[/etc/ocserv/ocpasswd]"
# Whether to enable the authentication method's session control (i.e., PAM). # Whether to enable the authentication method's session control (i.e., PAM).
# That requires more resources on the server so don't enable unless you need # That requires more resources on the server, and makes cookies one-time-use;
# it. # thus don't enable unless you need it.
#session-control = true #session-control = true
# A banner to be displayed on clients # A banner to be displayed on clients
@@ -642,11 +642,8 @@ doc-section = {
ds-type = 'IMPLEMENTATION NOTES'; ds-type = 'IMPLEMENTATION NOTES';
ds-format = 'texi'; ds-format = 'texi';
ds-text = <<-_EOT_ ds-text = <<-_EOT_
The support for PAM is limited to authentication only. That is, PAM is Note that while this server utilizes privilege separation and password
used for authentication but not for session control. authentication occurs on the security module, this does not apply for TLS client
Note also, that while this server utilizes privilege separation and password
authentication occurs on the main server, this does not apply for TLS client
certificate authentication. That is because the worker has no way to certificate authentication. That is because the worker has no way to
prove to the main server that it performed the certificate verification. prove to the main server that it performed the certificate verification.
_EOT_; _EOT_;

View File

@@ -279,7 +279,10 @@ int handle_sec_auth_res(sec_mod_st * sec, client_entry_st * e, int result)
return ret; return ret;
} }
del_client_entry(sec->client_db, e); ret = 0;
if (sec->config->session_control == 0 || module->open_session == NULL) {
del_client_entry(sec->client_db, e);
} /* else do nothing, and wait for session close/open messages */
} else { } else {
e->status = PS_AUTH_FAILED; e->status = PS_AUTH_FAILED;
add_ip_to_ban_list(sec->ban_db, e->ip, time(0) + sec->config->min_reauth_time); add_ip_to_ban_list(sec->ban_db, e->ip, time(0) + sec->config->min_reauth_time);
@@ -301,6 +304,44 @@ int handle_sec_auth_res(sec_mod_st * sec, client_entry_st * e, int result)
return ret; return ret;
} }
int handle_sec_auth_session_openclose(sec_mod_st * sec, const SecAuthSessionMsg * req, unsigned cmd)
{
client_entry_st *e;
int ret;
if (sec->config->session_control == 0 || module->open_session == NULL) {
seclog(LOG_ERR, "auth session open/close but session control is disabled!");
return 0;
}
if (req->sid.len != SID_SIZE) {
seclog(LOG_ERR, "auth session open/close but with illegal sid size (%d)!",
(int)req->sid.len);
return -1;
}
e = find_client_entry(sec->client_db, req->sid.data);
if (e == NULL) {
seclog(LOG_INFO, "session open/close but with non-existing sid!");
return -1;
}
if (cmd == SM_CMD_AUTH_SESSION_OPEN) {
ret = module->open_session(e->auth_ctx);
if (ret < 0) {
e->status = PS_AUTH_FAILED;
seclog(LOG_ERR, "could not open session.");
del_client_entry(sec->client_db, e);
return ret;
}
e->have_session = 1;
} else {
del_client_entry(sec->client_db, e);
}
return 0;
}
int handle_sec_auth_cont(sec_mod_st * sec, const SecAuthContMsg * req) int handle_sec_auth_cont(sec_mod_st * sec, const SecAuthContMsg * req)
{ {
client_entry_st *e; client_entry_st *e;
@@ -448,6 +489,9 @@ void sec_auth_user_deinit(client_entry_st * e)
{ {
seclog(LOG_DEBUG, "auth deinit for user '%s'", e->username); seclog(LOG_DEBUG, "auth deinit for user '%s'", e->username);
if (e->auth_ctx != NULL) { if (e->auth_ctx != NULL) {
if (e->have_session) {
module->close_session(e->auth_ctx);
}
module->auth_deinit(e->auth_ctx); module->auth_deinit(e->auth_ctx);
e->auth_ctx = NULL; e->auth_ctx = NULL;
} }

View File

@@ -33,6 +33,10 @@ struct auth_mod_st {
int (*auth_pass)(void* ctx, const char* pass, unsigned pass_len); int (*auth_pass)(void* ctx, const char* pass, unsigned pass_len);
int (*auth_group)(void* ctx, const char *suggested, char *groupname, int groupname_size); int (*auth_group)(void* ctx, const char *suggested, char *groupname, int groupname_size);
int (*auth_user)(void* ctx, char *groupname, int groupname_size); int (*auth_user)(void* ctx, char *groupname, int groupname_size);
int (*open_session)(void *ctx); /* optional, may be null */
void (*close_session)(void *ctx); /* optional */
void (*auth_deinit)(void* ctx); void (*auth_deinit)(void* ctx);
void (*group_list)(void *pool, void *additional, char ***groupname, unsigned *groupname_size); void (*group_list)(void *pool, void *additional, char ***groupname, unsigned *groupname_size);
}; };

View File

@@ -75,6 +75,16 @@ struct htable *db = _db;
} }
} }
unsigned sec_mod_ban_db_elems(void *_db)
{
struct htable *db = _db;
if (db)
return db->elems;
else
return 0;
}
void add_ip_to_ban_list(void *_db, const char *ip, time_t reenable_time) void add_ip_to_ban_list(void *_db, const char *ip, time_t reenable_time)
{ {
struct htable *db = _db; struct htable *db = _db;

View File

@@ -71,6 +71,17 @@ struct htable *db = _db;
talloc_free(db); talloc_free(db);
} }
/* The number of elements */
unsigned sec_mod_client_db_elems(void *_db)
{
struct htable *db = _db;
if (db)
return db->elems;
else
return 0;
}
client_entry_st *new_client_entry(void *_db, const char *ip) client_entry_st *new_client_entry(void *_db, const char *ip)
{ {
struct htable *db = _db; struct htable *db = _db;
@@ -129,6 +140,11 @@ static void clean_entry(client_entry_st * e)
talloc_free(e); talloc_free(e);
} }
/* Allow few seconds prior to cleaning up entries, to avoid any race
* conditions when session control is enabled.
*/
#define SLACK_TIME 10
void cleanup_client_entries(void *_db) void cleanup_client_entries(void *_db)
{ {
struct htable *db = _db; struct htable *db = _db;
@@ -138,7 +154,8 @@ void cleanup_client_entries(void *_db)
t = htable_first(db, &iter); t = htable_first(db, &iter);
while (t != NULL) { while (t != NULL) {
if (now - t->time > MAX_AUTH_SECS) { fprintf(stderr, "entry[%d]: %s\n", t->have_session, t->username);
if (t->have_session == 0 && now - t->time > MAX_AUTH_SECS + SLACK_TIME) {
htable_delval(db, &iter); htable_delval(db, &iter);
clean_entry(t); clean_entry(t);
} }

View File

@@ -186,7 +186,7 @@ static int handle_op(void *pool, sec_mod_st * sec, uint8_t type, uint8_t * rep,
static static
int process_packet(void *pool, sec_mod_st * sec, cmd_request_t cmd, int process_packet(void *pool, sec_mod_st * sec, cmd_request_t cmd,
uint8_t * buffer, size_t buffer_size) uid_t uid, uint8_t * buffer, size_t buffer_size)
{ {
unsigned i; unsigned i;
gnutls_datum_t data, out; gnutls_datum_t data, out;
@@ -275,6 +275,43 @@ int process_packet(void *pool, sec_mod_st * sec, cmd_request_t cmd,
ret = handle_sec_auth_cont(sec, auth_cont); ret = handle_sec_auth_cont(sec, auth_cont);
sec_auth_cont_msg__free_unpacked(auth_cont, &pa); sec_auth_cont_msg__free_unpacked(auth_cont, &pa);
return ret;
}
case SM_CMD_AUTH_SESSION_OPEN:
case SM_CMD_AUTH_SESSION_CLOSE:{
SecAuthSessionMsg *msg;
SecAuthSessionReplyMsg rep = SEC_AUTH_SESSION_REPLY_MSG__INIT;
if (uid != 0) {
seclog(LOG_INFO, "received session open/close from unauthorized uid (%u)\n", (unsigned)uid);
return -1;
}
msg =
sec_auth_session_msg__unpack(&pa, data.size,
data.data);
if (msg == NULL) {
seclog(LOG_INFO, "error unpacking session close\n");
return -1;
}
ret = handle_sec_auth_session_openclose(sec, msg, cmd);
sec_auth_session_msg__free_unpacked(msg, &pa);
if (cmd == SM_CMD_AUTH_SESSION_OPEN) {
if (ret < 0)
rep.reply = AUTH__REP__FAILED;
else
rep.reply = AUTH__REP__OK;
ret = send_msg(pool, sec->fd, SM_CMD_AUTH_SESSION_REPLY, &rep,
(pack_size_func) sec_auth_session_reply_msg__get_packed_size,
(pack_func) sec_auth_session_reply_msg__pack);
if (ret < 0) {
seclog(LOG_WARNING, "sec-mod error in sending session reply");
}
}
return ret; return ret;
} }
default: default:
@@ -314,7 +351,11 @@ static void check_other_work(sec_mod_st *sec)
seclog(LOG_DEBUG, "performing maintenance"); seclog(LOG_DEBUG, "performing maintenance");
cleanup_client_entries(sec->client_db); cleanup_client_entries(sec->client_db);
cleanup_banned_entries(sec->ban_db); cleanup_banned_entries(sec->ban_db);
seclog(LOG_DEBUG, "active sessions %d, banned entries %d",
sec_mod_client_db_elems(sec->client_db),
sec_mod_ban_db_elems(sec->ban_db));
alarm(MAINTAINANCE_TIME); alarm(MAINTAINANCE_TIME);
need_maintainance = 0;
} }
} }
@@ -353,6 +394,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
int cfd, ret, e; int cfd, ret, e;
unsigned cmd, length; unsigned cmd, length;
unsigned i, buffer_size; unsigned i, buffer_size;
uid_t uid;
uint8_t *buffer, *tpool; uint8_t *buffer, *tpool;
uint16_t l16; uint16_t l16;
struct pin_st pins; struct pin_st pins;
@@ -521,7 +563,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
/* do not allow unauthorized processes to issue commands /* do not allow unauthorized processes to issue commands
*/ */
ret = check_upeer_id("sec-mod", cfd, config->uid, config->gid); ret = check_upeer_id("sec-mod", cfd, config->uid, config->gid, &uid);
if (ret < 0) { if (ret < 0) {
seclog(LOG_INFO, "rejected unauthorized connection"); seclog(LOG_INFO, "rejected unauthorized connection");
goto cont; goto cont;
@@ -558,7 +600,7 @@ void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_f
tpool = talloc_new(sec); tpool = talloc_new(sec);
sec->fd = cfd; sec->fd = cfd;
ret = process_packet(tpool, sec, cmd, buffer, ret); ret = process_packet(tpool, sec, cmd, uid, buffer, ret);
if (ret < 0) { if (ret < 0) {
seclog(LOG_INFO, "error processing data for '%s' command (%d)", cmd_request_to_str(cmd), ret); seclog(LOG_INFO, "error processing data for '%s' command (%d)", cmd_request_to_str(cmd), ret);
} }

View File

@@ -45,6 +45,8 @@ typedef struct client_entry_st {
*/ */
uint8_t sid[SID_SIZE]; uint8_t sid[SID_SIZE];
void * auth_ctx; /* the context of authentication */ void * auth_ctx; /* the context of authentication */
unsigned have_session; /* whether an auth session is initialized */
unsigned status; /* PS_AUTH_ */ unsigned status; /* PS_AUTH_ */
char ip[MAX_IP_STR]; /* the user's IP */ char ip[MAX_IP_STR]; /* the user's IP */
@@ -61,6 +63,7 @@ typedef struct client_entry_st {
void *sec_mod_client_db_init(void *pool); void *sec_mod_client_db_init(void *pool);
void sec_mod_client_db_deinit(void *db); void sec_mod_client_db_deinit(void *db);
unsigned sec_mod_client_db_elems(void *_db);
client_entry_st * new_client_entry(void *_db, const char *ip); client_entry_st * new_client_entry(void *_db, const char *ip);
client_entry_st * find_client_entry(void *_db, uint8_t sid[SID_SIZE]); client_entry_st * find_client_entry(void *_db, uint8_t sid[SID_SIZE]);
void del_client_entry(void *_db, client_entry_st * e); void del_client_entry(void *_db, client_entry_st * e);
@@ -74,10 +77,11 @@ void cleanup_client_entries(void *_db);
#endif #endif
void sec_auth_init(struct cfg_st *config); void sec_auth_init(struct cfg_st *config);
void sec_auth_user_deinit(client_entry_st *e);
int handle_sec_auth_init(sec_mod_st *sec, const SecAuthInitMsg * req); int handle_sec_auth_init(sec_mod_st *sec, const SecAuthInitMsg * req);
int handle_sec_auth_cont(sec_mod_st *sec, const SecAuthContMsg * req); int handle_sec_auth_cont(sec_mod_st *sec, const SecAuthContMsg * req);
int handle_sec_auth_session_openclose(sec_mod_st * sec, const SecAuthSessionMsg * req, unsigned cmd);
void sec_auth_user_deinit(client_entry_st * e);
void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file, void sec_mod_server(void *main_pool, struct cfg_st *config, const char *socket_file,
uint8_t cookie_key[COOKIE_KEY_SIZE]); uint8_t cookie_key[COOKIE_KEY_SIZE]);
@@ -87,5 +91,6 @@ unsigned check_if_banned(void *_db, const char *ip);
void add_ip_to_ban_list(void *_db, const char *ip, time_t reenable_time); void add_ip_to_ban_list(void *_db, const char *ip, time_t reenable_time);
void *sec_mod_ban_db_init(void *pool); void *sec_mod_ban_db_init(void *pool);
void sec_mod_ban_db_deinit(void *_db); void sec_mod_ban_db_deinit(void *_db);
unsigned sec_mod_ban_db_elems(void *_db);
#endif #endif

View File

@@ -54,7 +54,7 @@ SIGHANDLER_T ocsignal(int signum, SIGHANDLER_T handler)
/* Checks whether the peer in a socket has the expected @uid and @gid. /* Checks whether the peer in a socket has the expected @uid and @gid.
* Returns zero on success. * Returns zero on success.
*/ */
int check_upeer_id(const char *mod, int cfd, int uid, int gid) int check_upeer_id(const char *mod, int cfd, uid_t uid, uid_t gid, uid_t *ruid)
{ {
int e, ret; int e, ret;
#if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED) #if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED)
@@ -78,6 +78,9 @@ int check_upeer_id(const char *mod, int cfd, int uid, int gid)
"%s: received request from pid %u and uid %u", "%s: received request from pid %u and uid %u",
mod, (unsigned)cr.pid, (unsigned)cr.uid); mod, (unsigned)cr.pid, (unsigned)cr.uid);
if (ruid)
*ruid = cr.uid;
if (cr.uid != 0 && (cr.uid != uid || cr.gid != gid)) { if (cr.uid != 0 && (cr.uid != uid || cr.gid != gid)) {
syslog(LOG_DEBUG, syslog(LOG_DEBUG,
"%s: received unauthorized request from pid %u and uid %u", "%s: received unauthorized request from pid %u and uid %u",
@@ -85,7 +88,7 @@ int check_upeer_id(const char *mod, int cfd, int uid, int gid)
return -1; return -1;
} }
#elif defined(HAVE_GETPEEREID) #elif defined(HAVE_GETPEEREID)
pid_t euid; uid_t euid;
gid_t egid; gid_t egid;
ret = getpeereid(cfd, &euid, &egid); ret = getpeereid(cfd, &euid, &egid);
@@ -97,6 +100,9 @@ int check_upeer_id(const char *mod, int cfd, int uid, int gid)
return -1; return -1;
} }
if (ruid)
*ruid = euid;
syslog(LOG_DEBUG, syslog(LOG_DEBUG,
"%s: received request from a processes with uid %u", "%s: received request from a processes with uid %u",
mod, (unsigned)euid); mod, (unsigned)euid);

View File

@@ -23,6 +23,7 @@
# include <config.h> # include <config.h>
# include <signal.h> # include <signal.h>
# include <unistd.h>
#ifdef HAVE_SIGHANDLER_T #ifdef HAVE_SIGHANDLER_T
# define SIGHANDLER_T sighandler_t # define SIGHANDLER_T sighandler_t
@@ -39,6 +40,6 @@ void kill_on_parent_kill(int sig);
SIGHANDLER_T ocsignal(int signum, SIGHANDLER_T handler); SIGHANDLER_T ocsignal(int signum, SIGHANDLER_T handler);
int check_upeer_id(const char *mod, int cfg, int uid, int gid); int check_upeer_id(const char *mod, int cfg, uid_t uid, uid_t gid, uid_t *ruid);
#endif #endif

View File

@@ -113,6 +113,9 @@ typedef enum {
SM_CMD_AUTH_REP, SM_CMD_AUTH_REP,
SM_CMD_DECRYPT, SM_CMD_DECRYPT,
SM_CMD_SIGN, SM_CMD_SIGN,
SM_CMD_AUTH_SESSION_OPEN,
SM_CMD_AUTH_SESSION_CLOSE,
SM_CMD_AUTH_SESSION_REPLY,
} cmd_request_t; } cmd_request_t;
#define MAX_IP_STR 46 #define MAX_IP_STR 46