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#ifdef ENABLE_OCC 34 35#include "occ.h" 36 37#include "memdbg.h" 38 39#include "forward-inline.h" 40#include "occ-inline.h" 41 42/* 43 * This random string identifies an OpenVPN 44 * Configuration Control packet. 45 * It should be of sufficient length and randomness 46 * so as not to collide with other tunnel data. 47 * 48 * The OCC protocol is as follows: 49 * 50 * occ_magic -- (16 octets) 51 * 52 * type [OCC_REQUEST | OCC_REPLY] (1 octet) 53 * null terminated options string if OCC_REPLY (variable) 54 * 55 * When encryption is used, the OCC packet 56 * is encapsulated within the encrypted 57 * envelope. 58 * 59 * OCC_STRING_SIZE must be set to sizeof (occ_magic) 60 */ 61 62const uint8_t occ_magic[] = { 63 0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81, 64 0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c 65}; 66 67static const struct mtu_load_test mtu_load_test_sequence[] = { 68 69 {OCC_MTU_LOAD_REQUEST, -1000}, 70 {OCC_MTU_LOAD, -1000}, 71 {OCC_MTU_LOAD_REQUEST, -1000}, 72 {OCC_MTU_LOAD, -1000}, 73 {OCC_MTU_LOAD_REQUEST, -1000}, 74 {OCC_MTU_LOAD, -1000}, 75 76 {OCC_MTU_LOAD_REQUEST, -750}, 77 {OCC_MTU_LOAD, -750}, 78 {OCC_MTU_LOAD_REQUEST, -750}, 79 {OCC_MTU_LOAD, -750}, 80 {OCC_MTU_LOAD_REQUEST, -750}, 81 {OCC_MTU_LOAD, -750}, 82 83 {OCC_MTU_LOAD_REQUEST, -500}, 84 {OCC_MTU_LOAD, -500}, 85 {OCC_MTU_LOAD_REQUEST, -500}, 86 {OCC_MTU_LOAD, -500}, 87 {OCC_MTU_LOAD_REQUEST, -500}, 88 {OCC_MTU_LOAD, -500}, 89 90 {OCC_MTU_LOAD_REQUEST, -400}, 91 {OCC_MTU_LOAD, -400}, 92 {OCC_MTU_LOAD_REQUEST, -400}, 93 {OCC_MTU_LOAD, -400}, 94 {OCC_MTU_LOAD_REQUEST, -400}, 95 {OCC_MTU_LOAD, -400}, 96 97 {OCC_MTU_LOAD_REQUEST, -300}, 98 {OCC_MTU_LOAD, -300}, 99 {OCC_MTU_LOAD_REQUEST, -300}, 100 {OCC_MTU_LOAD, -300}, 101 {OCC_MTU_LOAD_REQUEST, -300}, 102 {OCC_MTU_LOAD, -300}, 103 104 {OCC_MTU_LOAD_REQUEST, -200}, 105 {OCC_MTU_LOAD, -200}, 106 {OCC_MTU_LOAD_REQUEST, -200}, 107 {OCC_MTU_LOAD, -200}, 108 {OCC_MTU_LOAD_REQUEST, -200}, 109 {OCC_MTU_LOAD, -200}, 110 111 {OCC_MTU_LOAD_REQUEST, -150}, 112 {OCC_MTU_LOAD, -150}, 113 {OCC_MTU_LOAD_REQUEST, -150}, 114 {OCC_MTU_LOAD, -150}, 115 {OCC_MTU_LOAD_REQUEST, -150}, 116 {OCC_MTU_LOAD, -150}, 117 118 {OCC_MTU_LOAD_REQUEST, -100}, 119 {OCC_MTU_LOAD, -100}, 120 {OCC_MTU_LOAD_REQUEST, -100}, 121 {OCC_MTU_LOAD, -100}, 122 {OCC_MTU_LOAD_REQUEST, -100}, 123 {OCC_MTU_LOAD, -100}, 124 125 {OCC_MTU_LOAD_REQUEST, -50}, 126 {OCC_MTU_LOAD, -50}, 127 {OCC_MTU_LOAD_REQUEST, -50}, 128 {OCC_MTU_LOAD, -50}, 129 {OCC_MTU_LOAD_REQUEST, -50}, 130 {OCC_MTU_LOAD, -50}, 131 132 {OCC_MTU_LOAD_REQUEST, 0}, 133 {OCC_MTU_LOAD, 0}, 134 {OCC_MTU_LOAD_REQUEST, 0}, 135 {OCC_MTU_LOAD, 0}, 136 {OCC_MTU_LOAD_REQUEST, 0}, 137 {OCC_MTU_LOAD, 0}, 138 139 {OCC_MTU_REQUEST, 0}, 140 {OCC_MTU_REQUEST, 0}, 141 {OCC_MTU_REQUEST, 0}, 142 {OCC_MTU_REQUEST, 0}, 143 {OCC_MTU_REQUEST, 0}, 144 {OCC_MTU_REQUEST, 0}, 145 {OCC_MTU_REQUEST, 0}, 146 {OCC_MTU_REQUEST, 0}, 147 {OCC_MTU_REQUEST, 0}, 148 {OCC_MTU_REQUEST, 0}, 149 150 {-1, 0} 151}; 152 153void 154check_send_occ_req_dowork (struct context *c) 155{ 156 if (++c->c2.occ_n_tries >= OCC_N_TRIES) 157 { 158 if (c->options.ce.remote) 159 /* 160 * No OCC_REPLY from peer after repeated attempts. 161 * Give up. 162 */ 163 msg (D_SHOW_OCC, 164 "NOTE: failed to obtain options consistency info from peer -- " 165 "this could occur if the remote peer is running a version of " 166 PACKAGE_NAME 167 " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent " 168 PACKAGE_NAME 169 " from running (" counter_format " bytes received from peer, " counter_format 170 " bytes authenticated data channel traffic) -- you can disable the options consistency " 171 "check with --disable-occ.", 172 c->c2.link_read_bytes, 173 c->c2.link_read_bytes_auth); 174 event_timeout_clear (&c->c2.occ_interval); 175 } 176 else 177 { 178 c->c2.occ_op = OCC_REQUEST; 179 180 /* 181 * If we don't hear back from peer, send another 182 * OCC_REQUEST in OCC_INTERVAL_SECONDS. 183 */ 184 event_timeout_reset (&c->c2.occ_interval); 185 } 186} 187 188void 189check_send_occ_load_test_dowork (struct context *c) 190{ 191 if (CONNECTION_ESTABLISHED (c)) 192 { 193 const struct mtu_load_test *entry; 194 195 if (!c->c2.occ_mtu_load_n_tries) 196 msg (M_INFO, 197 "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes."); 198 199 entry = &mtu_load_test_sequence[c->c2.occ_mtu_load_n_tries++]; 200 if (entry->op >= 0) 201 { 202 c->c2.occ_op = entry->op; 203 c->c2.occ_mtu_load_size = 204 EXPANDED_SIZE (&c->c2.frame) + entry->delta; 205 } 206 else 207 { 208 msg (M_INFO, 209 "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME " 1.5 or higher at other end of connection)."); 210 event_timeout_clear (&c->c2.occ_mtu_load_test_interval); 211 c->c2.occ_mtu_load_n_tries = 0; 212 } 213 } 214} 215 216void 217check_send_occ_msg_dowork (struct context *c) 218{ 219 bool doit = false; 220 221 c->c2.buf = c->c2.buffers->aux_buf; 222 ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame))); 223 ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame))); 224 ASSERT (buf_write (&c->c2.buf, occ_magic, OCC_STRING_SIZE)); 225 226 switch (c->c2.occ_op) 227 { 228 case OCC_REQUEST: 229 if (!buf_write_u8 (&c->c2.buf, OCC_REQUEST)) 230 break; 231 dmsg (D_PACKET_CONTENT, "SENT OCC_REQUEST"); 232 doit = true; 233 break; 234 235 case OCC_REPLY: 236 if (!c->c2.options_string_local) 237 break; 238 if (!buf_write_u8 (&c->c2.buf, OCC_REPLY)) 239 break; 240 if (!buf_write (&c->c2.buf, c->c2.options_string_local, 241 strlen (c->c2.options_string_local) + 1)) 242 break; 243 dmsg (D_PACKET_CONTENT, "SENT OCC_REPLY"); 244 doit = true; 245 break; 246 247 case OCC_MTU_REQUEST: 248 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REQUEST)) 249 break; 250 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST"); 251 doit = true; 252 break; 253 254 case OCC_MTU_REPLY: 255 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REPLY)) 256 break; 257 if (!buf_write_u16 (&c->c2.buf, c->c2.max_recv_size_local)) 258 break; 259 if (!buf_write_u16 (&c->c2.buf, c->c2.max_send_size_local)) 260 break; 261 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REPLY"); 262 doit = true; 263 break; 264 265 case OCC_MTU_LOAD_REQUEST: 266 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD_REQUEST)) 267 break; 268 if (!buf_write_u16 (&c->c2.buf, c->c2.occ_mtu_load_size)) 269 break; 270 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST"); 271 doit = true; 272 break; 273 274 case OCC_MTU_LOAD: 275 { 276 int need_to_add; 277 278 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD)) 279 break; 280 need_to_add = min_int (c->c2.occ_mtu_load_size, EXPANDED_SIZE (&c->c2.frame)) 281 - OCC_STRING_SIZE 282 - sizeof (uint8_t) 283 - EXTRA_FRAME (&c->c2.frame); 284 285 while (need_to_add > 0) 286 { 287 /* 288 * Fill the load test packet with pseudo-random bytes. 289 */ 290 if (!buf_write_u8 (&c->c2.buf, get_random () & 0xFF)) 291 break; 292 --need_to_add; 293 } 294 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d", 295 c->c2.occ_mtu_load_size, 296 OCC_STRING_SIZE, 297 (int) sizeof (uint8_t), 298 EXTRA_FRAME (&c->c2.frame), 299 MAX_RW_SIZE_TUN (&c->c2.frame), 300 BLEN (&c->c2.buf)); 301 doit = true; 302 } 303 break; 304 305 case OCC_EXIT: 306 if (!buf_write_u8 (&c->c2.buf, OCC_EXIT)) 307 break; 308 dmsg (D_PACKET_CONTENT, "SENT OCC_EXIT"); 309 doit = true; 310 break; 311 } 312 313 if (doit) 314 { 315 /* 316 * We will treat the packet like any other outgoing packet, 317 * compress, encrypt, sign, etc. 318 */ 319 encrypt_sign (c, true); 320 } 321 322 c->c2.occ_op = -1; 323} 324 325void 326process_received_occ_msg (struct context *c) 327{ 328 ASSERT (buf_advance (&c->c2.buf, OCC_STRING_SIZE)); 329 switch (buf_read_u8 (&c->c2.buf)) 330 { 331 case OCC_REQUEST: 332 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REQUEST"); 333 c->c2.occ_op = OCC_REPLY; 334 break; 335 336 case OCC_MTU_REQUEST: 337 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST"); 338 c->c2.occ_op = OCC_MTU_REPLY; 339 break; 340 341 case OCC_MTU_LOAD_REQUEST: 342 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST"); 343 c->c2.occ_mtu_load_size = buf_read_u16 (&c->c2.buf); 344 if (c->c2.occ_mtu_load_size >= 0) 345 c->c2.occ_op = OCC_MTU_LOAD; 346 break; 347 348 case OCC_REPLY: 349 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REPLY"); 350 if (c->options.occ && !TLS_MODE (c) && c->c2.options_string_remote) 351 { 352 if (!options_cmp_equal_safe ((char *) BPTR (&c->c2.buf), 353 c->c2.options_string_remote, 354 c->c2.buf.len)) 355 { 356 options_warning_safe ((char *) BPTR (&c->c2.buf), 357 c->c2.options_string_remote, 358 c->c2.buf.len); 359 } 360 } 361 event_timeout_clear (&c->c2.occ_interval); 362 break; 363 364 case OCC_MTU_REPLY: 365 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY"); 366 c->c2.max_recv_size_remote = buf_read_u16 (&c->c2.buf); 367 c->c2.max_send_size_remote = buf_read_u16 (&c->c2.buf); 368 if (c->options.mtu_test 369 && c->c2.max_recv_size_remote > 0 370 && c->c2.max_send_size_remote > 0) 371 { 372 msg (M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]", 373 c->c2.max_send_size_local, 374 c->c2.max_recv_size_remote, 375 c->c2.max_send_size_remote, 376 c->c2.max_recv_size_local); 377 if (!c->options.ce.fragment 378 && (proto_is_dgram(c->options.ce.proto)) 379 && c->c2.max_send_size_local > TUN_MTU_MIN 380 && (c->c2.max_recv_size_remote < c->c2.max_send_size_local 381 || c->c2.max_recv_size_local < c->c2.max_send_size_remote)) 382 msg (M_INFO, "NOTE: This connection is unable to accomodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.", 383 c->c2.max_send_size_local); 384 } 385 event_timeout_clear (&c->c2.occ_mtu_load_test_interval); 386 break; 387 388 case OCC_EXIT: 389 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_EXIT"); 390 c->sig->signal_received = SIGTERM; 391 c->sig->signal_text = "remote-exit"; 392 break; 393 } 394 c->c2.buf.len = 0; /* don't pass packet on */ 395} 396 397#else 398static void dummy(void) {} 399#endif 400