📄 options.c
字号:
#endif/* * Build an options string to represent data channel encryption options. * This string must match exactly between peers. The keysize is checked * separately by read_key(). * * The following options must match on both peers: * * Tunnel options: * * --dev tun|tap [unit number need not match] * --dev-type tun|tap * --link-mtu * --udp-mtu * --tun-mtu * --proto udp * --proto tcp-client [matched with --proto tcp-server * on the other end of the connection] * --proto tcp-server [matched with --proto tcp-client on * the other end of the connection] * --tun-ipv6 * --ifconfig x y [matched with --ifconfig y x on * the other end of the connection] * * --comp-lzo * --fragment * * Crypto Options: * * --cipher * --auth * --keysize * --secret * --no-replay * --no-iv * * SSL Options: * * --tls-auth * --tls-client [matched with --tls-server on * the other end of the connection] * --tls-server [matched with --tls-client on * the other end of the connection] */char *options_string (const struct options *o, const struct frame *frame, struct tuntap *tt, bool remote, struct gc_arena *gc){ struct buffer out = alloc_buf (256); bool tt_local = false; buf_printf (&out, "V4"); /* * Tunnel Options */ buf_printf (&out, ",dev-type %s", dev_type_string (o->dev, o->dev_type)); buf_printf (&out, ",link-mtu %d", EXPANDED_SIZE (frame)); buf_printf (&out, ",tun-mtu %d", PAYLOAD_SIZE (frame)); buf_printf (&out, ",proto %s", proto2ascii (proto_remote (o->proto, remote), true)); if (o->tun_ipv6) buf_printf (&out, ",tun-ipv6"); /* * Try to get ifconfig parameters into the options string. * If tt is undefined, make a temporary instantiation. */ if (!tt) { tt = init_tun (o->dev, o->dev_type, o->ifconfig_local, o->ifconfig_remote_netmask, (in_addr_t)0, (in_addr_t)0); if (tt) tt_local = true; } if (tt && o->mode == MODE_POINT_TO_POINT && !PULL_DEFINED(o)) { const char *ios = ifconfig_options_string (tt, remote, o->ifconfig_nowarn, gc); if (ios && strlen (ios)) buf_printf (&out, ",ifconfig %s", ios); } if (tt_local) { free (tt); tt = NULL; }#ifdef USE_LZO if (o->comp_lzo) buf_printf (&out, ",comp-lzo");#endif if (o->fragment) buf_printf (&out, ",mtu-dynamic");#ifdef USE_CRYPTO#ifdef USE_SSL#define TLS_CLIENT (o->tls_client)#define TLS_SERVER (o->tls_server)#else#define TLS_CLIENT (false)#define TLS_SERVER (false)#endif /* * Key direction */ { const char *kd = keydirection2ascii (o->key_direction, remote); if (kd) buf_printf (&out, ",keydir %s", kd); } /* * Crypto Options */ if (o->shared_secret_file || TLS_CLIENT || TLS_SERVER) { struct key_type kt; ASSERT ((o->shared_secret_file != NULL) + (TLS_CLIENT == true) + (TLS_SERVER == true) <= 1); init_key_type (&kt, o->ciphername, o->ciphername_defined, o->authname, o->authname_defined, o->keysize, true, false); buf_printf (&out, ",cipher %s", kt_cipher_name (&kt)); buf_printf (&out, ",auth %s", kt_digest_name (&kt)); buf_printf (&out, ",keysize %d", kt_key_size (&kt)); if (o->shared_secret_file) buf_printf (&out, ",secret"); if (!o->replay) buf_printf (&out, ",no-replay"); if (!o->use_iv) buf_printf (&out, ",no-iv"); }#ifdef USE_SSL /* * SSL Options */ { if (TLS_CLIENT || TLS_SERVER) { if (o->tls_auth_file) buf_printf (&out, ",tls-auth"); if (o->key_method > 1) buf_printf (&out, ",key-method %d", o->key_method); } if (remote) { if (TLS_CLIENT) buf_printf (&out, ",tls-server"); else if (TLS_SERVER) buf_printf (&out, ",tls-client"); } else { if (TLS_CLIENT) buf_printf (&out, ",tls-client"); else if (TLS_SERVER) buf_printf (&out, ",tls-server"); } }#endif /* USE_SSL */#undef TLS_CLIENT#undef TLS_SERVER#endif /* USE_CRYPTO */ return BSTR (&out);}/* * Compare option strings for equality. * If the first two chars of the strings differ, it means that * we are looking at different versions of the options string, * therefore don't compare them and return true. */booloptions_cmp_equal (char *actual, const char *expected, size_t actual_n){ if (actual_n > 0) { actual[actual_n - 1] = 0;#ifndef STRICT_OPTIONS_CHECK if (strncmp (actual, expected, 2)) { msg (D_SHOW_OCC, "NOTE: failed to perform options consistency check between peers because of " PACKAGE_NAME " version differences -- you can disable the options consistency check with --disable-occ (Required for TLS connections between " PACKAGE_NAME " 1.3.x and later versions). Actual Remote Options: '%s'. Expected Remote Options: '%s'", actual, expected); return true; } else#endif return !strcmp (actual, expected); } else return true;}voidoptions_warning (char *actual, const char *expected, size_t actual_n){ if (actual_n > 0) { actual[actual_n - 1] = 0; msg (M_WARN, "WARNING: Actual Remote Options ('%s') are inconsistent with Expected Remote Options ('%s')", actual, expected); }}const char *options_string_version (const char* s, struct gc_arena *gc){ struct buffer out = alloc_buf_gc (4, gc); strncpynt (BPTR (&out), s, 3); return BSTR (&out);}static voidforeign_option (struct options *o, char *argv[], int len){ if (len > 0) { struct gc_arena gc = gc_new(); struct buffer name = alloc_buf_gc (64, &gc); struct buffer value = alloc_buf_gc (256, &gc); int i; bool first = true; buf_printf (&name, "foreign_option_%d", o->foreign_option_index + 1); ++o->foreign_option_index; for (i = 0; i < len; ++i) { if (argv[i]) { if (!first) buf_printf (&value, " "); buf_printf (&value, argv[i]); first = false; } } setenv_str (BSTR(&name), BSTR(&value)); gc_free (&gc); }}static voidusage (void){ struct options o; FILE *fp = msg_fp(); init_options (&o);#if defined(USE_CRYPTO) && defined(USE_SSL) fprintf (fp, usage_message, title_string, o.connect_retry_seconds, o.local_port, o.remote_port, TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT, o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#elif defined(USE_CRYPTO) fprintf (fp, usage_message, title_string, o.connect_retry_seconds, o.local_port, o.remote_port, TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT, o.verbosity, o.authname, o.ciphername, o.replay_window, o.replay_time);#else fprintf (fp, usage_message, title_string, o.connect_retry_seconds, o.local_port, o.remote_port, TUN_MTU_DEFAULT, TAP_MTU_EXTRA_DEFAULT, o.verbosity);#endif fflush(fp); openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */}voidusage_small (void){ msg (M_WARN|M_NOPREFIX, "Use --help for more information."); openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */}static voidusage_version (void){ msg (M_INFO|M_NOPREFIX, "%s", title_string); msg (M_INFO|M_NOPREFIX, "Copyright (C) 2002-2004 James Yonan <jim@yonan.net>"); openvpn_exit (OPENVPN_EXIT_STATUS_USAGE); /* exit point */}voidnotnull (const char *arg, const char *description){ if (!arg) msg (M_USAGE, "Options error: You must define %s", description);}boolstring_defined_equal (const char *s1, const char *s2){ if (s1 && s2) return !strcmp (s1, s2); else return false;}static voidping_rec_err (int msglevel){ msg (msglevel, "Options error: only one of --ping-exit or --ping-restart options may be specified");}static inline intpositive (int i){ return i < 0 ? 0 : i;}static inline boolspace (char c){ return c == '\0' || isspace (c);}static intparse_line (char *line, char *p[], int n, const char *file, int line_num, int msglevel, struct gc_arena *gc){ const int STATE_INITIAL = 0; const int STATE_READING_QUOTED_PARM = 1; const int STATE_READING_UNQUOTED_PARM = 2; const int STATE_DONE = 3; int ret = 0; char *c = line; int state = STATE_INITIAL; bool backslash = false; char in, out; char parm[256]; unsigned int parm_len = 0; do { in = *c; out = 0; if (!backslash && in == '\\') { backslash = true; } else { if (state == STATE_INITIAL) { if (!space (in)) { if (in == ';' || in == '#') /* comment */ break; if (!backslash && in == '\"') state = STATE_READING_QUOTED_PARM; else { out = in; state = STATE_READING_UNQUOTED_PARM; } } } else if (state == STATE_READING_UNQUOTED_PARM) { if (!backslash && space (in)) state = STATE_DONE; else out = in; } else if (state == STATE_READING_QUOTED_PARM) { if (!backslash && in == '\"') state = STATE_DONE; else out = in; } if (state == STATE_DONE) { ASSERT (parm_len > 0); p[ret] = gc_malloc (parm_len + 1, true, gc); memcpy (p[ret], parm, parm_len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -