1 /*
2 * Copyright (C) 2013-2018 Nikos Mavrogiannopoulos
3 * Copyright (C) 2015 Red Hat, Inc.
4 *
5 * Author: Nikos Mavrogiannopoulos
6 *
7 * This file is part of ocserv.
8 *
9 * ocserv is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 */
22 #ifndef MAIN_H
23 # define MAIN_H
24
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/resource.h>
28 #include <unistd.h>
29 #include <net/if.h>
30 #include <vpn.h>
31 #include <tlslib.h>
32 #include "ipc.pb-c.h"
33 #include <common.h>
34 #include <sys/un.h>
35 #include <sys/uio.h>
36 #include <signal.h>
37 #include <ev.h>
38 #include <hmac.h>
39 #include "vhost.h"
40 #include <namespace.h>
41
42 #if defined(__FreeBSD__) || defined(__OpenBSD__)
43 # include <limits.h>
44 # define SOL_IP IPPROTO_IP
45 #endif
46
47 #define COOKIE_KEY_SIZE 16
48
49 extern int saved_argc;
50 extern char **saved_argv;
51
52 extern struct ev_loop *main_loop;
53 extern ev_timer maintainance_watcher;
54
55 #define MAIN_MAINTENANCE_TIME (900)
56
57 int cmd_parser (void *pool, int argc, char **argv, struct list_head *head, bool worker);
58
59 #if defined(CAPTURE_LATENCY_SUPPORT)
60 #define LATENCY_AGGREGATION_TIME (60)
61 #endif
62
63 #define MINIMUM_USERS_PER_SEC_MOD 500
64
65 struct listener_st {
66 ev_io io;
67 struct list_node list;
68 int fd;
69 sock_type_t sock_type;
70
71 struct sockaddr_storage addr; /* local socket address */
72 socklen_t addr_len;
73 int family;
74 int protocol;
75 ev_timer resume_accept;
76 };
77
78 struct listen_list_st {
79 struct list_head head;
80 unsigned int total;
81 };
82
83 struct script_wait_st {
84 /* must be first so that this structure can behave as ev_child */
85 struct ev_child ev_child;
86
87 struct list_node list;
88
89 pid_t pid;
90 struct proc_st* proc;
91 };
92
93 /* Each worker process maps to a unique proc_st structure.
94 */
95 typedef struct proc_st {
96 /* This is first so this structure can behave as an ev_io */
97 struct ev_io io;
98 struct ev_child ev_child;
99
100 struct list_node list;
101 int fd; /* the command file descriptor */
102 pid_t pid;
103 unsigned pid_killed; /* if explicitly disconnected */
104
105 time_t udp_fd_receive_time; /* when the corresponding process has received a UDP fd */
106
107 time_t conn_time; /* the time the user connected */
108
109 /* the tun lease this process has */
110 struct tun_lease_st tun_lease;
111 struct ip_lease_st *ipv4;
112 struct ip_lease_st *ipv6;
113 unsigned leases_in_use; /* someone else got our IP leases */
114
115 struct sockaddr_storage remote_addr; /* peer address (CSTP) */
116 socklen_t remote_addr_len;
117 /* It can happen that the peer's DTLS stream comes through a different
118 * address. Most likely that's due to interception of the initial TLS/CSTP session */
119 struct sockaddr_storage dtls_remote_addr; /* peer address (DTLS) */
120 socklen_t dtls_remote_addr_len;
121 struct sockaddr_storage our_addr; /* our address */
122 socklen_t our_addr_len;
123
124 /* The SID which acts as a cookie */
125 uint8_t sid[SID_SIZE];
126 unsigned active_sid;
127
128 /* non zero if the sid has been invalidated and must not be allowed
129 * to reconnect. */
130 unsigned invalidated;
131
132 /* whether the host-update script has already been called */
133 unsigned host_updated;
134
135 /* The DTLS session ID associated with the TLS session
136 * it is either generated or restored from a cookie.
137 */
138 uint8_t dtls_session_id[GNUTLS_MAX_SESSION_ID];
139 unsigned dtls_session_id_size; /* would act as a flag if session_id is set */
140
141 /* The following are set by the worker process (or by a stored cookie) */
142 char username[MAX_USERNAME_SIZE]; /* the owner */
143 char groupname[MAX_GROUPNAME_SIZE]; /* the owner's group */
144 char hostname[MAX_HOSTNAME_SIZE]; /* the requested hostname */
145
146 /* the following are copied here from the worker process for reporting
147 * purposes (from main-ctl-handler). */
148 char user_agent[MAX_AGENT_NAME];
149 char device_type[MAX_DEVICE_TYPE];
150 char device_platform[MAX_DEVICE_PLATFORM];
151 char tls_ciphersuite[MAX_CIPHERSUITE_NAME];
152 char dtls_ciphersuite[MAX_CIPHERSUITE_NAME];
153 char cstp_compr[8];
154 char dtls_compr[8];
155 unsigned mtu;
156 unsigned int sec_mod_instance_index;
157
158 /* if the session is initiated by a cookie the following two are set
159 * and are considered when generating an IP address. That is used to
160 * generate the same address as previously allocated.
161 */
162 uint8_t ipv4_seed[4];
163
164 unsigned status; /* PS_AUTH_ */
165
166 /* these are filled in after the worker process dies, using the
167 * Cli stats message. */
168 uint64_t bytes_in;
169 uint64_t bytes_out;
170 uint32_t discon_reason; /* filled on session close */
171
172 unsigned applied_iroutes; /* whether the iroutes in the config have been successfully applied */
173
174 /* The following we rely on talloc for deallocation */
175 GroupCfgSt *config; /* custom user/group config */
176 int *config_usage_count; /* points to s->config->usage_count */
177 /* pointer to perm_cfg - set after we know the virtual host. As
178 * vhosts never get deleted, this pointer is always valid */
179 vhost_cfg_st *vhost;
180 } proc_st;
181
kill_proc(proc_st * proc)182 inline static void kill_proc(proc_st *proc)
183 {
184 kill(proc->pid, SIGTERM);
185 proc->pid_killed = 1;
186 }
187
188 struct ip_lease_db_st {
189 struct htable ht;
190 };
191
192 struct proc_list_st {
193 struct list_head head;
194 unsigned int total;
195 };
196
197 struct script_list_st {
198 struct list_head head;
199 };
200
201 struct proc_hash_db_st {
202 struct htable *db_ip;
203 struct htable *db_dtls_ip;
204 struct htable *db_dtls_id;
205 struct htable *db_sid;
206 unsigned total;
207 };
208
209 #if defined(CAPTURE_LATENCY_SUPPORT)
210 struct latency_stats_st {
211 uint64_t median_total;
212 uint64_t rms_total;
213 uint64_t sample_count;
214 };
215 #endif
216
217 struct main_stats_st {
218 uint64_t session_timeouts; /* sessions with timeout */
219 uint64_t session_idle_timeouts; /* sessions with idle timeout */
220 uint64_t session_errors; /* sessions closed with error */
221 uint64_t sessions_closed; /* sessions closed since last reset */
222 uint64_t kbytes_in;
223 uint64_t kbytes_out;
224 unsigned min_mtu;
225 unsigned max_mtu;
226
227 unsigned active_clients;
228 time_t start_time;
229 time_t last_reset;
230
231 uint32_t avg_session_mins; /* in minutes */
232 uint32_t max_session_mins;
233 uint64_t auth_failures; /* authentication failures */
234
235 /* These are counted since start time */
236 uint64_t total_auth_failures; /* authentication failures since start_time */
237 uint64_t total_sessions_closed; /* sessions closed since start_time */
238
239 #if defined(CAPTURE_LATENCY_SUPPORT)
240 struct latency_stats_st current_latency_stats;
241 struct latency_stats_st delta_latency_stats;
242 #endif
243 };
244
245 typedef struct sec_mod_instance_st {
246 struct main_server_st * server;
247 char socket_file[_POSIX_PATH_MAX];
248 char full_socket_file[_POSIX_PATH_MAX];
249 pid_t sec_mod_pid;
250
251 struct sockaddr_un secmod_addr;
252 unsigned secmod_addr_len;
253
254 int sec_mod_fd; /* messages are sent and received async */
255 int sec_mod_fd_sync; /* messages are send in a sync order (ping-pong). Only main sends. */
256 /* updated on the cli_stats_msg from sec-mod.
257 * Holds the number of entries in secmod list of users */
258 unsigned secmod_client_entries;
259 unsigned tlsdb_entries;
260 uint32_t avg_auth_time; /* in seconds */
261 uint32_t max_auth_time; /* in seconds */
262
263 } sec_mod_instance_st;
264
265 typedef struct if_address_st {
266 struct sockaddr if_addr;
267 struct sockaddr if_netmask;
268 } if_address_st;
269
270 typedef struct main_server_st {
271 /* virtual hosts are only being added to that list, never removed */
272 struct list_head *vconfig;
273
274 struct ip_lease_db_st ip_leases;
275
276 struct htable *ban_db;
277
278 struct listen_list_st listen_list;
279 struct proc_list_st proc_list;
280 struct script_list_st script_list;
281 /* maps DTLS session IDs to proc entries */
282 struct proc_hash_db_st proc_table;
283
284 struct main_stats_st stats;
285
286 void * auth_extra;
287
288 /* This one is on worker pool */
289 struct worker_st *ws;
290
291 unsigned int sec_mod_instance_count;
292 sec_mod_instance_st * sec_mod_instances;
293
294 int top_fd;
295 int ctl_fd;
296
297 void *main_pool; /* talloc main pool */
298 void *config_pool; /* talloc config pool */
299
300 const uint8_t hmac_key[HMAC_DIGEST_SIZE];
301
302 /* used as temporary buffer (currently by forward_udp_to_owner) */
303 uint8_t msg_buffer[MAX_MSG_SIZE];
304
305 struct netns_fds netns;
306
307 #ifdef RLIMIT_NOFILE
308 struct rlimit fd_limits_default_set;
309 #endif
310
311 struct if_address_st * if_addresses;
312 unsigned int if_addresses_count;
313 } main_server_st;
314
315 void clear_lists(main_server_st *s);
316
317 int handle_worker_commands(main_server_st *s, struct proc_st* cur);
318 int handle_sec_mod_commands(sec_mod_instance_st * sec_mod_instances);
319
320 int user_connected(main_server_st *s, struct proc_st* cur);
321 void user_hostname_update(main_server_st *s, struct proc_st* cur);
322 void user_disconnected(main_server_st *s, struct proc_st* cur);
323
324 int send_udp_fd(main_server_st* s, struct proc_st * proc, int fd);
325
326 int session_open(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc, const uint8_t *cookie, unsigned cookie_size);
327 int session_close(sec_mod_instance_st * sec_mod_instance, struct proc_st *proc);
328
329 #ifdef UNDER_TEST
330 /* for testing */
331 # define mslog(...)
332
333 #else
334
335 void
336 __attribute__ ((format(printf, 4, 5)))
337 _mslog(const main_server_st * s, const struct proc_st* proc,
338 int priority, const char *fmt, ...);
339
340 # ifdef __GNUC__
341 # define mslog(s, proc, prio, fmt, ...) \
342 (prio==LOG_ERR)?_mslog(s, proc, prio, "%s:%d: "fmt, __FILE__, __LINE__, ##__VA_ARGS__): \
343 _mslog(s, proc, prio, fmt, ##__VA_ARGS__)
344 # else
345 # define mslog _mslog
346 # endif
347
348 #endif
349
350
351 void mslog_hex(const main_server_st * s, const struct proc_st* proc,
352 int priority, const char *prefix, uint8_t* bin, unsigned bin_size, unsigned b64);
353
354 int open_tun(main_server_st* s, struct proc_st* proc);
355 void close_tun(main_server_st* s, struct proc_st* proc);
356 void reset_tun(struct proc_st* proc);
357 int set_tun_mtu(main_server_st* s, struct proc_st * proc, unsigned mtu);
358
359 int send_cookie_auth_reply(main_server_st* s, struct proc_st* proc,
360 AUTHREP r);
361
362 int handle_auth_cookie_req(sec_mod_instance_st * sec_mod_instance, struct proc_st* proc,
363 const AuthCookieRequestMsg * req);
364
365 int check_multiple_users(main_server_st *s, struct proc_st* proc);
366 int handle_script_exit(main_server_st *s, struct proc_st* proc, int code);
367
368 void run_sec_mod(sec_mod_instance_st * sec_mod_instance, unsigned int instance_index);
369
370 struct proc_st *new_proc(main_server_st * s, pid_t pid, int cmd_fd,
371 struct sockaddr_storage *remote_addr, socklen_t remote_addr_len,
372 struct sockaddr_storage *our_addr, socklen_t our_addr_len,
373 uint8_t *sid, size_t sid_size);
374
375 /* kill the pid */
376 #define RPROC_KILL 1
377 /* we are on shutdown, don't wait for anything */
378 #define RPROC_QUIT (1<<1)
379
380 void remove_proc(main_server_st* s, struct proc_st *proc, unsigned flags);
381 void proc_to_zombie(main_server_st* s, struct proc_st *proc);
382
disconnect_proc(main_server_st * s,proc_st * proc)383 inline static void disconnect_proc(main_server_st *s, proc_st *proc)
384 {
385 /* make sure that the SID cannot be reused */
386 proc->invalidated = 1;
387
388 /* if it has a PID, send a signal so that we cleanup
389 * and sec-mod gets stats orderly */
390 if (proc->pid != -1 && proc->pid != 0) {
391 kill(proc->pid, SIGTERM);
392 } else {
393 remove_proc(s, proc, RPROC_KILL);
394 }
395 }
396
397 void put_into_cgroup(main_server_st * s, const char* cgroup, pid_t pid);
398
399 inline static
send_msg_to_worker(main_server_st * s,struct proc_st * proc,uint8_t cmd,const void * msg,pack_size_func get_size,pack_func pack)400 int send_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd,
401 const void* msg, pack_size_func get_size, pack_func pack)
402 {
403 mslog(s, proc, LOG_DEBUG, "sending message '%s' to worker", cmd_request_to_str(cmd));
404 return send_msg(proc, proc->fd, cmd, msg, get_size, pack);
405 }
406
407 inline static
send_socket_msg_to_worker(main_server_st * s,struct proc_st * proc,uint8_t cmd,int socketfd,const void * msg,pack_size_func get_size,pack_func pack)408 int send_socket_msg_to_worker(main_server_st* s, struct proc_st* proc, uint8_t cmd,
409 int socketfd, const void* msg, pack_size_func get_size, pack_func pack)
410 {
411 mslog(s, proc, LOG_DEBUG, "sending (socket) message %u to worker", (unsigned)cmd);
412 return send_socket_msg(proc, proc->fd, cmd, socketfd, msg, get_size, pack);
413 }
414
415 int secmod_reload(sec_mod_instance_st * sec_mod_instance);
416
417 const char *secmod_socket_file_name(struct perm_cfg_st *perm_config);
418 void restore_secmod_socket_file_name(const char * save_path);
419 void clear_vhosts(struct list_head *head);
420
421 void request_reload(int signo);
422 void request_stop(int signo);
423
424 const struct auth_mod_st *get_auth_mod(void);
425 const struct auth_mod_st *get_backup_auth_mod(void);
426
427 #endif
428