int handle_sec_auth_cont(int cfd, sec_mod_st * sec, const SecAuthContMsg * req) { client_entry_st *e; int ret; if (req->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "auth cont but with illegal sid size (%d)!", (int)req->sid.len); return -1; } e = find_client_entry(sec, req->sid.data); if (e == NULL) { seclog(sec, LOG_ERR, "auth cont but with non-existing sid!"); return -1; } 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->auth_info.username, e->auth_info.psid, e->status); ret = -1; goto cleanup; } seclog(sec, LOG_DEBUG, "auth cont for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); if (req->password == NULL) { seclog(sec, LOG_ERR, "no password given in auth cont for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); ret = -1; goto cleanup; } if (e->module == NULL) { seclog(sec, LOG_ERR, "no module available!"); ret = -1; goto cleanup; } e->status = PS_AUTH_CONT; ret = e->module->auth_pass(e->auth_ctx, req->password, strlen(req->password)); if (ret < 0) { if (ret != ERR_AUTH_CONTINUE) { seclog(sec, LOG_DEBUG, "error in password given in auth cont for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); } goto cleanup; } cleanup: return handle_sec_auth_res(cfd, sec, e, ret); }
int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req) { client_entry_st *e; stats_st totals; if (req->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "auth session stats but with illegal sid size (%d)!", (int)req->sid.len); return -1; } e = find_client_entry(sec, req->sid.data); if (e == NULL) { char tmp[BASE64_LENGTH(SID_SIZE) + 1]; base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp)); seclog(sec, LOG_INFO, "session stats but with non-existing SID: %s", tmp); return -1; } if (e->status != PS_AUTH_COMPLETED) { seclog(sec, LOG_ERR, "session stats received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid); return -1; } /* stats only increase */ if (req->bytes_in > e->stats.bytes_in) e->stats.bytes_in = req->bytes_in; if (req->bytes_out > e->stats.bytes_out) e->stats.bytes_out = req->bytes_out; if (req->uptime > e->stats.uptime) e->stats.uptime = req->uptime; if (req->has_discon_reason && req->discon_reason != 0) { e->discon_reason = req->discon_reason; } if (sec->perm_config->acct.amod == NULL || sec->perm_config->acct.amod->session_stats == NULL) return 0; stats_add_to(&totals, &e->stats, &e->saved_stats); if (req->remote_ip) strlcpy(e->auth_info.remote_ip, req->remote_ip, sizeof(e->auth_info.remote_ip)); if (req->ipv4) strlcpy(e->auth_info.ipv4, req->ipv4, sizeof(e->auth_info.ipv4)); if (req->ipv6) strlcpy(e->auth_info.ipv6, req->ipv6, sizeof(e->auth_info.ipv6)); sec->perm_config->acct.amod->session_stats(e->auth_type, e->auth_ctx, &e->auth_info, &totals); return 0; }
client_entry_st *new_client_entry(sec_mod_st *sec, const char *ip) { struct htable *db = sec->client_db; client_entry_st *e, *te; int ret; int retries = 3; e = talloc_zero(db, client_entry_st); if (e == NULL) { return NULL; } strlcpy(e->auth_info.remote_ip, ip, sizeof(e->auth_info.remote_ip)); do { ret = gnutls_rnd(GNUTLS_RND_RANDOM, e->sid, sizeof(e->sid)); if (ret < 0) { seclog(sec, LOG_ERR, "error generating SID"); goto fail; } /* check if in use */ te = find_client_entry(sec, e->sid); } while(te != NULL && retries-- >= 0); if (te != NULL) { seclog(sec, LOG_ERR, "could not generate a unique SID!"); goto fail; } base64_encode((char *)e->sid, SID_SIZE, (char *)e->auth_info.psid, sizeof(e->auth_info.psid)); e->time = time(0); if (htable_add(db, rehash(e, NULL), e) == 0) { seclog(sec, LOG_ERR, "could not add client entry to hash table"); goto fail; } return e; fail: talloc_free(e); return NULL; }
void handle_sec_auth_ban_ip_reply(sec_mod_st *sec, const BanIpReplyMsg *msg) { client_entry_st *e; if (msg->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "ban IP reply but with illegal sid size (%d)!", (int)msg->sid.len); return; } e = find_client_entry(sec, msg->sid.data); if (e == NULL) { return; } if (msg->reply != AUTH__REP__OK) { e->status = PS_AUTH_FAILED; } return; }
static int handle_sec_auth_session_close(sec_mod_st *sec, int fd, const SecAuthSessionMsg *req) { client_entry_st *e; int ret; CliStatsMsg rep = CLI_STATS_MSG__INIT; if (req->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "auth session close but with illegal sid size (%d)!", (int)req->sid.len); return ERR_BAD_COMMAND; } e = find_client_entry(sec, req->sid.data); if (e == NULL) { char tmp[BASE64_LENGTH(SID_SIZE) + 1]; base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp)); seclog(sec, LOG_INFO, "session close but with non-existing SID: %s", tmp); return send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep, (pack_size_func) cli_stats_msg__get_packed_size, (pack_func) cli_stats_msg__pack); } if (e->status < PS_AUTH_COMPLETED) { seclog(sec, LOG_DEBUG, "session close received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid); return send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep, (pack_size_func) cli_stats_msg__get_packed_size, (pack_func) cli_stats_msg__pack); } if (req->has_uptime && req->uptime > e->stats.uptime) { e->stats.uptime = req->uptime; } if (req->has_bytes_in && req->bytes_in > e->stats.bytes_in) { e->stats.bytes_in = req->bytes_in; } if (req->has_bytes_out && req->bytes_out > e->stats.bytes_out) { e->stats.bytes_out = req->bytes_out; } /* send reply */ rep.bytes_in = e->stats.bytes_in; rep.bytes_out = e->stats.bytes_out; rep.has_secmod_client_entries = 1; rep.secmod_client_entries = sec_mod_client_db_elems(sec); ret = send_msg(e, fd, SM_CMD_AUTH_CLI_STATS, &rep, (pack_size_func) cli_stats_msg__get_packed_size, (pack_func) cli_stats_msg__pack); if (ret < 0) { seclog(sec, LOG_ERR, "error in sending session stats"); return ERR_BAD_COMMAND; } /* save total stats */ stats_add_to(&e->saved_stats, &e->saved_stats, &e->stats); memset(&e->stats, 0, sizeof(e->stats)); expire_client_entry(sec, e); return 0; }
static int handle_sec_auth_session_open(sec_mod_st *sec, int fd, const SecAuthSessionMsg *req) { client_entry_st *e; void *lpool; int ret; SecAuthSessionReplyMsg rep = SEC_AUTH_SESSION_REPLY_MSG__INIT; if (req->sid.len != SID_SIZE) { seclog(sec, LOG_ERR, "auth session open but with illegal sid size (%d)!", (int)req->sid.len); return send_failed_session_open_reply(sec, fd); } e = find_client_entry(sec, req->sid.data); if (e == NULL) { char tmp[BASE64_LENGTH(SID_SIZE) + 1]; base64_encode((char *)req->sid.data, req->sid.len, (char *)tmp, sizeof(tmp)); seclog(sec, LOG_INFO, "session open but with non-existing SID: %s!", tmp); return send_failed_session_open_reply(sec, fd); } if (e->status != PS_AUTH_COMPLETED) { seclog(sec, LOG_ERR, "session open received in unauthenticated client %s "SESSION_STR"!", e->auth_info.username, e->auth_info.psid); return send_failed_session_open_reply(sec, fd); } if (e->time != -1 && time(0) > e->time + sec->config->cookie_timeout) { seclog(sec, LOG_ERR, "session expired; denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); e->status = PS_AUTH_FAILED; return send_failed_session_open_reply(sec, fd); } if (req->has_cookie == 0 || (req->cookie.len != e->cookie_size) || memcmp(req->cookie.data, e->cookie, e->cookie_size) != 0) { seclog(sec, LOG_ERR, "cookie error; denied session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); e->status = PS_AUTH_FAILED; return send_failed_session_open_reply(sec, fd); } if (req->ipv4) strlcpy(e->auth_info.ipv4, req->ipv4, sizeof(e->auth_info.ipv4)); if (req->ipv6) strlcpy(e->auth_info.ipv6, req->ipv6, sizeof(e->auth_info.ipv6)); if (sec->perm_config->acct.amod != NULL && sec->perm_config->acct.amod->open_session != NULL && e->session_is_open == 0) { ret = sec->perm_config->acct.amod->open_session(e->auth_type, e->auth_ctx, &e->auth_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->auth_info.username, e->auth_info.psid); return send_failed_session_open_reply(sec, fd); } else { e->session_is_open = 1; } } rep.reply = AUTH__REP__OK; lpool = talloc_new(e); if (lpool == NULL) { return ERR_BAD_COMMAND; /* we desync */ } 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->auth_info.username, e->auth_info.psid); talloc_free(lpool); return send_failed_session_open_reply(sec, fd); } } ret = send_msg(lpool, 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(sec, LOG_ERR, "error in sending session reply"); return ERR_BAD_COMMAND; /* we desync */ } talloc_free(lpool); seclog(sec, LOG_INFO, "initiating session for user '%s' "SESSION_STR, e->auth_info.username, e->auth_info.psid); e->time = -1; e->in_use++; return 0; }