Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
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;
}