📄 options.c
字号:
/* * OpenVPN -- An application to securely tunnel IP networks * over a single UDP port, with support for TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002 James Yonan <jim@yonan.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "config.h"#include "syshead.h"#include "buffer.h"#include "error.h"#include "openvpn.h"#include "common.h"#include "mtu.h"#include "shaper.h"#include "crypto.h"#include "options.h"#include "memdbg.h"static const char usage_message[] = "%s\n" "\n" "General Options:\n" "--help : Show options.\n" "--version : Show copyright and version information.\n" "--config file : Read configuration options from file.\n" "\n" "Tunnel Options:\n" "--local host : Local host name or ip address.\n" "--remote host : Remote host name or ip address.\n" "--resolv-retry n: If hostname resolve fails for --local or --remote, retry\n" " resolve for n seconds before failing (disabled by default).\n" "--float : Allow remote to change its IP address/port, such as through\n" " DHCP (this is the default if --remote is not used).\n" "--ipchange cmd : Execute shell command cmd on remote ip address initial\n" " setting or change -- execute as: cmd ip-address port#\n" " (',' may be used to separate multiple args in cmd)\n" "--port port : UDP port # for both local and remote.\n" "--lport port : UDP port # for local (default=%d).\n" "--rport port : UDP port # for remote (default=%d).\n" "--nobind : Do not bind to local address and port.\n" "--dev tunX|tapX : tun/tap device (X can be omitted for dynamic device in\n" " Linux 2.4+).\n" "--dev-type dt : Which device type are we using? (dt = tun or tap) Use\n" " this option only if the tun/tap device used with --dev\n" " does not begin with \"tun\" or \"tap\".\n" "--dev-node node : Explicitly set the device node rather than using\n" " /dev/net/tun, /dev/tun, /dev/tap, etc.\n" "--tun-ipv6 : Build tun link capable of forwarding IPv6 traffic.\n" "--ifconfig l r : Configure tun device to use IP address l as a local\n" " endpoint and r as a remote endpoint. l & r should be\n" " swapped on the other peer. l & r must be private\n" " addresses outside of the subnets used by either peer.\n" " Implies --udp-mtu %d if neither --udp-mtu or --tun-mtu\n" " explicitly specified.\n" "--shaper n : Restrict output to peer to n bytes per second.\n" "--inactive n : Exit after n seconds of inactivity on tun/tap device.\n" "--ping-exit n : Exit if n seconds pass without reception of remote ping.\n" "--ping-restart n: Restart if n seconds pass without reception of remote ping.\n" "--ping-timer-rem: Run the --ping-exit/--ping-restart timer only if we have a\n" " remote address.\n" "--ping n : Ping remote once every n seconds over UDP port.\n" "--persist-tun : Keep tun/tap device open across SIGUSR1 or --ping-restart.\n" "--persist-remote-ip : Keep remote IP address across SIGUSR1 or --ping-restart.\n" "--persist-local-ip : Keep local IP address across SIGUSR1 or --ping-restart.\n" "--persist-key : Don't re-read key files across SIGUSR1 or --ping-restart.\n" "--tun-mtu n : Take the tun/tap device MTU to be n and derive the\n" " UDP MTU from it (default=%d).\n" "--udp-mtu n : Take the UDP device MTU to be n and derive the tun MTU\n" " from it (disabled by default).\n" "--mlock : Disable Paging -- ensures key material and tunnel\n" " data will never be written to disk.\n" "--up cmd : Shell cmd to execute after successful tun device open.\n" " Execute as: cmd tun/tap-dev tun-mtu udp-mtu \\\n" " ifconfig-local-ip ifconfig-remote-ip\n" " (pre --user or --group UID/GID change)\n" "--down cmd : Shell cmd to run after tun device close.\n" " (post --user/--group UID/GID change and/or --chroot)\n" " (script parameters are same as --up option)\n" "--user user : Set UID to user after initialization.\n" "--group group : Set GID to group after initialization.\n" "--chroot dir : Chroot to this directory before initialization.\n" "--cd dir : Change to this directory before initialization.\n" "--daemon : Become a daemon.\n" "--inetd : Run as an inetd or xinetd server.\n" "--writepid file : Write main process ID to file.\n" "--nice n : Change process priority (>0 = lower, <0 = higher).\n"#ifdef USE_PTHREAD "--nice-work n : Change thread priority of work thread. The work\n" " thread is used for background processing such as\n" " RSA key number crunching.\n"#endif "--verb n : Set output verbosity to n (default=%d):\n" " (Level 5 is recommended if you want a good summary\n" " of what's happening without being swamped by output).\n" " : 0 -- no output except fatal errors\n" " : 1 -- startup info + connection initiated messages +\n" " non-fatal encryption & net errors\n" " : 2 -- show all parameter settings\n" " : 3 -- show key negotiations + --gremlin net outages\n" " : 4 -- show partial TLS debug info\n" " : 5 -- show adaptive compress info\n" " : 6 -- show keys\n" " : 7 -- show verbose key negotiations\n" " : 8 -- show all debug info\n" "--mute n : Log at most n consecutive messages in the same category.\n" "--gremlin : Simulate dropped & corrupted packets + network outages\n" " to test robustness of protocol (for debugging only).\n"#ifdef USE_LZO "--comp-lzo : Use fast LZO compression -- may add up to 1 byte per\n" " packet for uncompressible data.\n" "--comp-noadapt : Don't use adaptive compression when --comp-lzo\n" " is specified.\n"#endif#ifdef USE_CRYPTO "\n" "Data Channel Encryption Options (must be compatible between peers):\n" "(These options are meaningful for both Static Key & TLS-mode)\n" "--secret file : Enable Static Key encryption mode (non-TLS),\n" " use shared secret file, generate with --genkey.\n" "--auth alg : Authenticate packets with HMAC using message\n" " digest algorithm alg (default=%s).\n" " (usually adds 16 or 20 bytes per packet)\n" " Set alg=none to disable authentication.\n" "--cipher alg : Encrypt packets with cipher algorithm alg\n" " (default=%s).\n" " Set alg=none to disable encryption.\n"#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH "--keysize n : Size of cipher key in bits (optional).\n"#endif " If unspecified, defaults to cipher-specific default.\n" "--no-replay : Disable replay protection.\n" "--no-iv : Disable cipher IV -- only allowed with CBC mode ciphers.\n" "--test-crypto : Run a self-test of crypto features enabled.\n" " For debugging only.\n"#ifdef USE_SSL "\n" "TLS Key Negotiation Options:\n" "(These options are meaningful only for TLS-mode)\n" "--tls-server : Enable TLS and assume server role during TLS handshake.\n" "--tls-client : Enable TLS and assume client role during TLS handshake.\n" "--ca file : Certificate authority file in .pem format containing\n" " root certificate.\n" "--dh file : File containing Diffie Hellman parameters\n" " in .pem format (for --tls-server only).\n" " Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n" "--cert file : Local certificate in .pem format -- must be signed\n" " by a Certificate Authority in --ca file.\n" "--key file : Local private key in .pem format.\n" "--tls-cipher l : A list l of allowable TLS ciphers separated by | (optional).\n" " : Use --show-tls to see a list of supported TLS ciphers.\n" "--tls-timeout n : Packet retransmit timeout on TLS control channel\n" " if no ACK from remote within n seconds (default=%d).\n" "--reneg-bytes n : Renegotiate data chan. key after n bytes sent and recvd.\n" "--reneg-pkts n : Renegotiate data chan. key after n packets sent and recvd.\n" "--reneg-sec n : Renegotiate data chan. key after n seconds (default=%d).\n" "--hand-window n : Data channel key exchange must finalize within n seconds\n" " of handshake initiation by any peer (default=%d).\n" "--tran-window n : Transition window -- old key can live this many seconds\n" " after new key renegotiation begins (default=%d).\n" "--single-session: Allow only one session (reset state on restart).\n" "--tls-auth f : Add an additional layer of authentication on top of the TLS\n" " control channel to protect against DoS attacks.\n" " f (required) is a shared-secret passphrase file.\n" "--askpass : Get PEM password from controlling tty before we daemonize.\n" "--tls-verify cmd: Execute shell command cmd to verify the X509 name of a\n" " pending TLS connection that has otherwise passed all other\n" " tests of certification. cmd should return 0 to allow\n" " TLS handshake to proceed, or 1 to fail. (cmd is\n" " executed as 'cmd certificate_depth X509_NAME_oneline')\n" " (',' may be used to separate multiple args in cmd)\n" "--disable-occ : Disable options compatibility check between peers.\n"#endif /* USE_SSL */ "\n" "SSL Library information:\n" "--show-ciphers : Show all cipher algorithms to use with --cipher option.\n" "--show-digests : Show all message digest algorithms to use with --auth option.\n"#ifdef USE_SSL "--show-tls : Show all TLS ciphers (TLS used only as a control channel).\n"#endif "\n" "Generate a random key (only for non-TLS static key encryption mode):\n" "--genkey : Generate a random key to be used as a shared secret,\n" " for use with the --secret option.\n" "--secret file : Write key to file.\n"#endif /* USE_CRYPTO */#ifdef TUNSETPERSIST "\n" "Tun/Tap config mode (available with linux 2.4+):\n" "--mktun : Create a persistent tunnel.\n" "--rmtun : Remove a persistent tunnel.\n" "--dev tunX|tapX : tun/tap device\n" "--dev-type dt : Device type. See tunnel options above for details.\n"#endif ;/* * This is where the options defaults go. * Any option not explicitly set here * will be set to 0. */voidinit_options (struct options *o){ CLEAR (*o);#ifdef TUNSETPERSIST o->persist_mode = 1;#endif o->local_port = o->remote_port = 5000; o->verbosity = 1; o->bind_local = true; o->tun_mtu = DEFAULT_TUN_MTU; o->udp_mtu = DEFAULT_UDP_MTU;#ifdef USE_LZO o->comp_lzo_adaptive = true;#endif#ifdef USE_CRYPTO o->ciphername = "BF-CBC"; o->ciphername_defined = true; o->authname = "SHA1"; o->authname_defined = true; o->packet_id = true; o->iv = true;#ifdef USE_SSL o->tls_timeout = 5; o->renegotiate_seconds = 3600; o->handshake_window = 60; o->transition_window = 3600;#endif#endif}#define SHOW_PARM(name, value, format) msg(D_SHOW_PARMS, " " #name " = " format, (value))#define SHOW_STR(var) SHOW_PARM(var, (o->var ? o->var : "[UNDEF]"), "'%s'")#define SHOW_INT(var) SHOW_PARM(var, o->var, "%d")#define SHOW_BOOL(var) SHOW_PARM(var, (o->var ? "ENABLED" : "DISABLED"), "%s");voidshow_settings (const struct options *o){ msg (D_SHOW_PARMS, "Current Parameter Settings:");#ifdef TUNSETPERSIST SHOW_BOOL (persist_config); SHOW_INT (persist_mode);#endif#ifdef USE_CRYPTO SHOW_BOOL (show_ciphers); SHOW_BOOL (show_digests); SHOW_BOOL (genkey);#ifdef USE_SSL SHOW_BOOL (askpass); SHOW_BOOL (show_tls_ciphers);#endif#endif SHOW_STR (local); SHOW_STR (remote); SHOW_INT (local_port); SHOW_INT (remote_port); SHOW_BOOL (remote_float); SHOW_STR (ipchange); SHOW_BOOL (bind_local); SHOW_STR (dev); SHOW_STR (dev_type); SHOW_STR (dev_node); SHOW_BOOL (tun_ipv6); SHOW_STR (ifconfig_local); SHOW_STR (ifconfig_remote); SHOW_INT (shaper); SHOW_INT (tun_mtu); SHOW_BOOL (tun_mtu_defined); SHOW_INT (udp_mtu); SHOW_BOOL (udp_mtu_defined); SHOW_BOOL (mlock); SHOW_INT (inactivity_timeout); SHOW_INT (ping_send_timeout); SHOW_INT (ping_rec_timeout); SHOW_INT (ping_rec_timeout_action); SHOW_BOOL (ping_timer_remote); SHOW_BOOL (persist_tun); SHOW_BOOL (persist_local_ip); SHOW_BOOL (persist_remote_ip); SHOW_BOOL (persist_key); SHOW_INT (resolve_retry_seconds); SHOW_STR (username); SHOW_STR (groupname); SHOW_STR (chroot_dir); SHOW_STR (cd_dir); SHOW_STR (writepid); SHOW_STR (up_script); SHOW_STR (down_script); SHOW_BOOL (daemon); SHOW_BOOL (inetd); SHOW_INT (nice); SHOW_INT (verbosity); SHOW_INT (mute); SHOW_BOOL (gremlin);#ifdef USE_LZO SHOW_BOOL (comp_lzo); SHOW_BOOL (comp_lzo_adaptive);#endif#ifdef USE_CRYPTO SHOW_STR (shared_secret_file); SHOW_BOOL (ciphername_defined); SHOW_STR (ciphername); SHOW_BOOL (authname_defined); SHOW_STR (authname); SHOW_INT (keysize); SHOW_BOOL (packet_id); SHOW_BOOL (iv); SHOW_BOOL (test_crypto);#ifdef USE_SSL SHOW_BOOL (tls_server); SHOW_BOOL (tls_client); SHOW_STR (ca_file); SHOW_STR (dh_file); SHOW_STR (cert_file); SHOW_STR (priv_key_file); SHOW_STR (cipher_list); SHOW_STR (tls_verify); SHOW_INT (tls_timeout); SHOW_INT (renegotiate_bytes); SHOW_INT (renegotiate_packets); SHOW_INT (renegotiate_seconds); SHOW_INT (handshake_window); SHOW_INT (transition_window); SHOW_BOOL (single_session); SHOW_BOOL (disable_occ); SHOW_STR (tls_auth_file);#endif#endif}#undef SHOW_PARM#undef SHOW_STR#undef SHOW_INT#undef SHOW_BOOL#if defined(USE_CRYPTO) && defined(USE_SSL)/* * 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(). * * TODO: add --dev-type tun|tap|null to TLS negotiation string using dev_type_string() */char *options_string (const struct options *o){ struct buffer out = alloc_buf (256); buf_printf (&out, "V1"); if (o->ciphername_defined) buf_printf (&out, " --cipher %s", o->ciphername); if (o->authname_defined) buf_printf (&out, " --auth %s", o->authname); if (!o->packet_id) buf_printf (&out, " --no-replay"); if (!o->iv) buf_printf (&out, " --no-iv");#ifdef USE_LZO if (o->comp_lzo) buf_printf (&out, " --comp-lzo");#endif return out.data;}#endifstatic char *comma_to_space (const char *src){ char *ret = (char *) gc_malloc (strlen (src) + 1); char *dest = ret; char c; do { c = *src++; if (c == ',') c = ' '; *dest++ = c; } while (c); return ret;}static voidusage (){ struct options o; init_options (&o);#if defined(USE_CRYPTO) && defined(USE_SSL) printf (usage_message, TITLE, o.local_port, o.remote_port, o.udp_mtu, o.tun_mtu, o.verbosity, o.authname, o.ciphername, o.tls_timeout, o.renegotiate_seconds, o.handshake_window, o.transition_window);#elif defined(USE_CRYPTO) printf (usage_message, TITLE, o.local_port, o.remote_port, o.udp_mtu, o.tun_mtu, o.verbosity, o.authname, o.ciphername);#else printf (usage_message, TITLE, o.local_port, o.remote_port, o.udp_mtu, o.tun_mtu, o.verbosity);#endif exit (1);}voidusage_small (){ msg (M_WARN, "Use --help for more information"); exit (1);}voidusage_version (){ printf ("%s\nCopyright (C) 2002 James Yonan <jim@yonan.net>\n", TITLE); exit (1);}voidnotnull (const char *arg, const char *description){ if (!arg) { msg (M_WARN, "Options error: You must define %s", description); usage_small (); }}boolstring_defined_equal (const char *s1, const char *s2){ if (s1 && s2) return !strcmp (s1, s2); else return false;}static voidping_rec_err (){ msg (M_WARN, "Options error: only one of --ping-exit or --ping-restart options may be specified"); usage_small ();}static intpositive (int i){ return i < 0 ? 0 : i;}static boolspace (char c){ return c == '\0' || isspace (c);}static intparse_line (char *line, char *p[], int n, const char *file, int line_num){ int ret = 0; char *c = line; char *start = NULL; /* * Parse states: * 0 -- Initial * 1 -- Reading non-quoted parm * 2 -- Leading quote * 3 -- Reading quoted parm * 4 -- First char after parm */ int state = 0; do { if (state == 0) { if (!space (*c)) { if (*c == ';' || *c == '#') /* comment */ break; if (*c == '\"') state = 2; else { start = c; state = 1; } } } else if (state == 1) { if (space (*c)) state = 4; } else if (state == 2) { start = c; state = 3; } else if (state == 3) { if (*c == '\"') state = 4; } if (state == 4) { const int len = c - start; ASSERT (len > 0); p[ret] = gc_malloc (len + 1); memcpy (p[ret], start, len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -