svn cleanup
[anytun.git] / openvpn / push.c
blob454b6e9820853d84068d2e47afd5f27ecb88257c
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-2005 OpenVPN Solutions LLC <info@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 #ifdef WIN32
26 #include "config-win32.h"
27 #else
28 #include "config.h"
29 #endif
31 #include "syshead.h"
33 #include "push.h"
34 #include "options.h"
35 #include "ssl.h"
36 #include "manage.h"
38 #include "memdbg.h"
40 #if P2MP
43 * Auth username/password
45 * Client received an authentication failed message from server.
46 * Runs on client.
48 void
49 receive_auth_failed (struct context *c, const struct buffer *buffer)
51 msg (M_VERB0, "AUTH: Received AUTH_FAILED control message");
52 if (c->options.pull)
54 switch (auth_retry_get ())
56 case AR_NONE:
57 c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */
58 break;
59 case AR_INTERACT:
60 ssl_purge_auth ();
61 case AR_NOINTERACT:
62 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */
63 break;
64 default:
65 ASSERT (0);
67 c->sig->signal_text = "auth-failure";
68 #ifdef ENABLE_MANAGEMENT
69 if (management)
70 management_auth_failure (management, UP_TYPE_AUTH);
71 #endif
75 #if P2MP_SERVER
77 * Send auth failed message from server to client.
79 bool
80 send_auth_failed (struct context *c)
82 return send_control_channel_string (c, "AUTH_FAILED", D_PUSH);
84 #endif
87 * Push/Pull
90 void
91 incoming_push_message (struct context *c, const struct buffer *buffer)
93 struct gc_arena gc = gc_new ();
94 unsigned int option_types_found = 0;
95 int status;
97 msg (D_PUSH, "PUSH: Received control message: '%s'", BSTR (buffer));
99 status = process_incoming_push_msg (c,
100 buffer,
101 c->options.pull,
102 pull_permission_mask (),
103 &option_types_found);
105 if (status == PUSH_MSG_ERROR)
106 msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", BSTR (buffer));
107 else if (status == PUSH_MSG_REPLY)
109 do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */
110 event_timeout_clear (&c->c2.push_request_interval);
113 gc_free (&gc);
116 bool
117 send_push_request (struct context *c)
119 return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH);
122 #if P2MP_SERVER
123 bool
124 send_push_reply (struct context *c)
126 struct gc_arena gc = gc_new ();
127 struct buffer buf = alloc_buf_gc (MAX_PUSH_LIST_LEN + 256, &gc);
128 bool ret = false;
130 buf_printf (&buf, "PUSH_REPLY");
132 if (c->options.push_list && strlen (c->options.push_list->options))
133 buf_printf (&buf, ",%s", c->options.push_list->options);
135 if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask)
136 buf_printf (&buf, ",ifconfig %s %s",
137 print_in_addr_t (c->c2.push_ifconfig_local, 0, &gc),
138 print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc));
140 if (strlen (BSTR (&buf)) < MAX_PUSH_LIST_LEN)
141 ret = send_control_channel_string (c, BSTR (&buf), D_PUSH);
142 else
143 msg (M_WARN, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);
145 gc_free (&gc);
146 return ret;
149 void
150 push_option (struct options *o, const char *opt, int msglevel)
152 int len;
153 bool first = false;
155 if (!string_class (opt, CC_ANY, CC_COMMA))
157 msg (msglevel, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt);
159 else
161 if (!o->push_list)
163 ALLOC_OBJ_CLEAR_GC (o->push_list, struct push_list, &o->gc);
164 first = true;
167 len = strlen (o->push_list->options);
168 if (len + strlen (opt) + 2 >= MAX_PUSH_LIST_LEN)
170 msg (msglevel, "Maximum length of --push buffer (%d) has been exceeded", MAX_PUSH_LIST_LEN);
172 else
174 if (!first)
175 strcat (o->push_list->options, ",");
176 strcat (o->push_list->options, opt);
181 void
182 push_reset (struct options *o)
184 o->push_list = NULL;
186 #endif
189 process_incoming_push_msg (struct context *c,
190 const struct buffer *buffer,
191 bool honor_received_options,
192 unsigned int permission_mask,
193 unsigned int *option_types_found)
195 int ret = PUSH_MSG_ERROR;
196 struct buffer buf = *buffer;
198 #if P2MP_SERVER
199 if (buf_string_compare_advance (&buf, "PUSH_REQUEST"))
201 if (!tls_authenticated (c->c2.tls_multi) || c->c2.context_auth == CAS_FAILED)
203 send_auth_failed (c);
204 schedule_exit (c, c->options.scheduled_exit_interval);
205 ret = PUSH_MSG_AUTH_FAILURE;
207 else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED)
209 if (send_push_reply (c))
210 ret = PUSH_MSG_REQUEST;
212 else
214 ret = PUSH_MSG_REQUEST_DEFERRED;
217 else
218 #endif
220 if (honor_received_options && buf_string_compare_advance (&buf, "PUSH_REPLY"))
222 const uint8_t ch = buf_read_u8 (&buf);
223 if (ch == ',')
225 pre_pull_restore (&c->options);
226 c->c2.pulled_options_string = string_alloc (BSTR (&buf), &c->c2.gc);
227 if (apply_push_options (&c->options,
228 &buf,
229 permission_mask,
230 option_types_found,
231 c->c2.es))
232 ret = PUSH_MSG_REPLY;
234 else if (ch == '\0')
236 ret = PUSH_MSG_REPLY;
238 /* show_settings (&c->options); */
240 return ret;
243 #if P2MP_SERVER
245 * Remove iroutes from the push_list.
247 void
248 remove_iroutes_from_push_route_list (struct options *o)
250 if (o && o->push_list && o->iroutes)
252 struct gc_arena gc = gc_new ();
253 struct push_list *pl;
254 struct buffer in, out;
255 char *line;
256 bool first = true;
258 /* prepare input and output buffers */
259 ALLOC_OBJ_CLEAR_GC (pl, struct push_list, &gc);
260 ALLOC_ARRAY_CLEAR_GC (line, char, MAX_PUSH_LIST_LEN, &gc);
262 buf_set_read (&in, (const uint8_t*) o->push_list->options, strlen (o->push_list->options));
263 buf_set_write (&out, (uint8_t*) pl->options, sizeof (pl->options));
265 /* cycle through the push list */
266 while (buf_parse (&in, ',', line, MAX_PUSH_LIST_LEN))
268 char *p[MAX_PARMS];
269 bool copy = true;
271 /* parse the push item */
272 CLEAR (p);
273 if (parse_line (line, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
275 /* is the push item a route directive? */
276 if (p[0] && p[1] && p[2] && !strcmp (p[0], "route"))
278 /* get route parameters */
279 bool status1, status2;
280 const in_addr_t network = getaddr (GETADDR_HOST_ORDER, p[1], 0, &status1, NULL);
281 const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, p[2], 0, &status2, NULL);
283 /* did route parameters parse correctly? */
284 if (status1 && status2)
286 const struct iroute *ir;
288 /* does route match an iroute? */
289 for (ir = o->iroutes; ir != NULL; ir = ir->next)
291 if (network == ir->network && netmask == netbits_to_netmask (ir->netbits))
293 copy = false;
294 break;
301 /* should we copy the push item? */
302 if (copy)
304 if (!first)
305 buf_printf (&out, ",");
306 buf_printf (&out, "%s", line);
307 first = false;
309 else
310 msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", line);
313 #if 0
314 msg (M_INFO, "BEFORE: '%s'", o->push_list->options);
315 msg (M_INFO, "AFTER: '%s'", pl->options);
316 #endif
318 /* copy new push list back to options */
319 *o->push_list = *pl;
321 gc_free (&gc);
324 #endif
326 #endif