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. 7 * 8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> 9 * 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. 13 * 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. 18 * 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 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#elif defined(_MSC_VER) 28#include "config-msvc.h" 29#endif 30 31#include "syshead.h" 32 33#include "push.h" 34#include "options.h" 35#include "ssl.h" 36#include "manage.h" 37 38#include "memdbg.h" 39 40#if P2MP 41 42/* 43 * Auth username/password 44 * 45 * Client received an authentication failed message from server. 46 * Runs on client. 47 */ 48void 49receive_auth_failed (struct context *c, const struct buffer *buffer) 50{ 51 msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer)); 52 connection_list_set_no_advance(&c->options); 53 if (c->options.pull) 54 { 55 switch (auth_retry_get ()) 56 { 57 case AR_NONE: 58 c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */ 59 break; 60 case AR_INTERACT: 61 ssl_purge_auth (false); 62 case AR_NOINTERACT: 63 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */ 64 break; 65 default: 66 ASSERT (0); 67 } 68 c->sig->signal_text = "auth-failure"; 69#ifdef ENABLE_MANAGEMENT 70 if (management) 71 { 72 const char *reason = NULL; 73 struct buffer buf = *buffer; 74 if (buf_string_compare_advance (&buf, "AUTH_FAILED,") && BLEN (&buf)) 75 reason = BSTR (&buf); 76 management_auth_failure (management, UP_TYPE_AUTH, reason); 77 } else 78#endif 79 { 80#ifdef ENABLE_CLIENT_CR 81 struct buffer buf = *buffer; 82 if (buf_string_match_head_str (&buf, "AUTH_FAILED,CRV1:") && BLEN (&buf)) 83 { 84 buf_advance (&buf, 12); /* Length of "AUTH_FAILED," substring */ 85 ssl_put_auth_challenge (BSTR (&buf)); 86 } 87#endif 88 } 89 } 90} 91 92/* 93 * Act on received restart message from server 94 */ 95void 96server_pushed_signal (struct context *c, const struct buffer *buffer, const bool restart, const int adv) 97{ 98 if (c->options.pull) 99 { 100 struct buffer buf = *buffer; 101 const char *m = ""; 102 if (buf_advance (&buf, adv) && buf_read_u8 (&buf) == ',' && BLEN (&buf)) 103 m = BSTR (&buf); 104 105 /* preserve cached passwords? */ 106 { 107 bool purge = true; 108 109 if (m[0] == '[') 110 { 111 int i; 112 for (i = 1; m[i] != '\0' && m[i] != ']'; ++i) 113 { 114 if (m[i] == 'P') 115 purge = false; 116 } 117 } 118 if (purge) 119 ssl_purge_auth (true); 120 } 121 122 if (restart) 123 { 124 msg (D_STREAM_ERRORS, "Connection reset command was pushed by server ('%s')", m); 125 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ 126 c->sig->signal_text = "server-pushed-connection-reset"; 127 } 128 else 129 { 130 msg (D_STREAM_ERRORS, "Halt command was pushed by server ('%s')", m); 131 c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- server-pushed halt */ 132 c->sig->signal_text = "server-pushed-halt"; 133 } 134#ifdef ENABLE_MANAGEMENT 135 if (management) 136 management_notify (management, "info", c->sig->signal_text, m); 137#endif 138 } 139} 140 141#if P2MP_SERVER 142 143/* 144 * Send auth failed message from server to client. 145 */ 146void 147send_auth_failed (struct context *c, const char *client_reason) 148{ 149 struct gc_arena gc = gc_new (); 150 static const char auth_failed[] = "AUTH_FAILED"; 151 size_t len; 152 153 schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); 154 155 len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed); 156 if (len > PUSH_BUNDLE_SIZE) 157 len = PUSH_BUNDLE_SIZE; 158 159 { 160 struct buffer buf = alloc_buf_gc (len, &gc); 161 buf_printf (&buf, auth_failed); 162 if (client_reason) 163 buf_printf (&buf, ",%s", client_reason); 164 send_control_channel_string (c, BSTR (&buf), D_PUSH); 165 } 166 167 gc_free (&gc); 168} 169 170/* 171 * Send restart message from server to client. 172 */ 173void 174send_restart (struct context *c, const char *kill_msg) 175{ 176 schedule_exit (c, c->options.scheduled_exit_interval, SIGTERM); 177 send_control_channel_string (c, kill_msg ? kill_msg : "RESTART", D_PUSH); 178} 179 180#endif 181 182/* 183 * Push/Pull 184 */ 185 186void 187incoming_push_message (struct context *c, const struct buffer *buffer) 188{ 189 struct gc_arena gc = gc_new (); 190 unsigned int option_types_found = 0; 191 int status; 192 193 msg (D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc)); 194 195 status = process_incoming_push_msg (c, 196 buffer, 197 c->options.pull, 198 pull_permission_mask (c), 199 &option_types_found); 200 201 if (status == PUSH_MSG_ERROR) 202 msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc)); 203 else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION) 204 { 205 if (status == PUSH_MSG_REPLY) 206 do_up (c, true, option_types_found); /* delay bringing tun/tap up until --push parms received from remote */ 207 event_timeout_clear (&c->c2.push_request_interval); 208 } 209 210 gc_free (&gc); 211} 212 213bool 214send_push_request (struct context *c) 215{ 216 const int max_push_requests = c->options.handshake_window / PUSH_REQUEST_INTERVAL; 217 if (++c->c2.n_sent_push_requests <= max_push_requests) 218 { 219 return send_control_channel_string (c, "PUSH_REQUEST", D_PUSH); 220 } 221 else 222 { 223 msg (D_STREAM_ERRORS, "No reply from server after sending %d push requests", max_push_requests); 224 c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ 225 c->sig->signal_text = "no-push-reply"; 226 return false; 227 } 228} 229 230#if P2MP_SERVER 231 232bool 233send_push_reply (struct context *c) 234{ 235 struct gc_arena gc = gc_new (); 236 struct buffer buf = alloc_buf_gc (PUSH_BUNDLE_SIZE, &gc); 237 struct push_entry *e = c->options.push_list.head; 238 bool multi_push = false; 239 static char cmd[] = "PUSH_REPLY"; 240 const int extra = 84; /* extra space for possible trailing ifconfig and push-continuation */ 241 const int safe_cap = BCAP (&buf) - extra; 242 bool push_sent = false; 243 char foxconn_log[512]; 244 245 msg( M_INFO, "send_push_reply(): safe_cap=%d", safe_cap ); 246 sprintf(foxconn_log, "[OpenVPN, connection successfully]IP address:%s",inet_ntoa (c->c2.to_link_addr->dest.addr.in4.sin_addr)); 247 ambitWriteLog(foxconn_log, sizeof(foxconn_log));//allenwen add openvpn log 248 249 250 buf_printf (&buf, "%s", cmd); 251 252 if ( c->c2.push_ifconfig_ipv6_defined ) 253 { 254 /* IPv6 is put into buffer first, could be lengthy */ 255 buf_printf( &buf, ",ifconfig-ipv6 %s/%d %s", 256 print_in6_addr( c->c2.push_ifconfig_ipv6_local, 0, &gc), 257 c->c2.push_ifconfig_ipv6_netbits, 258 print_in6_addr( c->c2.push_ifconfig_ipv6_remote, 0, &gc) ); 259 if (BLEN (&buf) >= safe_cap) 260 { 261 msg (M_WARN, "--push ifconfig-ipv6 option is too long"); 262 goto fail; 263 } 264 } 265 266 while (e) 267 { 268 if (e->enable) 269 { 270 const int l = strlen (e->option); 271 if (BLEN (&buf) + l >= safe_cap) 272 { 273 buf_printf (&buf, ",push-continuation 2"); 274 { 275 const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH); 276 if (!status) 277 goto fail; 278 push_sent = true; 279 multi_push = true; 280 buf_reset_len (&buf); 281 buf_printf (&buf, "%s", cmd); 282 } 283 } 284 if (BLEN (&buf) + l >= safe_cap) 285 { 286 msg (M_WARN, "--push option is too long"); 287 goto fail; 288 } 289 buf_printf (&buf, ",%s", e->option); 290 } 291 e = e->next; 292 } 293 294 if (c->c2.push_ifconfig_defined && c->c2.push_ifconfig_local && c->c2.push_ifconfig_remote_netmask) 295 { 296 in_addr_t ifconfig_local = c->c2.push_ifconfig_local; 297#ifdef ENABLE_CLIENT_NAT 298 if (c->c2.push_ifconfig_local_alias) 299 ifconfig_local = c->c2.push_ifconfig_local_alias; 300#endif 301 buf_printf (&buf, ",ifconfig %s %s", 302 print_in_addr_t (ifconfig_local, 0, &gc), 303 print_in_addr_t (c->c2.push_ifconfig_remote_netmask, 0, &gc)); 304 } 305 if (multi_push) 306 buf_printf (&buf, ",push-continuation 1"); 307 308 if (BLEN (&buf) > sizeof(cmd)-1) 309 { 310 const bool status = send_control_channel_string (c, BSTR (&buf), D_PUSH); 311 if (!status) 312 goto fail; 313 push_sent = true; 314 } 315 316 /* If nothing have been pushed, send an empty push, 317 * as the client is expecting a response 318 */ 319 if (!push_sent) 320 { 321 bool status = false; 322 323 buf_reset_len (&buf); 324 buf_printf (&buf, "%s", cmd); 325 status = send_control_channel_string (c, BSTR(&buf), D_PUSH); 326 if (!status) 327 goto fail; 328 } 329 330 gc_free (&gc); 331 return true; 332 333 fail: 334 gc_free (&gc); 335 return false; 336} 337 338static void 339push_option_ex (struct options *o, const char *opt, bool enable, int msglevel) 340{ 341 if (!string_class (opt, CC_ANY, CC_COMMA)) 342 { 343 msg (msglevel, "PUSH OPTION FAILED (illegal comma (',') in string): '%s'", opt); 344 } 345 else 346 { 347 struct push_entry *e; 348 ALLOC_OBJ_CLEAR_GC (e, struct push_entry, &o->gc); 349 e->enable = true; 350 e->option = opt; 351 if (o->push_list.head) 352 { 353 ASSERT(o->push_list.tail); 354 o->push_list.tail->next = e; 355 o->push_list.tail = e; 356 } 357 else 358 { 359 ASSERT(!o->push_list.tail); 360 o->push_list.head = e; 361 o->push_list.tail = e; 362 } 363 } 364} 365 366void 367push_option (struct options *o, const char *opt, int msglevel) 368{ 369 push_option_ex (o, opt, true, msglevel); 370} 371 372void 373clone_push_list (struct options *o) 374{ 375 if (o->push_list.head) 376 { 377 const struct push_entry *e = o->push_list.head; 378 push_reset (o); 379 while (e) 380 { 381 push_option_ex (o, string_alloc (e->option, &o->gc), true, M_FATAL); 382 e = e->next; 383 } 384 } 385} 386 387void 388push_options (struct options *o, char **p, int msglevel, struct gc_arena *gc) 389{ 390 const char **argv = make_extended_arg_array (p, gc); 391 char *opt = print_argv (argv, gc, 0); 392 push_option (o, opt, msglevel); 393} 394 395void 396push_reset (struct options *o) 397{ 398 CLEAR (o->push_list); 399} 400#endif 401 402int 403process_incoming_push_msg (struct context *c, 404 const struct buffer *buffer, 405 bool honor_received_options, 406 unsigned int permission_mask, 407 unsigned int *option_types_found) 408{ 409 int ret = PUSH_MSG_ERROR; 410 struct buffer buf = *buffer; 411 412#if P2MP_SERVER 413 if (buf_string_compare_advance (&buf, "PUSH_REQUEST")) 414 { 415 if (tls_authentication_status (c->c2.tls_multi, 0) == TLS_AUTHENTICATION_FAILED || c->c2.context_auth == CAS_FAILED) 416 { 417 const char *client_reason = tls_client_reason (c->c2.tls_multi); 418 send_auth_failed (c, client_reason); 419 ret = PUSH_MSG_AUTH_FAILURE; 420 } 421 else if (!c->c2.push_reply_deferred && c->c2.context_auth == CAS_SUCCEEDED) 422 { 423 time_t now; 424 425 openvpn_time(&now); 426 if (c->c2.sent_push_reply_expiry > now) 427 { 428 ret = PUSH_MSG_ALREADY_REPLIED; 429 } 430 else 431 { 432 if (send_push_reply (c)) 433 { 434 ret = PUSH_MSG_REQUEST; 435 c->c2.sent_push_reply_expiry = now + 30; 436 } 437 } 438 } 439 else 440 { 441 ret = PUSH_MSG_REQUEST_DEFERRED; 442 } 443 } 444 else 445#endif 446 447 if (honor_received_options && buf_string_compare_advance (&buf, "PUSH_REPLY")) 448 { 449 const uint8_t ch = buf_read_u8 (&buf); 450 if (ch == ',') 451 { 452 struct buffer buf_orig = buf; 453 if (!c->c2.pulled_options_md5_init_done) 454 { 455 md5_state_init (&c->c2.pulled_options_state); 456 c->c2.pulled_options_md5_init_done = true; 457 } 458 if (!c->c2.did_pre_pull_restore) 459 { 460 pre_pull_restore (&c->options); 461 c->c2.did_pre_pull_restore = true; 462 } 463 if (apply_push_options (&c->options, 464 &buf, 465 permission_mask, 466 option_types_found, 467 c->c2.es)) 468 switch (c->options.push_continuation) 469 { 470 case 0: 471 case 1: 472 md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); 473 md5_state_final (&c->c2.pulled_options_state, &c->c2.pulled_options_digest); 474 c->c2.pulled_options_md5_init_done = false; 475 ret = PUSH_MSG_REPLY; 476 break; 477 case 2: 478 md5_state_update (&c->c2.pulled_options_state, BPTR(&buf_orig), BLEN(&buf_orig)); 479 ret = PUSH_MSG_CONTINUATION; 480 break; 481 } 482 } 483 else if (ch == '\0') 484 { 485 ret = PUSH_MSG_REPLY; 486 } 487 /* show_settings (&c->options); */ 488 } 489 return ret; 490} 491 492#if P2MP_SERVER 493 494/* 495 * Remove iroutes from the push_list. 496 */ 497void 498remove_iroutes_from_push_route_list (struct options *o) 499{ 500 if (o && o->push_list.head && o->iroutes) 501 { 502 struct gc_arena gc = gc_new (); 503 struct push_entry *e = o->push_list.head; 504 505 /* cycle through the push list */ 506 while (e) 507 { 508 char *p[MAX_PARMS]; 509 bool enable = true; 510 511 /* parse the push item */ 512 CLEAR (p); 513 if (parse_line (e->option, p, SIZE (p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc)) 514 { 515 /* is the push item a route directive? */ 516 if (p[0] && !strcmp (p[0], "route") && !p[3]) 517 { 518 /* get route parameters */ 519 bool status1, status2; 520 const in_addr_t network = getaddr (GETADDR_HOST_ORDER, p[1], 0, &status1, NULL); 521 const in_addr_t netmask = getaddr (GETADDR_HOST_ORDER, p[2] ? p[2] : "255.255.255.255", 0, &status2, NULL); 522 523 /* did route parameters parse correctly? */ 524 if (status1 && status2) 525 { 526 const struct iroute *ir; 527 528 /* does route match an iroute? */ 529 for (ir = o->iroutes; ir != NULL; ir = ir->next) 530 { 531 if (network == ir->network && netmask == netbits_to_netmask (ir->netbits >= 0 ? ir->netbits : 32)) 532 { 533 enable = false; 534 break; 535 } 536 } 537 } 538 } 539 } 540 541 /* should we copy the push item? */ 542 e->enable = enable; 543 if (!enable) 544 msg (D_PUSH, "REMOVE PUSH ROUTE: '%s'", e->option); 545 546 e = e->next; 547 } 548 549 gc_free (&gc); 550 } 551} 552 553#endif 554 555#endif 556