コード例 #1
0
static int recv_auth_reply(worker_st * ws, int sd, char **txt)
{
	int ret;
	SecAuthReplyMsg *msg = NULL;
	PROTOBUF_ALLOCATOR(pa, ws);

	ret = recv_msg(ws, sd, SM_CMD_AUTH_REP,
		       (void *)&msg, (unpack_func) sec_auth_reply_msg__unpack);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "error receiving auth reply message");
		return ret;
	}

	oclog(ws, LOG_DEBUG, "received auth reply message (value: %u)",
	      (unsigned)msg->reply);

	if (txt) *txt = NULL;

	switch (msg->reply) {
	case AUTH__REP__MSG:
		if (txt == NULL || msg->msg == NULL) {
			oclog(ws, LOG_ERR, "received unexpected msg");
			return ERR_AUTH_FAIL;
		}

		*txt = talloc_strdup(ws, msg->msg);
		if (msg->has_sid && msg->sid.len == sizeof(ws->sid)) {
			/* update our sid */
			memcpy(ws->sid, msg->sid.data, sizeof(ws->sid));
			ws->sid_set = 1;
		}

		ret = ERR_AUTH_CONTINUE;
		goto cleanup;
	case AUTH__REP__OK:
		if (msg->user_name == NULL) {
			ret = ERR_AUTH_FAIL;
			goto cleanup;
		}

		strlcpy(ws->username, msg->user_name, sizeof(ws->username));
		if (msg->has_sid && msg->sid.len == sizeof(ws->sid)) {
			/* update our sid */
			memcpy(ws->sid, msg->sid.data, sizeof(ws->sid));
			ws->sid_set = 1;
		}

		if (msg->has_cookie == 0 ||
		    msg->cookie.len == 0 ||
		    msg->dtls_session_id.len != sizeof(ws->session_id)) {

			ret = ERR_AUTH_FAIL;
			goto cleanup;
		}
		
		ws->cookie = talloc_memdup(ws, msg->cookie.data, msg->cookie.len);
		if (ws->cookie) {
			ws->cookie_size = msg->cookie.len;
			ws->cookie_set = 1;
		}
		memcpy(ws->session_id, msg->dtls_session_id.data,
		       msg->dtls_session_id.len);

		if (txt)
			*txt = talloc_strdup(ws, msg->msg);

		break;
	case AUTH__REP__FAILED:
	default:
		if (msg->reply != AUTH__REP__FAILED)
			oclog(ws, LOG_ERR, "unexpected auth reply %u",
			      (unsigned)msg->reply);
		ret = ERR_AUTH_FAIL;
		goto cleanup;
	}

	ret = 0;
 cleanup:
	sec_auth_reply_msg__free_unpacked(msg, &pa);
	return ret;
}
コード例 #2
0
ファイル: sec-mod.c プロジェクト: xyz12810/ocserv
static
int process_packet_from_main(void *pool, int fd, sec_mod_st * sec, cmd_request_t cmd,
		   uint8_t * buffer, size_t buffer_size)
{
	gnutls_datum_t data;
	int ret;
	PROTOBUF_ALLOCATOR(pa, pool);

	seclog(sec, LOG_DEBUG, "cmd [size=%d] %s\n", (int)buffer_size,
	       cmd_request_to_str(cmd));
	data.data = buffer;
	data.size = buffer_size;

	switch (cmd) {
	case CMD_SECM_LIST_COOKIES:
		handle_secm_list_cookies_reply(pool, fd, sec);

		return 0;
	case CMD_SECM_BAN_IP_REPLY:{
		BanIpReplyMsg *msg = NULL;

		msg =
		    ban_ip_reply_msg__unpack(&pa, data.size,
					     data.data);
		if (msg == NULL) {
			seclog(sec, LOG_INFO, "error unpacking auth ban ip reply\n");
			return ERR_BAD_COMMAND;
		}

		handle_sec_auth_ban_ip_reply(sec, msg);
		ban_ip_reply_msg__free_unpacked(msg, &pa);

		return 0;
	}
	case CMD_SECM_SESSION_OPEN:{
			SecmSessionOpenMsg *msg;

			msg =
			    secm_session_open_msg__unpack(&pa, data.size,
						      data.data);
			if (msg == NULL) {
				seclog(sec, LOG_INFO, "error unpacking session open\n");
				return ERR_BAD_COMMAND;
			}

			ret = handle_secm_session_open_cmd(sec, fd, msg);
			secm_session_open_msg__free_unpacked(msg, &pa);

			return ret;
		}
	case CMD_SECM_SESSION_CLOSE:{
			SecmSessionCloseMsg *msg;

			msg =
			    secm_session_close_msg__unpack(&pa, data.size,
						      data.data);
			if (msg == NULL) {
				seclog(sec, LOG_INFO, "error unpacking session close\n");
				return ERR_BAD_COMMAND;
			}

			ret = handle_secm_session_close_cmd(sec, fd, msg);
			secm_session_close_msg__free_unpacked(msg, &pa);

			return ret;
		}
	default:
		seclog(sec, LOG_WARNING, "unknown type 0x%.2x", cmd);
		return ERR_BAD_COMMAND;
	}

	return 0;
}
コード例 #3
0
/* auth reply from main process */
static int recv_cookie_auth_reply(worker_st * ws)
{
	unsigned i;
	int ret;
	int socketfd = -1;
	AuthReplyMsg *msg = NULL;
	PROTOBUF_ALLOCATOR(pa, ws);

	ret = recv_socket_msg(ws, ws->cmd_fd, AUTH_COOKIE_REP, &socketfd,
			      (void *)&msg,
			      (unpack_func) auth_reply_msg__unpack);
	if (ret < 0) {
		oclog(ws, LOG_ERR, "error receiving auth reply message");
		return ret;
	}

	oclog(ws, LOG_DEBUG, "received auth reply message (value: %u)",
	      (unsigned)msg->reply);

	switch (msg->reply) {
	case AUTH__REP__OK:
		if (socketfd != -1) {
			ws->tun_fd = socketfd;

			if (msg->vname == NULL || msg->user_name == NULL) {
				ret = ERR_AUTH_FAIL;
				goto cleanup;
			}

			strlcpy(ws->vinfo.name, msg->vname, sizeof(ws->vinfo.name));
			strlcpy(ws->username, msg->user_name, sizeof(ws->username));

			if (msg->group_name != NULL) {
				strlcpy(ws->groupname, msg->group_name, sizeof(ws->groupname));
			} else {
				ws->groupname[0] = 0;
			}

			memcpy(ws->session_id, msg->session_id.data,
			       msg->session_id.len);

			if (msg->ipv4 != NULL) {
				talloc_free(ws->vinfo.ipv4);
				if (strcmp(msg->ipv4, "0.0.0.0") == 0)
					ws->vinfo.ipv4 = NULL;
				else
					ws->vinfo.ipv4 =
					    talloc_strdup(ws, msg->ipv4);
			}

			if (msg->ipv6 != NULL) {
				talloc_free(ws->vinfo.ipv6);
				if (strcmp(msg->ipv6, "::") == 0)
					ws->vinfo.ipv6 = NULL;
				else
					ws->vinfo.ipv6 =
					    talloc_strdup(ws, msg->ipv6);
			}

			if (msg->ipv4_local != NULL) {
				talloc_free(ws->vinfo.ipv4_local);
				if (strcmp(msg->ipv4_local, "0.0.0.0") == 0)
					ws->vinfo.ipv4_local = NULL;
				else
					ws->vinfo.ipv4_local =
					    talloc_strdup(ws, msg->ipv4_local);
			}

			if (msg->ipv6_local != NULL) {
				talloc_free(ws->vinfo.ipv6_local);
				if (strcmp(msg->ipv6_local, "::") == 0)
					ws->vinfo.ipv6_local = NULL;
				else
					ws->vinfo.ipv6_local =
					    talloc_strdup(ws, msg->ipv6_local);
			}

			/* Read any additional data */
			if (msg->ipv4_netmask != NULL) {
				talloc_free(ws->config->network.ipv4_netmask);
				ws->config->network.ipv4_netmask =
				    talloc_strdup(ws, msg->ipv4_netmask);
			}

			if (msg->ipv4_network != NULL) {
				talloc_free(ws->config->network.ipv4_network);
				ws->config->network.ipv4_network =
				    talloc_strdup(ws, msg->ipv4_network);
			}

			if (msg->ipv6_network != NULL) {
				talloc_free(ws->config->network.ipv6_network);
				ws->config->network.ipv6_network =
				    talloc_strdup(ws, msg->ipv6_network);
			}

			if (msg->has_ipv6_prefix) {
				ws->config->network.ipv6_prefix = msg->ipv6_prefix;
			}

			if (msg->has_rx_per_sec)
				ws->config->rx_per_sec = msg->rx_per_sec;

			if (msg->has_tx_per_sec)
				ws->config->tx_per_sec = msg->tx_per_sec;

			if (msg->has_net_priority)
				ws->config->net_priority = msg->net_priority;

			if (msg->has_no_udp && msg->no_udp != 0)
				ws->perm_config->udp_port = 0;

			if (msg->xml_config_file) {
				talloc_free(ws->config->xml_config_file);
				ws->config->xml_config_file = talloc_strdup(ws, msg->xml_config_file);
			}

			/* routes */
			ws->routes = talloc_size(ws, msg->n_routes*sizeof(char*));
			if (ws->routes != NULL) {
				ws->routes_size = msg->n_routes;
				for (i = 0; i < ws->routes_size; i++) {
					ws->routes[i] =
					    talloc_strdup(ws, msg->routes[i]);

					/* If a default route is detected */
					if (ws->routes[i] != NULL &&
					    (strcmp(ws->routes[i], "default") == 0 ||
					     strcmp(ws->routes[i], "0.0.0.0/0") == 0)) {

					     /* disable all routes */
					     ws->routes_size = 0;
					     ws->default_route = 1;
					     break;
					}
				}
			}

			if (check_if_default_route(ws->routes, ws->routes_size))
				ws->default_route = 1;

			ws->no_routes = talloc_size(ws, msg->n_no_routes*sizeof(char*));
			if (ws->no_routes != NULL) {
				ws->no_routes_size = msg->n_no_routes;
				for (i = 0; i < ws->no_routes_size; i++) {
					ws->no_routes[i] =
					    talloc_strdup(ws, msg->no_routes[i]);
				}
			}

			ws->dns = talloc_size(ws, msg->n_dns*sizeof(char*));
			if (ws->dns != NULL) {
				ws->dns_size = msg->n_dns;
				for (i = 0; i < ws->dns_size; i++) {
					ws->dns[i] = talloc_strdup(ws, msg->dns[i]);
				}
			}

			ws->nbns = talloc_size(ws, msg->n_nbns*sizeof(char*));
			if (ws->nbns != NULL) {
				ws->nbns_size = msg->n_nbns;
				for (i = 0; i < ws->nbns_size; i++) {
					ws->nbns[i] = talloc_strdup(ws, msg->nbns[i]);
				}
			}
		} else {
			oclog(ws, LOG_ERR, "error in received message");
			ret = ERR_AUTH_FAIL;
			goto cleanup;
		}
		break;
	case AUTH__REP__FAILED:
	default:
		if (msg->reply != AUTH__REP__FAILED)
			oclog(ws, LOG_ERR, "unexpected auth reply %u",
			      (unsigned)msg->reply);
		ret = ERR_AUTH_FAIL;
		goto cleanup;
	}

	ret = 0;
 cleanup:
	auth_reply_msg__free_unpacked(msg, &pa);
	return ret;
}
コード例 #4
0
ファイル: sec-mod.c プロジェクト: xyz12810/ocserv
static
int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st * sec, cmd_request_t cmd,
		   uint8_t * buffer, size_t buffer_size)
{
	unsigned i;
	gnutls_datum_t data, out;
	int ret;
	SecOpMsg *op;
	PROTOBUF_ALLOCATOR(pa, pool);

	seclog(sec, LOG_DEBUG, "cmd [size=%d] %s\n", (int)buffer_size,
	       cmd_request_to_str(cmd));
	data.data = buffer;
	data.size = buffer_size;

	switch (cmd) {
	case CMD_SEC_SIGN:
	case CMD_SEC_DECRYPT:
		op = sec_op_msg__unpack(&pa, data.size, data.data);
		if (op == NULL) {
			seclog(sec, LOG_INFO, "error unpacking sec op\n");
			return -1;
		}

		i = op->key_idx;
		if (op->has_key_idx == 0 || i >= sec->key_size) {
			seclog(sec, LOG_INFO,
			       "received out-of-bounds key index (%d)", i);
			return -1;
		}

		data.data = op->data.data;
		data.size = op->data.len;

		if (cmd == CMD_SEC_DECRYPT) {
			ret =
			    gnutls_privkey_decrypt_data(sec->key[i], 0, &data,
							&out);
		} else {
#if GNUTLS_VERSION_NUMBER >= 0x030200
			ret =
			    gnutls_privkey_sign_hash(sec->key[i], 0,
						     GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
						     &data, &out);
#else
			ret =
			    gnutls_privkey_sign_raw_data(sec->key[i], 0, &data,
							 &out);
#endif
		}
		sec_op_msg__free_unpacked(op, &pa);

		if (ret < 0) {
			seclog(sec, LOG_INFO, "error in crypto operation: %s",
			       gnutls_strerror(ret));
			return -1;
		}

		ret = handle_op(pool, cfd, sec, cmd, out.data, out.size);
		gnutls_free(out.data);

		return ret;

	case CMD_SEC_CLI_STATS:{
			CliStatsMsg *tmsg;

			tmsg = cli_stats_msg__unpack(&pa, data.size, data.data);
			if (tmsg == NULL) {
				seclog(sec, LOG_ERR, "error unpacking data");
				return -1;
			}

			ret = handle_sec_auth_stats_cmd(sec, tmsg, pid);
			cli_stats_msg__free_unpacked(tmsg, &pa);
			return ret;
		}
		break;

	case CMD_SEC_AUTH_INIT:{
			SecAuthInitMsg *auth_init;

			auth_init =
			    sec_auth_init_msg__unpack(&pa, data.size,
						      data.data);
			if (auth_init == NULL) {
				seclog(sec, LOG_INFO, "error unpacking auth init\n");
				return -1;
			}

			ret = handle_sec_auth_init(cfd, sec, auth_init, pid);
			sec_auth_init_msg__free_unpacked(auth_init, &pa);
			return ret;
		}
	case CMD_SEC_AUTH_CONT:{
			SecAuthContMsg *auth_cont;

			auth_cont =
			    sec_auth_cont_msg__unpack(&pa, data.size,
						      data.data);
			if (auth_cont == NULL) {
				seclog(sec, LOG_INFO, "error unpacking auth cont\n");
				return -1;
			}

			ret = handle_sec_auth_cont(cfd, sec, auth_cont);
			sec_auth_cont_msg__free_unpacked(auth_cont, &pa);
			return ret;
		}
	case RESUME_STORE_REQ:{
			SessionResumeStoreReqMsg *smsg;

			smsg =
			    session_resume_store_req_msg__unpack(&pa, buffer_size,
								 buffer);
			if (smsg == NULL) {
				seclog(sec, LOG_ERR, "error unpacking data");
				return ERR_BAD_COMMAND;
			}

			ret = handle_resume_store_req(sec, smsg);

			/* zeroize the data */
			safe_memset(buffer, 0, buffer_size);
			safe_memset(smsg->session_data.data, 0, smsg->session_data.len);

			session_resume_store_req_msg__free_unpacked(smsg, &pa);

			if (ret < 0) {
				seclog(sec, LOG_DEBUG,
				      "could not store resumption data");
			}
		}

		break;

	case RESUME_DELETE_REQ:{
			SessionResumeFetchMsg *fmsg;

			fmsg =
			    session_resume_fetch_msg__unpack(&pa, buffer_size,
							     buffer);
			if (fmsg == NULL) {
				seclog(sec, LOG_ERR, "error unpacking data");
				return ERR_BAD_COMMAND;
			}

			ret = handle_resume_delete_req(sec, fmsg);

			session_resume_fetch_msg__free_unpacked(fmsg, &pa);

			if (ret < 0) {
				seclog(sec, LOG_DEBUG,
				      "could not delete resumption data.");
			}
		}

		break;
	case RESUME_FETCH_REQ:{
			SessionResumeReplyMsg msg =
			    SESSION_RESUME_REPLY_MSG__INIT;
			SessionResumeFetchMsg *fmsg;

			/* FIXME: rate limit that */

			fmsg =
			    session_resume_fetch_msg__unpack(&pa, buffer_size,
							     buffer);
			if (fmsg == NULL) {
				seclog(sec, LOG_ERR, "error unpacking data");
				return ERR_BAD_COMMAND;
			}

			ret = handle_resume_fetch_req(sec, fmsg, &msg);

			session_resume_fetch_msg__free_unpacked(fmsg, &pa);

			if (ret < 0) {
				msg.reply =
				    SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED;
				seclog(sec, LOG_DEBUG,
				      "could not fetch resumption data.");
			} else {
				msg.reply =
				    SESSION_RESUME_REPLY_MSG__RESUME__REP__OK;
			}

			ret =
			    send_msg(pool, cfd, RESUME_FETCH_REP, &msg,
					       (pack_size_func)
					       session_resume_reply_msg__get_packed_size,
					       (pack_func)
					       session_resume_reply_msg__pack);

			if (ret < 0) {
				seclog(sec, LOG_ERR,
				      "could not send reply cmd %d.",
				      (unsigned)cmd);
				return ERR_BAD_COMMAND;
			}

		}

		break;

	default:
		seclog(sec, LOG_WARNING, "unknown type 0x%.2x", cmd);
		return -1;
	}

	return 0;
}