mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
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:
@@ -347,6 +347,33 @@ struct pam_ctx_st * pctx = ctx;
|
||||
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)
|
||||
{
|
||||
struct group *grp;
|
||||
@@ -392,6 +419,8 @@ const struct auth_mod_st pam_auth_funcs = {
|
||||
.auth_pass = pam_auth_pass,
|
||||
.auth_group = pam_auth_group,
|
||||
.auth_user = pam_auth_user,
|
||||
.open_session = pam_auth_open_session,
|
||||
.close_session = pam_auth_close_session,
|
||||
.group_list = pam_group_list
|
||||
};
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ static char tmp[32];
|
||||
return "sm: decrypt";
|
||||
case SM_CMD_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:
|
||||
snprintf(tmp, sizeof(tmp), "unknown (%u)", _cmd);
|
||||
return tmp;
|
||||
|
||||
@@ -85,6 +85,7 @@ static struct cfg_options available_options[] = {
|
||||
{ .name = "occtl-socket-file", .type = OPTION_STRING, .mandatory = 0 },
|
||||
{ .name = "banner", .type = OPTION_STRING, .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 = "default-select-group", .type = OPTION_STRING, .mandatory = 0 },
|
||||
/* this is alias for cisco-client-compat */
|
||||
@@ -439,6 +440,8 @@ unsigned force_cert_auth;
|
||||
if (config->occtl_socket_file == NULL)
|
||||
config->occtl_socket_file = talloc_strdup(config, OCCTL_UNIX_SOCKET);
|
||||
|
||||
READ_TF("session-control", config->session_control, 0);
|
||||
|
||||
READ_STRING("banner", config->banner);
|
||||
READ_TF("cisco-client-compat", config->cisco_client_compat, 0);
|
||||
READ_TF("always-require-cert", force_cert_auth, 1);
|
||||
|
||||
@@ -106,7 +106,7 @@ message session_info_msg
|
||||
/*
|
||||
* == Auth with username/password ==
|
||||
*
|
||||
* main worker
|
||||
* sec-mod worker
|
||||
* <------ AUTH_INIT (username)
|
||||
* AUTH_REP(MSG,SID) ------>
|
||||
* <------ AUTH_CONT (SID,password)
|
||||
@@ -173,3 +173,22 @@ message cookie
|
||||
required uint32 ipv4_seed = 7;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -192,6 +192,7 @@ struct cookie_entry_st *old;
|
||||
memcpy(proc->dtls_session_id, cmsg->session_id.data, cmsg->session_id.len);
|
||||
proc->dtls_session_id_size = cmsg->session_id.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
|
||||
* 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));
|
||||
|
||||
ret = session_openclose(s, proc, 1);
|
||||
if (ret < 0) {
|
||||
mslog(s, proc, LOG_INFO, "could not open session");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -610,7 +610,7 @@ static void ctl_handle_commands(main_server_st * s)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = check_upeer_id("ctl", cfd, 0, 0);
|
||||
ret = check_upeer_id("ctl", cfd, 0, 0, NULL);
|
||||
if (ret < 0) {
|
||||
mslog(s, NULL, LOG_ERR, "ctl: unauthorized connection");
|
||||
goto cleanup;
|
||||
|
||||
@@ -163,6 +163,77 @@ struct proc_st *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
|
||||
*/
|
||||
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)
|
||||
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 */
|
||||
if (proc->fd >= 0)
|
||||
close(proc->fd);
|
||||
@@ -197,8 +273,15 @@ void remove_proc(main_server_st * s, struct proc_st *proc, unsigned k)
|
||||
if (proc->cookie_ptr) {
|
||||
unsigned timeout = s->config->cookie_timeout;
|
||||
|
||||
proc->cookie_ptr->expiration = time(0) + timeout;
|
||||
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);
|
||||
|
||||
@@ -956,6 +956,10 @@ int main(int argc, char** argv)
|
||||
/* Initialize certificates */
|
||||
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 */
|
||||
worker_pool = talloc_named(main_pool, 0, "worker");
|
||||
if (worker_pool == NULL) {
|
||||
@@ -1066,9 +1070,8 @@ int main(int argc, char** argv)
|
||||
kill_on_parent_kill(SIGTERM);
|
||||
|
||||
/* write sec-mod's address */
|
||||
ws->secmod_addr.sun_family = AF_UNIX;
|
||||
snprintf(ws->secmod_addr.sun_path, sizeof(ws->secmod_addr.sun_path), "%s", s->socket_file);
|
||||
ws->secmod_addr_len = SUN_LEN(&ws->secmod_addr);
|
||||
memcpy(&ws->secmod_addr, &s->secmod_addr, s->secmod_addr_len);
|
||||
ws->secmod_addr_len = s->secmod_addr_len;
|
||||
|
||||
ws->main_pool = main_pool;
|
||||
ws->config = s->config;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <tlslib.h>
|
||||
#include "ipc.pb-c.h"
|
||||
#include <common.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
# include <limits.h>
|
||||
@@ -111,6 +113,7 @@ typedef struct proc_st {
|
||||
|
||||
/* The SID present in the cookie. Used for session control only */
|
||||
uint8_t sid[SID_SIZE];
|
||||
unsigned active_sid;
|
||||
|
||||
/* The DTLS session ID associated with the TLS session
|
||||
* 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 full_socket_file[_POSIX_PATH_MAX];
|
||||
pid_t sec_mod_pid;
|
||||
|
||||
struct sockaddr_un secmod_addr;
|
||||
unsigned secmod_addr_len;
|
||||
|
||||
unsigned active_clients;
|
||||
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,
|
||||
const SessionResumeStoreReqMsg *);
|
||||
|
||||
int session_openclose(main_server_st * s, struct proc_st *proc, unsigned open);
|
||||
|
||||
void
|
||||
__attribute__ ((format(printf, 4, 5)))
|
||||
_mslog(const main_server_st * s, const struct proc_st* proc,
|
||||
|
||||
@@ -89,8 +89,8 @@ An example configuration file follows.
|
||||
#auth = "plain[/etc/ocserv/ocpasswd]"
|
||||
|
||||
# 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
|
||||
# it.
|
||||
# That requires more resources on the server, and makes cookies one-time-use;
|
||||
# thus don't enable unless you need it.
|
||||
#session-control = true
|
||||
|
||||
# A banner to be displayed on clients
|
||||
@@ -642,11 +642,8 @@ doc-section = {
|
||||
ds-type = 'IMPLEMENTATION NOTES';
|
||||
ds-format = 'texi';
|
||||
ds-text = <<-_EOT_
|
||||
The support for PAM is limited to authentication only. That is, PAM is
|
||||
used for authentication but not for session control.
|
||||
|
||||
Note also, that while this server utilizes privilege separation and password
|
||||
authentication occurs on the main server, this does not apply for TLS client
|
||||
Note that while this server utilizes privilege separation and password
|
||||
authentication occurs on the security module, this does not apply for TLS client
|
||||
certificate authentication. That is because the worker has no way to
|
||||
prove to the main server that it performed the certificate verification.
|
||||
_EOT_;
|
||||
|
||||
@@ -279,7 +279,10 @@ int handle_sec_auth_res(sec_mod_st * sec, client_entry_st * e, int result)
|
||||
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 {
|
||||
e->status = PS_AUTH_FAILED;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (e->auth_ctx != NULL) {
|
||||
if (e->have_session) {
|
||||
module->close_session(e->auth_ctx);
|
||||
}
|
||||
module->auth_deinit(e->auth_ctx);
|
||||
e->auth_ctx = NULL;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ struct auth_mod_st {
|
||||
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_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 (*group_list)(void *pool, void *additional, char ***groupname, unsigned *groupname_size);
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
struct htable *db = _db;
|
||||
|
||||
@@ -71,6 +71,17 @@ struct htable *db = _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)
|
||||
{
|
||||
struct htable *db = _db;
|
||||
@@ -129,6 +140,11 @@ static void clean_entry(client_entry_st * 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)
|
||||
{
|
||||
struct htable *db = _db;
|
||||
@@ -138,7 +154,8 @@ void cleanup_client_entries(void *_db)
|
||||
|
||||
t = htable_first(db, &iter);
|
||||
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);
|
||||
clean_entry(t);
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ static int handle_op(void *pool, sec_mod_st * sec, uint8_t type, uint8_t * rep,
|
||||
|
||||
static
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
default:
|
||||
@@ -314,7 +351,11 @@ static void check_other_work(sec_mod_st *sec)
|
||||
seclog(LOG_DEBUG, "performing maintenance");
|
||||
cleanup_client_entries(sec->client_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);
|
||||
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;
|
||||
unsigned cmd, length;
|
||||
unsigned i, buffer_size;
|
||||
uid_t uid;
|
||||
uint8_t *buffer, *tpool;
|
||||
uint16_t l16;
|
||||
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
|
||||
*/
|
||||
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) {
|
||||
seclog(LOG_INFO, "rejected unauthorized connection");
|
||||
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);
|
||||
sec->fd = cfd;
|
||||
ret = process_packet(tpool, sec, cmd, buffer, ret);
|
||||
ret = process_packet(tpool, sec, cmd, uid, buffer, ret);
|
||||
if (ret < 0) {
|
||||
seclog(LOG_INFO, "error processing data for '%s' command (%d)", cmd_request_to_str(cmd), ret);
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ typedef struct client_entry_st {
|
||||
*/
|
||||
uint8_t sid[SID_SIZE];
|
||||
void * auth_ctx; /* the context of authentication */
|
||||
unsigned have_session; /* whether an auth session is initialized */
|
||||
|
||||
unsigned status; /* PS_AUTH_ */
|
||||
|
||||
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_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 * find_client_entry(void *_db, uint8_t sid[SID_SIZE]);
|
||||
void del_client_entry(void *_db, client_entry_st * e);
|
||||
@@ -74,10 +77,11 @@ void cleanup_client_entries(void *_db);
|
||||
#endif
|
||||
|
||||
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_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,
|
||||
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 *sec_mod_ban_db_init(void *pool);
|
||||
void sec_mod_ban_db_deinit(void *_db);
|
||||
unsigned sec_mod_ban_db_elems(void *_db);
|
||||
|
||||
#endif
|
||||
|
||||
10
src/system.c
10
src/system.c
@@ -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.
|
||||
* 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;
|
||||
#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",
|
||||
mod, (unsigned)cr.pid, (unsigned)cr.uid);
|
||||
|
||||
if (ruid)
|
||||
*ruid = cr.uid;
|
||||
|
||||
if (cr.uid != 0 && (cr.uid != uid || cr.gid != gid)) {
|
||||
syslog(LOG_DEBUG,
|
||||
"%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;
|
||||
}
|
||||
#elif defined(HAVE_GETPEEREID)
|
||||
pid_t euid;
|
||||
uid_t euid;
|
||||
gid_t 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;
|
||||
}
|
||||
|
||||
if (ruid)
|
||||
*ruid = euid;
|
||||
|
||||
syslog(LOG_DEBUG,
|
||||
"%s: received request from a processes with uid %u",
|
||||
mod, (unsigned)euid);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
# include <config.h>
|
||||
# include <signal.h>
|
||||
# include <unistd.h>
|
||||
|
||||
#ifdef HAVE_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);
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user