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-2009 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");
48 switch (auth_retry_get ())
51 c
->sig
->signal_received
= SIGTERM
; /* SOFT-SIGTERM -- Auth failure error */
56 c
->sig
->signal_received
= SIGUSR1
; /* SOFT-SIGUSR1 -- Auth failure error */
61 c
->sig
->signal_text
= "auth-failure";
62 #ifdef ENABLE_MANAGEMENT
65 const char *reason
= UP_TYPE_AUTH
;
66 struct buffer buf
= *buffer
;
67 if (buf_string_compare_advance (&buf
, "AUTH_FAILED,") && BLEN (&buf
))
69 management_auth_failure (management
, reason
);
76 * Act on received restart message from server
79 server_pushed_restart (struct context
*c
, const struct buffer
*buffer
)
83 msg (D_STREAM_ERRORS
, "Connection reset command was pushed by server");
84 c
->sig
->signal_received
= SIGUSR1
; /* SOFT-SIGUSR1 -- server-pushed connection reset */
85 c
->sig
->signal_text
= "server-pushed-connection-reset";
92 * Send auth failed message from server to client.
95 send_auth_failed (struct context
*c
, const char *client_reason
)
97 struct gc_arena gc
= gc_new ();
98 static const char auth_failed
[] = "AUTH_FAILED";
101 schedule_exit (c
, c
->options
.scheduled_exit_interval
, SIGTERM
);
103 len
= (client_reason
? strlen(client_reason
)+1 : 0) + sizeof(auth_failed
);
104 if (len
> TLS_CHANNEL_BUF_SIZE
)
105 len
= TLS_CHANNEL_BUF_SIZE
;
108 struct buffer buf
= alloc_buf_gc (len
, &gc
);
109 buf_printf (&buf
, auth_failed
);
111 buf_printf (&buf
, ",%s", client_reason
);
112 send_control_channel_string (c
, BSTR (&buf
), D_PUSH
);
119 * Send restart message from server to client.
122 send_restart (struct context
*c
)
124 schedule_exit (c
, c
->options
.scheduled_exit_interval
, SIGTERM
);
125 send_control_channel_string (c
, "RESTART", D_PUSH
);
135 incoming_push_message (struct context
*c
, const struct buffer
*buffer
)
137 struct gc_arena gc
= gc_new ();
138 unsigned int option_types_found
= 0;
141 msg (D_PUSH
, "PUSH: Received control message: '%s'", BSTR (buffer
));
143 status
= process_incoming_push_msg (c
,
146 pull_permission_mask (c
),
147 &option_types_found
);
149 if (status
== PUSH_MSG_ERROR
)
150 msg (D_PUSH_ERRORS
, "WARNING: Received bad push/pull message: %s", BSTR (buffer
));
151 else if (status
== PUSH_MSG_REPLY
|| status
== PUSH_MSG_CONTINUATION
)
153 if (status
== PUSH_MSG_REPLY
)
154 do_up (c
, true, option_types_found
); /* delay bringing tun/tap up until --push parms received from remote */
155 event_timeout_clear (&c
->c2
.push_request_interval
);
162 send_push_request (struct context
*c
)
164 return send_control_channel_string (c
, "PUSH_REQUEST", D_PUSH
);
170 send_push_reply (struct context
*c
)
172 struct gc_arena gc
= gc_new ();
173 struct buffer buf
= alloc_buf_gc (TLS_CHANNEL_BUF_SIZE
, &gc
);
174 struct push_entry
*e
= c
->options
.push_list
.head
;
175 bool multi_push
= false;
176 static char cmd
[] = "PUSH_REPLY";
177 const int extra
= 64; /* extra space for possible trailing ifconfig and push-continuation */
178 const int safe_cap
= BCAP (&buf
) - extra
;
180 buf_printf (&buf
, cmd
);
186 const int l
= strlen (e
->option
);
187 if (BLEN (&buf
) + l
>= safe_cap
)
189 buf_printf (&buf
, ",push-continuation 2");
191 const bool status
= send_control_channel_string (c
, BSTR (&buf
), D_PUSH
);
195 buf_reset_len (&buf
);
196 buf_printf (&buf
, cmd
);
199 if (BLEN (&buf
) + l
>= safe_cap
)
201 msg (M_WARN
, "--push option is too long");
204 buf_printf (&buf
, ",%s", e
->option
);
209 if (c
->c2
.push_ifconfig_defined
&& c
->c2
.push_ifconfig_local
&& c
->c2
.push_ifconfig_remote_netmask
)
210 buf_printf (&buf
, ",ifconfig %s %s",
211 print_in_addr_t (c
->c2
.push_ifconfig_local
, 0, &gc
),
212 print_in_addr_t (c
->c2
.push_ifconfig_remote_netmask
, 0, &gc
));
214 buf_printf (&buf
, ",push-continuation 1");
216 if (BLEN (&buf
) > sizeof(cmd
)-1)
218 const bool status
= send_control_channel_string (c
, BSTR (&buf
), D_PUSH
);
232 push_option_ex (struct options
*o
, const char *opt
, bool enable
, int msglevel
)
234 if (!string_class (opt
, CC_ANY
, CC_COMMA
))
236 msg (msglevel
, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt
);
240 struct push_entry
*e
;
241 ALLOC_OBJ_CLEAR_GC (e
, struct push_entry
, &o
->gc
);
244 if (o
->push_list
.head
)
246 ASSERT(o
->push_list
.tail
);
247 o
->push_list
.tail
->next
= e
;
248 o
->push_list
.tail
= e
;
252 ASSERT(!o
->push_list
.tail
);
253 o
->push_list
.head
= e
;
254 o
->push_list
.tail
= e
;
260 push_option (struct options
*o
, const char *opt
, int msglevel
)
262 push_option_ex (o
, opt
, true, msglevel
);
266 clone_push_list (struct options
*o
)
268 if (o
->push_list
.head
)
270 const struct push_entry
*e
= o
->push_list
.head
;
274 push_option_ex (o
, string_alloc (e
->option
, &o
->gc
), true, M_FATAL
);
281 push_options (struct options
*o
, char **p
, int msglevel
, struct gc_arena
*gc
)
283 const char **argv
= make_extended_arg_array (p
, gc
);
284 char *opt
= print_argv (argv
, gc
, 0);
285 push_option (o
, opt
, msglevel
);
289 push_reset (struct options
*o
)
291 CLEAR (o
->push_list
);
296 process_incoming_push_msg (struct context
*c
,
297 const struct buffer
*buffer
,
298 bool honor_received_options
,
299 unsigned int permission_mask
,
300 unsigned int *option_types_found
)
302 int ret
= PUSH_MSG_ERROR
;
303 struct buffer buf
= *buffer
;
306 if (buf_string_compare_advance (&buf
, "PUSH_REQUEST"))
308 if (tls_authentication_status (c
->c2
.tls_multi
, 0) == TLS_AUTHENTICATION_FAILED
|| c
->c2
.context_auth
== CAS_FAILED
)
310 const char *client_reason
= tls_client_reason (c
->c2
.tls_multi
);
311 send_auth_failed (c
, client_reason
);
312 ret
= PUSH_MSG_AUTH_FAILURE
;
314 else if (!c
->c2
.push_reply_deferred
&& c
->c2
.context_auth
== CAS_SUCCEEDED
)
316 if (send_push_reply (c
))
317 ret
= PUSH_MSG_REQUEST
;
321 ret
= PUSH_MSG_REQUEST_DEFERRED
;
327 if (honor_received_options
&& buf_string_compare_advance (&buf
, "PUSH_REPLY"))
329 const uint8_t ch
= buf_read_u8 (&buf
);
332 struct buffer buf_orig
= buf
;
333 if (!c
->c2
.did_pre_pull_restore
)
335 pre_pull_restore (&c
->options
);
336 md5_state_init (&c
->c2
.pulled_options_state
);
337 c
->c2
.did_pre_pull_restore
= true;
339 if (apply_push_options (&c
->options
,
344 switch (c
->options
.push_continuation
)
348 md5_state_update (&c
->c2
.pulled_options_state
, BPTR(&buf_orig
), BLEN(&buf_orig
));
349 md5_state_final (&c
->c2
.pulled_options_state
, &c
->c2
.pulled_options_digest
);
350 ret
= PUSH_MSG_REPLY
;
353 md5_state_update (&c
->c2
.pulled_options_state
, BPTR(&buf_orig
), BLEN(&buf_orig
));
354 ret
= PUSH_MSG_CONTINUATION
;
360 ret
= PUSH_MSG_REPLY
;
362 /* show_settings (&c->options); */
370 * Remove iroutes from the push_list.
373 remove_iroutes_from_push_route_list (struct options
*o
)
375 if (o
&& o
->push_list
.head
&& o
->iroutes
)
377 struct gc_arena gc
= gc_new ();
378 struct push_entry
*e
= o
->push_list
.head
;
380 /* cycle through the push list */
386 /* parse the push item */
388 if (parse_line (e
->option
, p
, SIZE (p
), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG
, &gc
))
390 /* is the push item a route directive? */
391 if (p
[0] && !strcmp (p
[0], "route") && !p
[3])
393 /* get route parameters */
394 bool status1
, status2
;
395 const in_addr_t network
= getaddr (GETADDR_HOST_ORDER
, p
[1], 0, &status1
, NULL
);
396 const in_addr_t netmask
= getaddr (GETADDR_HOST_ORDER
, p
[2] ? p
[2] : "255.255.255.255", 0, &status2
, NULL
);
398 /* did route parameters parse correctly? */
399 if (status1
&& status2
)
401 const struct iroute
*ir
;
403 /* does route match an iroute? */
404 for (ir
= o
->iroutes
; ir
!= NULL
; ir
= ir
->next
)
406 if (network
== ir
->network
&& netmask
== netbits_to_netmask (ir
->netbits
>= 0 ? ir
->netbits
: 32))
416 /* should we copy the push item? */
419 msg (D_PUSH
, "REMOVE PUSH ROUTE: '%s'", e
->option
);