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
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
37 * Auth username/password
39 * Client received an authentication failed message from server.
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
);
49 switch (auth_retry_get ())
52 c
->sig
->signal_received
= SIGTERM
; /* SOFT-SIGTERM -- Auth failure error */
57 c
->sig
->signal_received
= SIGUSR1
; /* SOFT-SIGUSR1 -- Auth failure error */
62 c
->sig
->signal_text
= "auth-failure";
63 #ifdef ENABLE_MANAGEMENT
66 const char *reason
= NULL
;
67 struct buffer buf
= *buffer
;
68 if (buf_string_compare_advance (&buf
, "AUTH_FAILED,") && BLEN (&buf
))
70 management_auth_failure (management
, UP_TYPE_AUTH
, reason
);
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
));
87 * Act on received restart message from server
90 server_pushed_restart (struct context
*c
, const struct buffer
*buffer
)
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";
103 * Send auth failed message from server to client.
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";
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
);
122 buf_printf (&buf
, ",%s", client_reason
);
123 send_control_channel_string (c
, BSTR (&buf
), D_PUSH
);
130 * Send restart message from server to client.
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
);
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;
152 msg (D_PUSH
, "PUSH: Received control message: '%s'", BSTR (buffer
));
154 status
= process_incoming_push_msg (c
,
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
);
173 send_push_request (struct context
*c
)
175 return send_control_channel_string (c
, "PUSH_REQUEST", D_PUSH
);
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
);
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
);
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");
217 buf_printf (&buf
, ",%s", e
->option
);
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
));
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
);
237 /* If nothing have been pushed, send an empty push,
238 * as the client is expecting a response
244 buf_reset_len (&buf
);
245 buf_printf (&buf
, "%s", cmd
);
246 status
= send_control_channel_string (c
, BSTR(&buf
), D_PUSH
);
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
);
268 struct push_entry
*e
;
269 ALLOC_OBJ_CLEAR_GC (e
, struct push_entry
, &o
->gc
);
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
;
280 ASSERT(!o
->push_list
.tail
);
281 o
->push_list
.head
= e
;
282 o
->push_list
.tail
= e
;
288 push_option (struct options
*o
, const char *opt
, int msglevel
)
290 push_option_ex (o
, opt
, true, msglevel
);
294 clone_push_list (struct options
*o
)
296 if (o
->push_list
.head
)
298 const struct push_entry
*e
= o
->push_list
.head
;
302 push_option_ex (o
, string_alloc (e
->option
, &o
->gc
), true, M_FATAL
);
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
);
317 push_reset (struct options
*o
)
319 CLEAR (o
->push_list
);
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
;
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
;
349 ret
= PUSH_MSG_REQUEST_DEFERRED
;
355 if (honor_received_options
&& buf_string_compare_advance (&buf
, "PUSH_REPLY"))
357 const uint8_t ch
= buf_read_u8 (&buf
);
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
,
372 switch (c
->options
.push_continuation
)
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
;
381 md5_state_update (&c
->c2
.pulled_options_state
, BPTR(&buf_orig
), BLEN(&buf_orig
));
382 ret
= PUSH_MSG_CONTINUATION
;
388 ret
= PUSH_MSG_REPLY
;
390 /* show_settings (&c->options); */
398 * Remove iroutes from the push_list.
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 */
414 /* parse the push item */
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))
444 /* should we copy the push item? */
447 msg (D_PUSH
, "REMOVE PUSH ROUTE: '%s'", e
->option
);