1 /*
2  * Copyright (C) 2013 Nikos Mavrogiannopoulos
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of ocserv.
7  *
8  * ocserv is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>
20  */
21 #ifndef SEC_MOD_H
22 # define SEC_MOD_H
23 
24 #include <gnutls/abstract.h>
25 #include <ccan/htable/htable.h>
26 #include <nettle/base64.h>
27 #include <tlslib.h>
28 #include <hmac.h>
29 #include "common/common.h"
30 
31 #include "vhost.h"
32 
33 #define SESSION_STR "(session: %.6s)"
34 #define MAX_GROUPS 32
35 
36 typedef struct sec_mod_st {
37 	struct list_head *vconfig;
38 	void *config_pool;
39 	void *sec_mod_pool;
40 
41 	struct htable *client_db;
42 	int cmd_fd;
43 	int cmd_fd_sync;
44 
45 	tls_sess_db_st tls_db;
46 	uint64_t auth_failures; /* auth failures since the last update (SECM_CLI_STATS) we sent to main */
47 	uint32_t max_auth_time; /* the maximum time spent in (sucessful) authentication */
48 	uint32_t avg_auth_time; /* the average time spent in (sucessful) authentication */
49 	uint32_t total_authentications; /* successful authentications: to calculate the average above */
50 	time_t last_stats_reset;
51 	const uint8_t hmac_key[HMAC_DIGEST_SIZE];
52 	uint32_t sec_mod_instance_id;
53 } sec_mod_st;
54 
55 typedef struct stats_st {
56 	uint64_t bytes_in;
57 	uint64_t bytes_out;
58 	time_t uptime;
59 } stats_st;
60 
61 typedef struct common_auth_init_st {
62 	const char *username;
63 	const char *ip;
64 	const char *our_ip;
65 	const char *user_agent;
66 	unsigned id;
67 } common_auth_init_st;
68 
69 typedef struct common_acct_info_st {
70 	char username[MAX_USERNAME_SIZE*2];
71 	char groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */
72 	char safe_id[SAFE_ID_SIZE]; /* an ID to be sent to external apps - printable */
73 	char remote_ip[MAX_IP_STR];
74 	char user_agent[MAX_AGENT_NAME];
75 	char device_type[MAX_DEVICE_TYPE];
76 	char device_platform[MAX_DEVICE_PLATFORM];
77 	char our_ip[MAX_IP_STR];
78 	char ipv4[MAX_IP_STR];
79 	char ipv6[MAX_IP_STR];
80 	unsigned id;
81 } common_acct_info_st;
82 
83 #define IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, clean) (e->exptime != -1 && now >= e->exptime && e->in_use == 0)
84 #define IS_CLIENT_ENTRY_EXPIRED(sec, e, now) IS_CLIENT_ENTRY_EXPIRED_FULL(sec, e, now, 0)
85 
86 typedef struct client_entry_st {
87 	/* A unique session identifier used to distinguish sessions
88 	 * prior to authentication. It is sent as cookie to the client
89 	 * who re-uses it when it performs authentication in multiple
90 	 * sessions.
91 	 */
92 	uint8_t sid[SID_SIZE];
93 
94 	void *auth_ctx; /* the context of authentication */
95 	unsigned session_is_open; /* whether open_session was done */
96 	unsigned in_use; /* counter of users of this structure */
97 	unsigned tls_auth_ok;
98 
99 	char *msg_str;
100 	unsigned passwd_counter; /* if msg_str is for a password this indicates the passwrd number (0,1,2) */
101 
102 	stats_st saved_stats; /* saved from previous cookie usage */
103 	stats_st stats; /* current */
104 
105 	unsigned status; /* PS_AUTH_ */
106 
107 	uint8_t dtls_session_id[GNUTLS_MAX_SESSION_ID];
108 
109 	/* The time this client entry was created */
110 	time_t created;
111 	/* The time this client entry is supposed to expire */
112 	time_t exptime;
113 
114 	/* the auth type associated with the user */
115 	unsigned auth_type;
116 	unsigned discon_reason; /* reason for disconnection */
117 
118 	struct common_acct_info_st acct_info;
119 
120 	/* saved during authentication; used after successful auth */
121 	char req_group_name[MAX_GROUPNAME_SIZE]; /* the requested by the user group */
122 	char *cert_group_names[MAX_GROUPS];
123 	unsigned cert_group_names_size;
124 	char cert_user_name[MAX_USERNAME_SIZE];
125 
126 	/* the module this entry is using */
127 	const struct auth_mod_st *module;
128 	void *vhost_auth_ctx;
129 	void *vhost_acct_ctx;
130 
131 	/* the vhost this user is associated with */
132 	vhost_cfg_st *vhost;
133 } client_entry_st;
134 
135 void *sec_mod_client_db_init(sec_mod_st *sec);
136 void sec_mod_client_db_deinit(sec_mod_st *sec);
137 unsigned sec_mod_client_db_elems(sec_mod_st *sec);
138 client_entry_st * new_client_entry(sec_mod_st *sec, struct vhost_cfg_st *, const char *ip, unsigned pid);
139 client_entry_st * find_client_entry(sec_mod_st *sec, uint8_t sid[SID_SIZE]);
140 void del_client_entry(sec_mod_st *sec, client_entry_st * e);
141 void expire_client_entry(sec_mod_st *sec, client_entry_st * e);
142 void cleanup_client_entries(sec_mod_st *sec);
143 
144 #ifdef __GNUC__
145 # define seclog(sec, prio, fmt, ...) \
146 	if (prio != LOG_DEBUG || GETPCONFIG(sec)->debug >= 3) { \
147 		syslog(prio, "sec-mod: "fmt, ##__VA_ARGS__); \
148 	}
149 #else
150 # define seclog(sec,prio,...) \
151 	if (prio != LOG_DEBUG || GETPCONFIG(sec)->debug >= 3) { \
152 		 syslog(prio, __VA_ARGS__); \
153 	}
154 #endif
155 
156 void  seclog_hex(const struct sec_mod_st* sec, int priority,
157 		const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
158 
159 void sec_auth_init(struct vhost_cfg_st *vhost);
160 
161 void handle_secm_list_cookies_reply(void *pool, int fd, sec_mod_st *sec);
162 void handle_sec_auth_ban_ip_reply(sec_mod_st *sec, const BanIpReplyMsg *msg);
163 int handle_sec_auth_init(int cfd, sec_mod_st *sec, const SecAuthInitMsg * req, pid_t pid);
164 int handle_sec_auth_cont(int cfd, sec_mod_st *sec, const SecAuthContMsg * req);
165 int handle_secm_session_open_cmd(sec_mod_st *sec, int fd, const SecmSessionOpenMsg *req);
166 int handle_secm_session_close_cmd(sec_mod_st *sec, int fd, const SecmSessionCloseMsg *req);
167 int handle_sec_auth_stats_cmd(sec_mod_st * sec, const CliStatsMsg * req, pid_t pid);
168 void sec_auth_user_deinit(sec_mod_st *sec, client_entry_st *e);
169 
170 void sec_mod_server(void *main_pool, void *config_pool, struct list_head *vconfig,
171 		    const char *socket_file,
172 		    int cmd_fd, int cmd_fd_sync,
173 			size_t  hmac_key_length, const uint8_t * hmac_key,
174 			const uint8_t instance_id);
175 
176 #endif
177