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:
Nikos Mavrogiannopoulos
2017-01-25 20:07:00 +01:00
parent 3033591343
commit fdea01f4f5
12 changed files with 76 additions and 39 deletions

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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];

View File

@@ -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