Column sorting fixes, thanks to Tony550
[tomato.git] / release / src / router / openvpn / push.c
blob08c7f995832306a7ee180e77a5d8d55b28eb41a9
1 /*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "syshead.h"
27 #include "push.h"
28 #include "options.h"
29 #include "ssl.h"
30 #include "manage.h"
32 #include "memdbg.h"
34 #if P2MP
37 * Auth username/password
39 * Client received an authentication failed message from server.
40 * Runs on client.
42 void
43 receive_auth_failed (struct context *c, const struct buffer *buffer)
45 msg (M_VERB0, "AUTH: Received AUTH_FAILED control message");
46 connection_list_set_no_advance(&c->options);
47 if (c->options.pull)
49 switch (auth_retry_get ())
51 case AR_NONE:
52 c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */
53 break;
54 case AR_INTERACT:
55 ssl_purge_auth ();
56 case AR_NOINTERACT:
57 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */
58 break;
59 default:
60 ASSERT (0);
62 c->sig->signal_text = "auth-failure";
63 #ifdef ENABLE_MANAGEMENT
64 if (management)
66 const char *reason = NULL;
67 struct buffer buf = *buffer;
68 if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf))
69 reason = BSTR (&buf);
70 management_auth_failure (management, UP_TYPE_AUTH, reason);
71 } else
72 #endif
74 #ifdef ENABLE_CLIENT_CR
75 struct buffer buf = *buffer;
76 if (buf_string_match_head_str (&buf, "AUTH_FAILED,CRV1:") && BLEN (&buf))
78 buf_advance (&buf, 12); /* Length of "AUTH_FAILED," substring */
79 ssl_put_auth_challenge (BSTR (&buf));
81 #endif
87 * Act on received restart message from server
89 void
90 server_pushed_restart (struct context *c, const struct buffer *buffer)
92 if (c->options.pull)
94 msg (D_STREAM_ERRORS, "Connection reset command was pushed by server");
95 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */
96 c->sig->signal_text = "server-pushed-connection-reset";
100 #if P2MP_SERVER
103 * Send auth failed message from server to client.
105 void
106 send_auth_failed (struct context *c, const char *client_reason)
108 struct gc_arena gc = gc_new ();
109 static const char auth_failed[] = "AUTH_FAILED";
110 size_t len;
112 schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM);
114 len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed);
115 if (len > PUSH_BUNDLE_SIZE)
116 len = PUSH_BUNDLE_SIZE;
119 struct buffer buf = alloc_buf_gc (len, &gc);
120 buf_printf (&buf, auth_failed);
121 if (client_reason)
122 buf_printf (&buf, ",%s", client_reason);
123 send_control_channel_string (c, BSTR (&buf), D_PUSH);
126 gc_free (&gc);
130 * Send restart message from server to client.
132 void
133 send_restart (struct context *c)
135 schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM);
136 send_control_channel_string (c, "RESTART", D_PUSH);
139 #endif
142 * Push/Pull
145 void
146 incoming_push_message (struct context *c, const struct buffer *buffer)
148 struct gc_arena gc = gc_new ();
149 unsigned int option_types_found = 0;
150 int status;
152 msg (D_PUSH, "PUSH: Received control message: '%s'", BSTR (buffer));
154 status = process_incoming_push_msg (c,
155 buffer,
156 c->options.pull,
157 pull_permission_mask (c),
158 &option_types_found);
160 if (status == PUSH_MSG_ERROR)
161 msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", BSTR (buffer));
162 else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION)
164 if (status == PUSH_MSG_REPLY)
165 do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */
166 event_timeout_clear (&c->c2.push_request_interval);
169 gc_free (&gc);
172 bool
173 send_push_request (struct context *c)
175 return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH);
178 #if P2MP_SERVER
180 bool
181 send_push_reply (struct context *c)
183 struct gc_arena gc = gc_new ();
184 struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc);
185 struct push_entry *e = c->options.push_list.head;
186 bool multi_push = false;
187 static char cmd[] = "PUSH_REPLY";
188 const int extra = 64; /* extra space for possible trailing ifconfig and push-continuation */
189 const int safe_cap = BCAP (&buf) - extra;
190 bool push_sent = false;
192 buf_printf (&buf, "%s", cmd);
194 while (e)
196 if (e->enable)
198 const int l = strlen (e->option);
199 if (BLEN (&buf) + l >= safe_cap)
201 buf_printf (&buf, ",push-continuation 2");
203 const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
204 if (!status)
205 goto fail;
206 push_sent = true;
207 multi_push = true;
208 buf_reset_len (&buf);
209 buf_printf (&buf, "%s", cmd);
212 if (BLEN (&buf) + l >= safe_cap)
214 msg (M_WARN, "--push option is too long");
215 goto fail;
217 buf_printf (&buf, ",%s", e->option);
219 e = e->next;
222 if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
223 buf_printf (&buf, ",ifconfig %s %s",
224 print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc),
225 print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
226 if (multi_push)
227 buf_printf (&buf, ",push-continuation 1");
229 if (BLEN (&buf) > sizeof(cmd)-1)
231 const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH);
232 if (!status)
233 goto fail;
234 push_sent = true;
237 /* If nothing have been pushed, send an empty push,
238 * as the client is expecting a response
240 if (!push_sent)
242 bool status = false;
244 buf_reset_len (&buf);
245 buf_printf (&buf, "%s", cmd);
246 status = send_control_channel_string (c, BSTR(&buf), D_PUSH);
247 if (!status)
248 goto fail;
251 gc_free (&gc);
252 return true;
254 fail:
255 gc_free (&gc);
256 return false;
259 static void
260 push_option_ex (struct options *o, const char *opt, bool enable, int msglevel)
262 if (!string_class (opt, CC_ANY, CC_COMMA))
264 msg (msglevel, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt);
266 else
268 struct push_entry *e;
269 ALLOC_OBJ_CLEAR_GC (e, struct push_entry, &o->gc);
270 e->enable = true;
271 e->option = opt;
272 if (o->push_list.head)
274 ASSERT(o->push_list.tail);
275 o->push_list.tail->next = e;
276 o->push_list.tail = e;
278 else
280 ASSERT(!o->push_list.tail);
281 o->push_list.head = e;
282 o->push_list.tail = e;
287 void
288 push_option (struct options *o, const char *opt, int msglevel)
290 push_option_ex (o, opt, true, msglevel);
293 void
294 clone_push_list (struct options *o)
296 if (o->push_list.head)
298 const struct push_entry *e = o->push_list.head;
299 push_reset (o);
300 while (e)
302 push_option_ex (o, string_alloc (e->option, &o->gc), true, M_FATAL);
303 e = e->next;
308 void
309 push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc)
311 const char **argv = make_extended_arg_array (p, gc);
312 char *opt = print_argv (argv, gc, 0);
313 push_option (o, opt, msglevel);
316 void
317 push_reset (struct options *o)
319 CLEAR (o->push_list);
321 #endif
324 process_incoming_push_msg (struct context *c,
325 const struct buffer *buffer,
326 bool honor_received_options,
327 unsigned int permission_mask,
328 unsigned int *option_types_found)
330 int ret = PUSH_MSG_ERROR;
331 struct buffer buf = *buffer;
333 #if P2MP_SERVER
334 if (buf_string_compare_advance (&buf, "PUSH_REQUEST"))
336 if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED)
338 const char *client_reason = tls_client_reason (c->c2.tls_multi);
339 send_auth_failed (c, client_reason);
340 ret = PUSH_MSG_AUTH_FAILURE;
342 else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
344 if (send_push_reply (c))
345 ret = PUSH_MSG_REQUEST;
347 else
349 ret = PUSH_MSG_REQUEST_DEFERRED;
352 else
353 #endif
355 if (honor_received_options && buf_string_compare_advance (&buf, "PUSH_REPLY"))
357 const uint8_t ch = buf_read_u8 (&buf);
358 if (ch == ',')
360 struct buffer buf_orig = buf;
361 if (!c->c2.did_pre_pull_restore)
363 pre_pull_restore (&c->options);
364 md5_state_init (&c->c2.pulled_options_state);
365 c->c2.did_pre_pull_restore = true;
367 if (apply_push_options (&c->options,
368 &buf,
369 permission_mask,
370 option_types_found,
371 c->c2.es))
372 switch (c->options.push_continuation)
374 case 0:
375 case 1:
376 md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
377 md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest);
378 ret = PUSH_MSG_REPLY;
379 break;
380 case 2:
381 md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig));
382 ret = PUSH_MSG_CONTINUATION;
383 break;
386 else if (ch == '\0')
388 ret = PUSH_MSG_REPLY;
390 /* show_settings (&c->options); */
392 return ret;
395 #if P2MP_SERVER
398 * Remove iroutes from the push_list.
400 void
401 remove_iroutes_from_push_route_list (struct options *o)
403 if (o && o->push_list.head && o->iroutes)
405 struct gc_arena gc = gc_new ();
406 struct push_entry *e = o->push_list.head;
408 /* cycle through the push list */
409 while (e)
411 char *p[MAX_PARMS];
412 bool enable = true;
414 /* parse the push item */
415 CLEAR (p);
416 if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
418 /* is the push item a route directive? */
419 if (p[0] && !strcmp (p[0], "route") && !p[3])
421 /* get route parameters */
422 bool status1, status2;
423 const in_addr_t network = getaddr (GETADDR_HOST_ORDER, p[1], 0, &status1, NULL);
424 const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, p[2] ? p[2] : "255.255.255.255", 0, &status2, NULL);
426 /* did route parameters parse correctly? */
427 if (status1 && status2)
429 const struct iroute *ir;
431 /* does route match an iroute? */
432 for (ir = o->iroutes; ir != NULL; ir = ir->next)
434 if (network == ir->network && netmask == netbits_to_netmask (ir->netbits >= 0 ? ir->netbits : 32))
436 enable = false;
437 break;
444 /* should we copy the push item? */
445 e->enable = enable;
446 if (!enable)
447 msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option);
449 e = e->next;
452 gc_free (&gc);
456 #endif
458 #endif