1026 static const struct option longopts[] = {
1027 {.name =
"username", .has_arg = required_argument, .flag =
nullptr, .val =
'u'},
1028 {.name =
"password", .has_arg = required_argument, .flag =
nullptr, .val =
'p'},
1029 {.name =
"response", .has_arg = required_argument, .flag =
nullptr, .val =
'r'},
1030 {.name =
"dc", .has_arg = required_argument, .flag =
nullptr, .val =
'D'},
1031 {.name =
"proto", .has_arg = required_argument, .flag =
nullptr, .val =
'P'},
1032 {.name =
"ipv6", .has_arg = required_argument, .flag =
nullptr, .val =
'6'},
1033 {.name =
"server", .has_arg = required_argument, .flag =
nullptr, .val =
's'},
1034 {.name =
"port", .has_arg = required_argument, .flag =
nullptr, .val =
'R'},
1035 {.name =
"timeout", .has_arg = required_argument, .flag =
nullptr, .val =
't'},
1036 {.name =
"compress", .has_arg = required_argument, .flag =
nullptr, .val =
'c'},
1037 {.name =
"pk-password", .has_arg = required_argument, .flag =
nullptr, .val =
'z'},
1038 {.name =
"tvm-override", .has_arg = required_argument, .flag =
nullptr, .val =
'M'},
1039 {.name =
"proxy-host", .has_arg = required_argument, .flag =
nullptr, .val =
'h'},
1040 {.name =
"proxy-port", .has_arg = required_argument, .flag =
nullptr, .val =
'q'},
1041 {.name =
"proxy-username", .has_arg = required_argument, .flag =
nullptr, .val =
'U'},
1042 {.name =
"proxy-password", .has_arg = required_argument, .flag =
nullptr, .val =
'W'},
1043 {.name =
"peer-info", .has_arg = required_argument, .flag =
nullptr, .val =
'I'},
1044 {.name =
"acc-protos", .has_arg = required_argument, .flag =
nullptr, .val =
'K'},
1045 {.name =
"gremlin", .has_arg = required_argument, .flag =
nullptr, .val =
'G'},
1046 {.name =
"corrupt-data", .has_arg = required_argument, .flag =
nullptr, .val =
'F'},
1047 {.name =
"proxy-basic", .has_arg = no_argument, .flag =
nullptr, .val =
'B'},
1048 {.name =
"alt-proxy", .has_arg = no_argument, .flag =
nullptr, .val =
'A'},
1049#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1050 {.name =
"no-dco", .has_arg = no_argument, .flag =
nullptr, .val =
'd'},
1052 {.name =
"eval", .has_arg = no_argument, .flag =
nullptr, .val =
'e'},
1053 {.name =
"self-test", .has_arg = no_argument, .flag =
nullptr, .val =
'T'},
1054 {.name =
"cache-password", .has_arg = no_argument, .flag =
nullptr, .val =
'C'},
1055 {.name =
"no-cert", .has_arg = no_argument, .flag =
nullptr, .val =
'x'},
1056 {.name =
"force-aes-cbc", .has_arg = no_argument, .flag =
nullptr, .val =
'f'},
1057 {.name =
"google-dns", .has_arg = no_argument, .flag =
nullptr, .val =
'g'},
1058 {.name =
"persist-tun", .has_arg = no_argument, .flag =
nullptr, .val =
'j'},
1059 {.name =
"wintun", .has_arg = no_argument, .flag =
nullptr, .val =
'w'},
1060 {.name =
"allow-local-dns-resolvers", .has_arg = no_argument, .flag =
nullptr, .val =
'l'},
1061 {.name =
"def-keydir", .has_arg = required_argument, .flag =
nullptr, .val =
'k'},
1062 {.name =
"merge", .has_arg = no_argument, .flag =
nullptr, .val =
'm'},
1063 {.name =
"version", .has_arg = no_argument, .flag =
nullptr, .val =
'v'},
1064 {.name =
"auto-sess", .has_arg = no_argument, .flag =
nullptr, .val =
'a'},
1065 {.name =
"auth-retry", .has_arg = no_argument, .flag =
nullptr, .val =
'Y'},
1066 {.name =
"tcprof-override", .has_arg = required_argument, .flag =
nullptr, .val =
'X'},
1067 {.name =
"write-url", .has_arg = required_argument, .flag =
nullptr, .val =
'Z'},
1068 {.name =
"sso-methods", .has_arg = required_argument, .flag =
nullptr, .val =
'S'},
1069 {.name =
"ssl-debug", .has_arg = required_argument, .flag =
nullptr, .val = 1 },
1070 {.name =
"epki-cert", .has_arg = required_argument, .flag =
nullptr, .val = 2 },
1071 {.name =
"epki-ca", .has_arg = required_argument, .flag =
nullptr, .val = 3 },
1072 {.name =
"epki-key", .has_arg = required_argument, .flag =
nullptr, .val = 4 },
1073 {.name =
"legacy-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'L'},
1074 {.name =
"non-preferred-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'Q'},
1075#ifdef OPENVPN_REMOTE_OVERRIDE
1076 {.name =
"remote-override", .has_arg = required_argument, .flag =
nullptr, .val = 5 },
1078 {.name =
"tbc", .has_arg = no_argument, .flag =
nullptr, .val = 6 },
1079 {.name =
"app-custom-protocols", .has_arg = required_argument, .flag =
nullptr, .val =
'K'},
1080 {.name =
"certcheck-cert", .has_arg = required_argument, .flag =
nullptr, .val =
'o'},
1081 {.name =
"certcheck-pkey", .has_arg = required_argument, .flag =
nullptr, .val =
'O'},
1082 {.name =
"certcheck-clientca", .has_arg = required_argument, .flag =
nullptr, .val =
'b'},
1083 {.name =
nullptr, .has_arg = 0, .flag =
nullptr, .val = 0 }
1095 std::string username;
1096 std::string password;
1097 std::string response;
1098 std::string dynamicChallengeCookie;
1100 std::string allowUnusedAddrFamilies;
1104 std::string compress;
1105 std::string privateKeyPassword;
1106 std::string tlsVersionMinOverride;
1107 std::string tlsCertProfileOverride;
1108 std::string proxyHost;
1109 std::string proxyPort;
1110 std::string proxyUsername;
1111 std::string proxyPassword;
1112 std::string peer_info;
1113 std::string gremlin;
1114 unsigned int corruptData = 0;
1115 std::string ssoMethods;
1116 std::string appCustomProtocols;
1117 std::string certcheck_cert_fn;
1118 std::string certcheck_pkey_fn;
1119 std::string certcheck_clientca;
1121 bool self_test =
false;
1122 bool disableClientCert =
false;
1123 bool proxyAllowCleartextAuth =
false;
1124 int defaultKeyDirection = -1;
1125 int sslDebugLevel = 0;
1126 bool googleDnsFallback =
false;
1127 bool autologinSessions =
false;
1128 bool retryOnAuthFailed =
false;
1129 bool tunPersist =
false;
1130 bool wintun =
false;
1131 bool allowLocalDnsResolvers =
false;
1132 bool enableLegacyAlgorithms =
false;
1133 bool enableNonPreferredDCO =
false;
1135 bool version =
false;
1136 bool altProxy =
false;
1137#if defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1142 bool generateTunBuilderCaptureEvent =
false;
1143 std::string epki_cert_fn;
1144 std::string epki_ca_fn;
1145 std::string epki_key_fn;
1147#ifdef OPENVPN_REMOTE_OVERRIDE
1148 std::string remote_override_cmd;
1150 std::string write_url_fn;
1155 while ((ch = getopt_long(argc, argv,
"6:ABCD:F:G:I:K:LM:P:QR:S:TU:W:X:YZ:ac:degh:o:O:b:jk:lmp:q:r:s:t:u:vwxz:", longopts,
nullptr)) != -1)
1160 sslDebugLevel = ::atoi(optarg);
1163 epki_cert_fn = optarg;
1166 epki_ca_fn = optarg;
1169 epki_key_fn = optarg;
1171#ifdef OPENVPN_REMOTE_OVERRIDE
1173 remote_override_cmd = optarg;
1177 generateTunBuilderCaptureEvent =
true;
1186 disableClientCert =
true;
1201 allowUnusedAddrFamilies = optarg;
1210 ssoMethods = optarg;
1213 timeout = ::atoi(optarg);
1219 privateKeyPassword = optarg;
1222 tlsVersionMinOverride = optarg;
1225 tlsCertProfileOverride = optarg;
1234 enableNonPreferredDCO =
true;
1237 proxyUsername = optarg;
1240 proxyPassword = optarg;
1243 proxyAllowCleartextAuth =
true;
1252 googleDnsFallback =
true;
1255 autologinSessions =
true;
1258 retryOnAuthFailed =
true;
1267 allowLocalDnsResolvers =
true;
1277 const std::string arg = optarg;
1278 if (arg ==
"bi" || arg ==
"bidirectional")
1279 defaultKeyDirection = -1;
1280 else if (arg ==
"0")
1281 defaultKeyDirection = 0;
1282 else if (arg ==
"1")
1283 defaultKeyDirection = 1;
1289 dynamicChallengeCookie = optarg;
1298 corruptData =
static_cast<unsigned int>(::atoi(optarg));
1301 appCustomProtocols = optarg;
1304 certcheck_cert_fn = optarg;
1307 certcheck_pkey_fn = optarg;
1310 certcheck_clientca = optarg;
1313 enableLegacyAlgorithms =
true;
1316 write_url_fn = optarg;
1327 std::cout <<
"OpenVPN cli 1.0\n";
1354#ifdef OPENVPN_PLATFORM_WIN
1356 auto argvw = CommandLineToArgvW(GetCommandLineW(), &nargs);
1362 for (
int i = 1; i < argc; ++i)
1364 config.content += argv[i];
1367 config.serverOverride = server;
1368 config.portOverride = port;
1369 config.protoOverride = proto;
1370 config.connTimeout = timeout;
1371 config.compressionMode = compress;
1372 config.allowUnusedAddrFamilies = allowUnusedAddrFamilies;
1373 config.privateKeyPassword = privateKeyPassword;
1374 config.tlsVersionMinOverride = tlsVersionMinOverride;
1375 config.tlsCertProfileOverride = tlsCertProfileOverride;
1376 config.disableClientCert = disableClientCert;
1377 config.proxyHost = proxyHost;
1378 config.proxyPort = proxyPort;
1379 config.proxyUsername = proxyUsername;
1380 config.proxyPassword = proxyPassword;
1381 config.proxyAllowCleartextAuth = proxyAllowCleartextAuth;
1382 config.altProxy = altProxy;
1384 config.generateTunBuilderCaptureEvent = generateTunBuilderCaptureEvent;
1385 config.defaultKeyDirection = defaultKeyDirection;
1386 config.sslDebugLevel = sslDebugLevel;
1387 config.googleDnsFallback = googleDnsFallback;
1388 config.autologinSessions = autologinSessions;
1389 config.retryOnAuthFailed = retryOnAuthFailed;
1390 config.tunPersist = tunPersist;
1392 std::string gremlinConfig = gremlin;
1395 if (gremlinConfig.empty())
1396 gremlinConfig =
"0,0,0,0";
1397 gremlinConfig +=
',';
1398 gremlinConfig += std::to_string(corruptData);
1400 config.gremlinConfig = std::move(gremlinConfig);
1404 config.allowLocalDnsResolvers = allowLocalDnsResolvers;
1405 config.enableLegacyAlgorithms = enableLegacyAlgorithms;
1406 config.enableNonPreferredDCAlgorithms = enableNonPreferredDCO;
1407 config.ssoMethods = ssoMethods;
1408 config.appCustomProtocols = appCustomProtocols;
1409#ifdef OPENVPN_OVPNCLI_SINGLE_THREAD
1410 config.clockTickMS = 250;
1413 if (!epki_cert_fn.empty())
1414 config.externalPkiAlias =
"epki";
1421 if (!
config.serverOverride.empty())
1427 if (
config.serverOverride == se.friendlyName)
1429 config.serverOverride = se.server;
1439 std::cout <<
"EVAL PROFILE\n";
1440 std::cout <<
"error=" << cfg_eval.
error <<
"\n";
1441 std::cout <<
"message=" << cfg_eval.
message <<
"\n";
1443 std::cout <<
"profileName=" << cfg_eval.
profileName <<
"\n";
1444 std::cout <<
"friendlyName=" << cfg_eval.
friendlyName <<
"\n";
1445 std::cout <<
"autologin=" << cfg_eval.
autologin <<
"\n";
1446 std::cout <<
"externalPki=" << cfg_eval.
externalPki <<
"\n";
1452 if (!
config.serverOverride.empty())
1453 std::cout <<
"server=" <<
config.serverOverride <<
"\n";
1455 for (
size_t i = 0; i < cfg_eval.
serverList.size(); ++i)
1464 auto dbus_system = DBus::Connection::Create(DBus::BusType::SYSTEM);
1465 NetCfgTunBuilder<Client> client(dbus_system);
1474 if (!username.empty() || !password.empty())
1475 std::cout <<
"NOTE: creds were not needed\n";
1478 if (!proxyUsername.empty())
1484 if (creds_status.
error)
1490 if (username.empty())
1493 if (password.empty() && dynamicChallengeCookie.empty())
1502 if (creds_status.
error)
1506 client.certcheck_clientca_fn = certcheck_clientca;
1509 if (!epki_cert_fn.empty())
1512 if (!epki_ca_fn.empty())
1514#if defined(USE_MBEDTLS) || defined(USE_OPENSSL)
1515 if (!epki_key_fn.empty())
1520 auto mbedrng = std::make_unique<MbedTLSRandom>();
1521 client.epki_ctx.parse(epki_key_txt,
"EPKI", privateKeyPassword, *mbedrng);
1523 client.epki_pkey.parse_pem(epki_key_txt,
"epki private key",
nullptr);
1532 if (!certcheck_cert_fn.empty())
1535 const std::string epki_key_txt =
read_text_utf8(certcheck_pkey_fn);
1537 client.certcheck_pkey.parse_pem(epki_key_txt,
"certcheck private key",
nullptr);
1539 auto mbedrng = std::make_unique<MbedTLSRandom>();
1540 client.certcheck_pkey.parse(epki_key_txt,
"Certcheck", privateKeyPassword, *mbedrng);
1544#ifdef OPENVPN_REMOTE_OVERRIDE
1545 client.set_remote_override_cmd(remote_override_cmd);
1548 client.set_write_url_fn(write_url_fn);
1550 std::cout <<
"CONNECTING...\n";
1556 if (client.is_dynamic_challenge())
1558 std::cout <<
"ENTER RESPONSE\n";
1559 std::getline(std::cin, response);
1560 if (!response.empty())
1562 dynamicChallengeCookie = client.dynamic_challenge_cookie();
1569 client.print_stats();
1576 if (ERR_peek_error())
1587 catch (
const usage &)
1589 std::cout <<
"OpenVPN Client (ovpncli)\n";
1590 std::cout <<
"usage: cli [options] <config-file> [extra-config-directives...]\n";
1591 std::cout <<
"--version, -v : show version info\n";
1592 std::cout <<
"--eval, -e : evaluate profile only (standalone)\n";
1593 std::cout <<
"--merge, -m : merge profile into unified format (standalone)\n";
1594 std::cout <<
"--username, -u : username\n";
1595 std::cout <<
"--password, -p : password\n";
1596 std::cout <<
"--response, -r : static response\n";
1597 std::cout <<
"--dc, -D : dynamic challenge/response cookie\n";
1598 std::cout <<
"--proto, -P : protocol override (udp|tcp)\n";
1599 std::cout <<
"--server, -s : server override\n";
1600 std::cout <<
"--port, -R : port override\n";
1601#ifdef OPENVPN_REMOTE_OVERRIDE
1602 std::cout <<
"--remote-override : command to run to generate next remote (returning host,ip,port,proto)\n";
1604 std::cout <<
"--allowAF, -6 : Allow unused address families (yes|no|default)\n";
1605 std::cout <<
"--timeout, -t : timeout\n";
1606 std::cout <<
"--compress, -c : compression mode (yes|no|asym)\n";
1607 std::cout <<
"--pk-password, -z : private key password\n";
1608 std::cout <<
"--tvm-override, -M : tls-version-min override (disabled, default, tls_1_x)\n";
1609 std::cout <<
"--legacy-algorithms, -L: Enable legacy algorithm (OpenSSL legacy provider)\n";
1610 std::cout <<
"--non-preferred-algorithms, -Q: Enables non preferred data channel algorithms\n";
1611 std::cout <<
"--tcprof-override, -X : tls-cert-profile override ("
1613#ifdef OPENVPN_ALLOW_INSECURE_CERTPROFILE
1617 "legacy, preferred, etc.)\n";
1618 std::cout <<
"--proxy-host, -h : HTTP proxy hostname/IP\n";
1619 std::cout <<
"--proxy-port, -q : HTTP proxy port\n";
1620 std::cout <<
"--proxy-username, -U : HTTP proxy username\n";
1621 std::cout <<
"--proxy-password, -W : HTTP proxy password\n";
1622 std::cout <<
"--proxy-basic, -B : allow HTTP basic auth\n";
1623 std::cout <<
"--alt-proxy, -A : enable alternative proxy module\n";
1624#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1625 std::cout <<
"--no-dco, -d : disable data channel offload\n";
1627 std::cout <<
"--cache-password, -C : cache password\n";
1628 std::cout <<
"--no-cert, -x : disable client certificate\n";
1629 std::cout <<
"--def-keydir, -k : default key direction ('bi', '0', or '1')\n";
1630 std::cout <<
"--ssl-debug : SSL debug level\n";
1631 std::cout <<
"--google-dns, -g : enable Google DNS fallback\n";
1632 std::cout <<
"--auto-sess, -a : request autologin session\n";
1633 std::cout <<
"--auth-retry, -Y : retry connection on auth failure\n";
1634 std::cout <<
"--persist-tun, -j : keep TUN interface open across reconnects\n";
1635 std::cout <<
"--wintun, -w : use WinTun instead of TAP-Windows6 on Windows\n";
1636 std::cout <<
"--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,... or @kv.json\n";
1637 std::cout <<
"--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob[, send_corrupt_prob])\n";
1638 std::cout <<
"--corrupt-data, -F : 1-in-N probability of bit-flipping outgoing data-channel packets (post-encryption); for testing server decrypt-fail-limit\n";
1639 std::cout <<
"--epki-ca : simulate external PKI cert supporting intermediate/root certs\n";
1640 std::cout <<
"--epki-cert : simulate external PKI cert\n";
1641 std::cout <<
"--epki-key : simulate external PKI private key\n";
1642 std::cout <<
"--sso-methods : auth pending methods to announce via IV_SSO\n";
1643 std::cout <<
"--write-url, -Z : write INFO URL to file\n";
1644 std::cout <<
"--tbc : generate INFO_JSON/TUN_BUILDER_CAPTURE event\n";
1645 std::cout <<
"--app-custom-protocols, -K : ACC protocols to advertise\n";
1646 std::cout <<
"--certcheck-cert, -o : path to certificate PEM for certcheck\n";
1647 std::cout <<
"--certcheck-pkey, -O : path to decrypted pkey PEM for certcheck\n";
1648 std::cout <<
"--certcheck-clientca, -b : path to decrypted pkey PEM for certcheck CA\n";