mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 00:37:00 +08:00
Do not log the internal session ID nor re-use it in radius
Use instead a value derived from it, to avoid access to the debugging log files, or radius result to access to the server. Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
This commit is contained in:
@@ -154,7 +154,7 @@ static void append_acct_standard(rc_handle *rh, const common_acct_info_st *ai, V
|
||||
#endif
|
||||
|
||||
rc_avpair_add(rh, send, PW_CALLING_STATION_ID, ai->remote_ip, -1, 0);
|
||||
rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, ai->psid, -1, 0);
|
||||
rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, ai->safe_id, -1, 0);
|
||||
|
||||
i = PW_RADIUS;
|
||||
rc_avpair_add(rh, send, PW_ACCT_AUTHENTIC, &i, -1, 0);
|
||||
@@ -208,7 +208,7 @@ VALUE_PAIR *send = NULL, *recvd = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
syslog(LOG_DEBUG, "radius-auth: opening session %s", ai->psid);
|
||||
syslog(LOG_DEBUG, "radius-auth: opening session %s", ai->safe_id);
|
||||
|
||||
if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &status_type, -1, 0) == NULL) {
|
||||
ret = -1;
|
||||
|
||||
@@ -30,9 +30,31 @@
|
||||
#include <netinet/ip.h>
|
||||
#include <poll.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <nettle/sha1.h>
|
||||
#include "common.h"
|
||||
#include "defs.h"
|
||||
#include "common/base64-helper.h"
|
||||
|
||||
/* A hash of the input, to a 20-byte output. The goal is one-wayness.
|
||||
*/
|
||||
static void safe_hash(const uint8_t *data, unsigned data_size, uint8_t output[20])
|
||||
{
|
||||
struct sha1_ctx ctx;
|
||||
|
||||
sha1_init(&ctx);
|
||||
|
||||
sha1_update(&ctx, data_size, data);
|
||||
sha1_digest(&ctx, 20, output);
|
||||
}
|
||||
|
||||
|
||||
void calc_safe_id(const uint8_t *data, unsigned size, char *output, unsigned output_size)
|
||||
{
|
||||
uint8_t safe_id[20];
|
||||
|
||||
safe_hash(data, size, safe_id);
|
||||
oc_base64_encode((char*)safe_id, 20, output, output_size);
|
||||
}
|
||||
|
||||
/* Note that meaning slightly changes depending on whether we are
|
||||
* referring to the cookie or the session itself.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <talloc.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <nettle/base64.h>
|
||||
|
||||
void _talloc_free2(void *ctx, void *ptr);
|
||||
void *_talloc_size2(void *ctx, size_t size);
|
||||
@@ -127,4 +128,7 @@ size_t oc_strlcpy(char *dst, char const *src, size_t siz);
|
||||
# define strlcpy oc_strlcpy
|
||||
#endif
|
||||
|
||||
#define SAFE_ID_SIZE (BASE64_ENCODE_RAW_LENGTH(20)+1)
|
||||
void calc_safe_id(const uint8_t *data, unsigned size, char *output, unsigned output_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@ message user_info_rep
|
||||
required bool restrict_to_routes = 30;
|
||||
repeated fw_port_st fw_ports = 31;
|
||||
|
||||
required bytes sid = 32; /* the cookie */
|
||||
required bytes safe_id = 32; /* a value derived from the cookie */
|
||||
}
|
||||
|
||||
message user_list_rep
|
||||
|
||||
@@ -284,7 +284,7 @@ message secm_session_reply_msg
|
||||
/* internal struct */
|
||||
message cookie_int_msg
|
||||
{
|
||||
required bytes sid = 1;
|
||||
required bytes safe_id = 1;
|
||||
required bool session_is_open = 2;
|
||||
required bool tls_auth_ok = 3;
|
||||
required uint32 last_modified = 4;
|
||||
|
||||
@@ -249,6 +249,7 @@ static int append_user_info(method_ctx *ctx,
|
||||
char *ipbuf;
|
||||
char *strtmp;
|
||||
UserInfoRep *rep;
|
||||
char *safe_id;
|
||||
|
||||
list->user =
|
||||
talloc_realloc(ctx->pool, list->user, UserInfoRep *, (1 + list->n_user));
|
||||
@@ -259,6 +260,10 @@ static int append_user_info(method_ctx *ctx,
|
||||
if (rep == NULL)
|
||||
return -1;
|
||||
|
||||
safe_id = talloc_size(ctx->pool, SAFE_ID_SIZE);
|
||||
if (safe_id == NULL)
|
||||
return -1;
|
||||
|
||||
list->user[list->n_user] = rep;
|
||||
list->n_user++;
|
||||
|
||||
@@ -356,8 +361,9 @@ static int append_user_info(method_ctx *ctx,
|
||||
rep->tls_ciphersuite = ctmp->tls_ciphersuite;
|
||||
rep->dtls_ciphersuite = ctmp->dtls_ciphersuite;
|
||||
|
||||
rep->sid.data = ctmp->sid;
|
||||
rep->sid.len = sizeof(ctmp->sid);
|
||||
calc_safe_id(ctmp->sid, sizeof(ctmp->sid), safe_id, SAFE_ID_SIZE);
|
||||
rep->safe_id.data = (unsigned char*)safe_id;
|
||||
rep->safe_id.len = SAFE_ID_SIZE;
|
||||
|
||||
rep->cstp_compr = ctmp->cstp_compr;
|
||||
rep->dtls_compr = ctmp->dtls_compr;
|
||||
|
||||
@@ -611,15 +611,18 @@ int handle_list_users_cmd(struct unix_ctx *ctx, const char *arg, cmd_params_st *
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *cookie_to_str(void *cookie, unsigned cookie_size, unsigned small)
|
||||
static char *shorten(void *cookie, unsigned cookie_size, unsigned small)
|
||||
{
|
||||
static char psid[BASE64_ENCODE_RAW_LENGTH(SID_SIZE) + 1];
|
||||
static char psid[SAFE_ID_SIZE];
|
||||
|
||||
assert(cookie_size == SID_SIZE);
|
||||
oc_base64_encode((char *)cookie, cookie_size, (char *)psid, sizeof(psid));
|
||||
assert(cookie_size <= SAFE_ID_SIZE);
|
||||
memcpy(psid, cookie, cookie_size);
|
||||
|
||||
if (small)
|
||||
psid[6] = 0;
|
||||
else
|
||||
psid[SAFE_ID_SIZE-1] = 0;
|
||||
|
||||
return psid;
|
||||
}
|
||||
|
||||
@@ -665,7 +668,7 @@ void cookie_list(struct unix_ctx *ctx, SecmListCookiesReplyMsg *rep, FILE *out,
|
||||
|
||||
|
||||
fprintf(out, "%.6s %8s %8s %14s %.24s %8s %8s\n",
|
||||
cookie_to_str(rep->cookies[i]->sid.data, rep->cookies[i]->sid.len, 1),
|
||||
shorten(rep->cookies[i]->safe_id.data, rep->cookies[i]->safe_id.len, 1),
|
||||
username, groupname, rep->cookies[i]->remote_ip,
|
||||
rep->cookies[i]->user_agent, tmpbuf, ps_status_to_str(rep->cookies[i]->status, 1));
|
||||
}
|
||||
@@ -1030,8 +1033,8 @@ int common_info_cmd(UserListRep * args, FILE *out, cmd_params_st *params)
|
||||
print_single_value_ex(out, params, "Connected at", str_since, tmpbuf, 1);
|
||||
|
||||
if (HAVE_JSON(params))
|
||||
print_single_value(out, params, "Raw cookie", cookie_to_str(args->user[i]->sid.data, args->user[i]->sid.len, 0), 1);
|
||||
print_single_value(out, params, "Cookie", cookie_to_str(args->user[i]->sid.data, args->user[i]->sid.len, 1), 1);
|
||||
print_single_value(out, params, "Full cookie", shorten(args->user[i]->safe_id.data, args->user[i]->safe_id.len, 0), 1);
|
||||
print_single_value(out, params, "Cookie", shorten(args->user[i]->safe_id.data, args->user[i]->safe_id.len, 1), 1);
|
||||
|
||||
print_single_value(out, params, "TLS ciphersuite", args->user[i]->tls_ciphersuite, 1);
|
||||
print_single_value(out, params, "DTLS cipher", args->user[i]->dtls_ciphersuite, 1);
|
||||
@@ -1148,8 +1151,8 @@ int cookie_info_cmd(SecmListCookiesReplyMsg * args, FILE *out, cmd_params_st *pa
|
||||
|
||||
print_single_value(out, params, "Last Modified", str_since, 1);
|
||||
|
||||
print_single_value(out, params, "Raw cookie", cookie_to_str(args->cookies[i]->sid.data, args->cookies[i]->sid.len, 0), 1);
|
||||
print_single_value(out, params, "Cookie", cookie_to_str(args->cookies[i]->sid.data, args->cookies[i]->sid.len, 1), 1);
|
||||
print_single_value(out, params, "Full cookie", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 0), 1);
|
||||
print_single_value(out, params, "Cookie", shorten(args->cookies[i]->safe_id.data, args->cookies[i]->safe_id.len, 1), 1);
|
||||
|
||||
print_end_block(out, params, i<(args->n_cookies-1)?1:0);
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ static int check_cert_user_group_status(sec_mod_st * sec, client_entry_st * e)
|
||||
if (e->auth_type & AUTH_TYPE_CERTIFICATE) {
|
||||
if (e->tls_auth_ok == 0) {
|
||||
seclog(sec, LOG_INFO, "user %s "SESSION_STR" presented no certificate; rejecting",
|
||||
e->acct_info.username, e->acct_info.psid);
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ static int check_cert_user_group_status(sec_mod_st * sec, client_entry_st * e)
|
||||
if (sec->config->cert_user_oid != NULL && e->cert_user_name[0] && strcmp(e->acct_info.username, e->cert_user_name) != 0) {
|
||||
seclog(sec, LOG_INFO,
|
||||
"user '%s' "SESSION_STR" presented a certificate which is for user '%s'; rejecting",
|
||||
e->acct_info.username, e->acct_info.psid, e->cert_user_name);
|
||||
e->acct_info.username, e->acct_info.safe_id, e->cert_user_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ static int check_cert_user_group_status(sec_mod_st * sec, client_entry_st * e)
|
||||
if (found == 0) {
|
||||
seclog(sec, LOG_INFO,
|
||||
"user '%s' "SESSION_STR" presented a certificate from group '%s' but he isn't a member of it; rejecting",
|
||||
e->acct_info.username, e->acct_info.psid, e->acct_info.groupname);
|
||||
e->acct_info.username, e->acct_info.safe_id, e->acct_info.groupname);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -432,12 +432,12 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
|
||||
}
|
||||
|
||||
if (e->status != PS_AUTH_COMPLETED) {
|
||||
seclog(sec, LOG_ERR, "session open received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_ERR, "session open received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
|
||||
return send_failed_session_open_reply(sec, fd);
|
||||
}
|
||||
|
||||
if IS_CLIENT_ENTRY_EXPIRED(sec, e, time(0)) {
|
||||
seclog(sec, LOG_ERR, "session expired; denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_ERR, "session expired; denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
e->status = PS_AUTH_FAILED;
|
||||
return send_failed_session_open_reply(sec, fd);
|
||||
}
|
||||
@@ -451,7 +451,7 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
|
||||
ret = sec->perm_config->acct.amod->open_session(e->auth_type, &e->acct_info, req->sid.data, req->sid.len);
|
||||
if (ret < 0) {
|
||||
e->status = PS_AUTH_FAILED;
|
||||
seclog(sec, LOG_INFO, "denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_INFO, "denied session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
return send_failed_session_open_reply(sec, fd);
|
||||
} else {
|
||||
e->session_is_open = 1;
|
||||
@@ -485,7 +485,7 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
|
||||
if (sec->config_module && sec->config_module->get_sup_config) {
|
||||
ret = sec->config_module->get_sup_config(sec->config, e, &rep, lpool);
|
||||
if (ret < 0) {
|
||||
seclog(sec, LOG_ERR, "error reading additional configuration for '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_ERR, "error reading additional configuration for '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
talloc_free(lpool);
|
||||
return send_failed_session_open_reply(sec, fd);
|
||||
}
|
||||
@@ -500,7 +500,7 @@ int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenM
|
||||
}
|
||||
talloc_free(lpool);
|
||||
|
||||
seclog(sec, LOG_INFO, "initiating session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_INFO, "initiating session for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
e->time = -1;
|
||||
e->in_use++;
|
||||
|
||||
@@ -530,7 +530,7 @@ int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionClos
|
||||
}
|
||||
|
||||
if (e->status < PS_AUTH_COMPLETED) {
|
||||
seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
|
||||
return send_msg(e, fd, CMD_SECM_CLI_STATS, &rep,
|
||||
(pack_size_func) cli_stats_msg__get_packed_size,
|
||||
(pack_func) cli_stats_msg__pack);
|
||||
@@ -617,7 +617,7 @@ int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req, pid_t p
|
||||
}
|
||||
|
||||
if (e->status != PS_AUTH_COMPLETED) {
|
||||
seclog(sec, LOG_ERR, "session stats received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_ERR, "session stats received in unauthenticated client %s "SESSION_STR"!", e->acct_info.username, e->acct_info.safe_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -671,16 +671,16 @@ int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
|
||||
|
||||
if (e->status != PS_AUTH_INIT && e->status != PS_AUTH_CONT) {
|
||||
seclog(sec, LOG_ERR, "auth cont received for %s "SESSION_STR" but we are on state %u!",
|
||||
e->acct_info.username, e->acct_info.psid, e->status);
|
||||
e->acct_info.username, e->acct_info.safe_id, e->status);
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
seclog(sec, LOG_DEBUG, "auth cont for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_DEBUG, "auth cont for user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
|
||||
if (req->password == NULL) {
|
||||
seclog(sec, LOG_ERR, "no password given in auth cont for user '%s' "SESSION_STR,
|
||||
e->acct_info.username, e->acct_info.psid);
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -700,7 +700,7 @@ int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req)
|
||||
if (ret != ERR_AUTH_CONTINUE) {
|
||||
seclog(sec, LOG_DEBUG,
|
||||
"error in password given in auth cont for user '%s' "SESSION_STR,
|
||||
e->acct_info.username, e->acct_info.psid);
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -724,7 +724,7 @@ int set_module(sec_mod_st * sec, client_entry_st *e, unsigned auth_type)
|
||||
e->module = sec->perm_config->auth[i].amod;
|
||||
e->auth_type = sec->perm_config->auth[i].type;
|
||||
|
||||
seclog(sec, LOG_INFO, "using '%s' authentication to authenticate user "SESSION_STR, sec->perm_config->auth[i].name, e->acct_info.psid);
|
||||
seclog(sec, LOG_INFO, "using '%s' authentication to authenticate user "SESSION_STR, sec->perm_config->auth[i].name, e->acct_info.safe_id);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -802,7 +802,7 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
|
||||
e->status = PS_AUTH_INIT;
|
||||
seclog(sec, LOG_DEBUG, "auth init %sfor user '%s' "SESSION_STR" of group: '%s' from '%s'",
|
||||
req->tls_auth_ok?"(with cert) ":"",
|
||||
e->acct_info.username, e->acct_info.psid, e->acct_info.groupname, req->ip);
|
||||
e->acct_info.username, e->acct_info.safe_id, e->acct_info.groupname, req->ip);
|
||||
|
||||
if (need_continue != 0) {
|
||||
ret = ERR_AUTH_CONTINUE;
|
||||
@@ -816,7 +816,7 @@ int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg *req, pi
|
||||
|
||||
void sec_auth_user_deinit(sec_mod_st *sec, client_entry_st *e)
|
||||
{
|
||||
seclog(sec, LOG_DEBUG, "permamently closing session of user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_DEBUG, "permamently closing session of user '%s' "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
if (sec->perm_config->acct.amod != NULL && sec->perm_config->acct.amod->close_session != NULL && e->session_is_open != 0) {
|
||||
sec->perm_config->acct.amod->close_session(e->auth_type, &e->acct_info, &e->saved_stats, e->discon_reason);
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@ void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec)
|
||||
break;
|
||||
|
||||
cookie_int_msg__init(&cookies[msg.n_cookies]);
|
||||
cookies[msg.n_cookies].sid.data = t->sid;
|
||||
cookies[msg.n_cookies].sid.len = sizeof(t->sid);
|
||||
cookies[msg.n_cookies].safe_id.data = (void*)t->acct_info.safe_id;
|
||||
cookies[msg.n_cookies].safe_id.len = sizeof(t->acct_info.safe_id);
|
||||
|
||||
cookies[msg.n_cookies].session_is_open = t->session_is_open;
|
||||
cookies[msg.n_cookies].tls_auth_ok = t->tls_auth_ok;
|
||||
|
||||
@@ -116,7 +116,7 @@ client_entry_st *new_client_entry(sec_mod_st *sec, const char *ip, unsigned pid)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
oc_base64_encode((char *)e->sid, SID_SIZE, (char *)e->acct_info.psid, sizeof(e->acct_info.psid));
|
||||
calc_safe_id(e->sid, SID_SIZE, (char *)e->acct_info.safe_id, sizeof(e->acct_info.safe_id));
|
||||
e->time = time(0);
|
||||
|
||||
if (htable_add(db, rehash(e, NULL), e) == 0) {
|
||||
@@ -195,11 +195,11 @@ void expire_client_entry(sec_mod_st *sec, client_entry_st * e)
|
||||
if (sec->config->persistent_cookies == 0 && (e->discon_reason == REASON_USER_DISCONNECT
|
||||
|| e->discon_reason == REASON_SERVER_DISCONNECT || e->discon_reason == REASON_SESSION_TIMEOUT)) {
|
||||
seclog(sec, LOG_INFO, "invalidating session of user '%s' "SESSION_STR,
|
||||
e->acct_info.username, e->acct_info.psid);
|
||||
e->acct_info.username, e->acct_info.safe_id);
|
||||
/* immediately disconnect the user */
|
||||
del_client_entry(sec, e);
|
||||
} else {
|
||||
seclog(sec, LOG_INFO, "temporarily closing session for %s "SESSION_STR, e->acct_info.username, e->acct_info.psid);
|
||||
seclog(sec, LOG_INFO, "temporarily closing session for %s "SESSION_STR, e->acct_info.username, e->acct_info.safe_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <ccan/htable/htable.h>
|
||||
#include <nettle/base64.h>
|
||||
#include <tlslib.h>
|
||||
#include "common/common.h"
|
||||
|
||||
#define SESSION_STR "(session: %.6s)"
|
||||
#define MAX_GROUPS 32
|
||||
@@ -60,7 +61,7 @@ typedef struct common_auth_init_st {
|
||||
typedef struct common_acct_info_st {
|
||||
char username[MAX_USERNAME_SIZE*2];
|
||||
char groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */
|
||||
char psid[BASE64_ENCODE_RAW_LENGTH(SID_SIZE) + 1]; /* printable */
|
||||
char safe_id[SAFE_ID_SIZE]; /* an ID to be sent to external apps - printable */
|
||||
char remote_ip[MAX_IP_STR];
|
||||
char user_agent[MAX_AGENT_NAME];
|
||||
char our_ip[MAX_IP_STR];
|
||||
|
||||
@@ -154,5 +154,6 @@ ssize_t dtls_recv_packet(struct worker_st *ws, gnutls_datum_t *data, void **p);
|
||||
|
||||
/* Helper functions */
|
||||
unsigned need_file_reload(const char *file, time_t last_access);
|
||||
void safe_hash(const uint8_t *data, unsigned data_size, uint8_t output[20]);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user