1023 static const struct option longopts[] = {
1024 {.name =
"username", .has_arg = required_argument, .flag =
nullptr, .val =
'u'},
1025 {.name =
"password", .has_arg = required_argument, .flag =
nullptr, .val =
'p'},
1026 {.name =
"response", .has_arg = required_argument, .flag =
nullptr, .val =
'r'},
1027 {.name =
"dc", .has_arg = required_argument, .flag =
nullptr, .val =
'D'},
1028 {.name =
"proto", .has_arg = required_argument, .flag =
nullptr, .val =
'P'},
1029 {.name =
"ipv6", .has_arg = required_argument, .flag =
nullptr, .val =
'6'},
1030 {.name =
"server", .has_arg = required_argument, .flag =
nullptr, .val =
's'},
1031 {.name =
"port", .has_arg = required_argument, .flag =
nullptr, .val =
'R'},
1032 {.name =
"timeout", .has_arg = required_argument, .flag =
nullptr, .val =
't'},
1033 {.name =
"compress", .has_arg = required_argument, .flag =
nullptr, .val =
'c'},
1034 {.name =
"pk-password", .has_arg = required_argument, .flag =
nullptr, .val =
'z'},
1035 {.name =
"tvm-override", .has_arg = required_argument, .flag =
nullptr, .val =
'M'},
1036 {.name =
"proxy-host", .has_arg = required_argument, .flag =
nullptr, .val =
'h'},
1037 {.name =
"proxy-port", .has_arg = required_argument, .flag =
nullptr, .val =
'q'},
1038 {.name =
"proxy-username", .has_arg = required_argument, .flag =
nullptr, .val =
'U'},
1039 {.name =
"proxy-password", .has_arg = required_argument, .flag =
nullptr, .val =
'W'},
1040 {.name =
"peer-info", .has_arg = required_argument, .flag =
nullptr, .val =
'I'},
1041 {.name =
"acc-protos", .has_arg = required_argument, .flag =
nullptr, .val =
'K'},
1042 {.name =
"gremlin", .has_arg = required_argument, .flag =
nullptr, .val =
'G'},
1043 {.name =
"proxy-basic", .has_arg = no_argument, .flag =
nullptr, .val =
'B'},
1044 {.name =
"alt-proxy", .has_arg = no_argument, .flag =
nullptr, .val =
'A'},
1045#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1046 {.name =
"no-dco", .has_arg = no_argument, .flag =
nullptr, .val =
'd'},
1048 {.name =
"eval", .has_arg = no_argument, .flag =
nullptr, .val =
'e'},
1049 {.name =
"self-test", .has_arg = no_argument, .flag =
nullptr, .val =
'T'},
1050 {.name =
"cache-password", .has_arg = no_argument, .flag =
nullptr, .val =
'C'},
1051 {.name =
"no-cert", .has_arg = no_argument, .flag =
nullptr, .val =
'x'},
1052 {.name =
"force-aes-cbc", .has_arg = no_argument, .flag =
nullptr, .val =
'f'},
1053 {.name =
"google-dns", .has_arg = no_argument, .flag =
nullptr, .val =
'g'},
1054 {.name =
"persist-tun", .has_arg = no_argument, .flag =
nullptr, .val =
'j'},
1055 {.name =
"wintun", .has_arg = no_argument, .flag =
nullptr, .val =
'w'},
1056 {.name =
"allow-local-dns-resolvers", .has_arg = no_argument, .flag =
nullptr, .val =
'l'},
1057 {.name =
"def-keydir", .has_arg = required_argument, .flag =
nullptr, .val =
'k'},
1058 {.name =
"merge", .has_arg = no_argument, .flag =
nullptr, .val =
'm'},
1059 {.name =
"version", .has_arg = no_argument, .flag =
nullptr, .val =
'v'},
1060 {.name =
"auto-sess", .has_arg = no_argument, .flag =
nullptr, .val =
'a'},
1061 {.name =
"auth-retry", .has_arg = no_argument, .flag =
nullptr, .val =
'Y'},
1062 {.name =
"tcprof-override", .has_arg = required_argument, .flag =
nullptr, .val =
'X'},
1063 {.name =
"write-url", .has_arg = required_argument, .flag =
nullptr, .val =
'Z'},
1064 {.name =
"sso-methods", .has_arg = required_argument, .flag =
nullptr, .val =
'S'},
1065 {.name =
"ssl-debug", .has_arg = required_argument, .flag =
nullptr, .val = 1 },
1066 {.name =
"epki-cert", .has_arg = required_argument, .flag =
nullptr, .val = 2 },
1067 {.name =
"epki-ca", .has_arg = required_argument, .flag =
nullptr, .val = 3 },
1068 {.name =
"epki-key", .has_arg = required_argument, .flag =
nullptr, .val = 4 },
1069 {.name =
"legacy-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'L'},
1070 {.name =
"non-preferred-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'Q'},
1071#ifdef OPENVPN_REMOTE_OVERRIDE
1072 {.name =
"remote-override", .has_arg = required_argument, .flag =
nullptr, .val = 5 },
1074 {.name =
"tbc", .has_arg = no_argument, .flag =
nullptr, .val = 6 },
1075 {.name =
"app-custom-protocols", .has_arg = required_argument, .flag =
nullptr, .val =
'K'},
1076 {.name =
"certcheck-cert", .has_arg = required_argument, .flag =
nullptr, .val =
'o'},
1077 {.name =
"certcheck-pkey", .has_arg = required_argument, .flag =
nullptr, .val =
'O'},
1078 {.name =
"certcheck-clientca", .has_arg = required_argument, .flag =
nullptr, .val =
'b'},
1079 {.name =
nullptr, .has_arg = 0, .flag =
nullptr, .val = 0 }
1091 std::string username;
1092 std::string password;
1093 std::string response;
1094 std::string dynamicChallengeCookie;
1096 std::string allowUnusedAddrFamilies;
1100 std::string compress;
1101 std::string privateKeyPassword;
1102 std::string tlsVersionMinOverride;
1103 std::string tlsCertProfileOverride;
1104 std::string proxyHost;
1105 std::string proxyPort;
1106 std::string proxyUsername;
1107 std::string proxyPassword;
1108 std::string peer_info;
1109 std::string gremlin;
1110 std::string ssoMethods;
1111 std::string appCustomProtocols;
1112 std::string certcheck_cert_fn;
1113 std::string certcheck_pkey_fn;
1114 std::string certcheck_clientca;
1116 bool self_test =
false;
1117 bool disableClientCert =
false;
1118 bool proxyAllowCleartextAuth =
false;
1119 int defaultKeyDirection = -1;
1120 int sslDebugLevel = 0;
1121 bool googleDnsFallback =
false;
1122 bool autologinSessions =
false;
1123 bool retryOnAuthFailed =
false;
1124 bool tunPersist =
false;
1125 bool wintun =
false;
1126 bool allowLocalDnsResolvers =
false;
1127 bool enableLegacyAlgorithms =
false;
1128 bool enableNonPreferredDCO =
false;
1130 bool version =
false;
1131 bool altProxy =
false;
1132#if defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1137 bool generateTunBuilderCaptureEvent =
false;
1138 std::string epki_cert_fn;
1139 std::string epki_ca_fn;
1140 std::string epki_key_fn;
1142#ifdef OPENVPN_REMOTE_OVERRIDE
1143 std::string remote_override_cmd;
1145 std::string write_url_fn;
1150 while ((ch = getopt_long(argc, argv,
"6:ABCD: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)
1155 sslDebugLevel = ::atoi(optarg);
1158 epki_cert_fn = optarg;
1161 epki_ca_fn = optarg;
1164 epki_key_fn = optarg;
1166#ifdef OPENVPN_REMOTE_OVERRIDE
1168 remote_override_cmd = optarg;
1172 generateTunBuilderCaptureEvent =
true;
1181 disableClientCert =
true;
1196 allowUnusedAddrFamilies = optarg;
1205 ssoMethods = optarg;
1208 timeout = ::atoi(optarg);
1214 privateKeyPassword = optarg;
1217 tlsVersionMinOverride = optarg;
1220 tlsCertProfileOverride = optarg;
1229 enableNonPreferredDCO =
true;
1232 proxyUsername = optarg;
1235 proxyPassword = optarg;
1238 proxyAllowCleartextAuth =
true;
1247 googleDnsFallback =
true;
1250 autologinSessions =
true;
1253 retryOnAuthFailed =
true;
1262 allowLocalDnsResolvers =
true;
1272 const std::string arg = optarg;
1273 if (arg ==
"bi" || arg ==
"bidirectional")
1274 defaultKeyDirection = -1;
1275 else if (arg ==
"0")
1276 defaultKeyDirection = 0;
1277 else if (arg ==
"1")
1278 defaultKeyDirection = 1;
1284 dynamicChallengeCookie = optarg;
1293 appCustomProtocols = optarg;
1296 certcheck_cert_fn = optarg;
1299 certcheck_pkey_fn = optarg;
1302 certcheck_clientca = optarg;
1305 enableLegacyAlgorithms =
true;
1308 write_url_fn = optarg;
1319 std::cout <<
"OpenVPN cli 1.0\n";
1346#ifdef OPENVPN_PLATFORM_WIN
1348 auto argvw = CommandLineToArgvW(GetCommandLineW(), &nargs);
1354 for (
int i = 1; i < argc; ++i)
1356 config.content += argv[i];
1359 config.serverOverride = server;
1361 config.protoOverride = proto;
1362 config.connTimeout = timeout;
1363 config.compressionMode = compress;
1364 config.allowUnusedAddrFamilies = allowUnusedAddrFamilies;
1365 config.privateKeyPassword = privateKeyPassword;
1366 config.tlsVersionMinOverride = tlsVersionMinOverride;
1367 config.tlsCertProfileOverride = tlsCertProfileOverride;
1368 config.disableClientCert = disableClientCert;
1369 config.proxyHost = proxyHost;
1370 config.proxyPort = proxyPort;
1371 config.proxyUsername = proxyUsername;
1372 config.proxyPassword = proxyPassword;
1373 config.proxyAllowCleartextAuth = proxyAllowCleartextAuth;
1374 config.altProxy = altProxy;
1376 config.generateTunBuilderCaptureEvent = generateTunBuilderCaptureEvent;
1377 config.defaultKeyDirection = defaultKeyDirection;
1378 config.sslDebugLevel = sslDebugLevel;
1379 config.googleDnsFallback = googleDnsFallback;
1380 config.autologinSessions = autologinSessions;
1381 config.retryOnAuthFailed = retryOnAuthFailed;
1382 config.tunPersist = tunPersist;
1383 config.gremlinConfig = gremlin;
1386 config.allowLocalDnsResolvers = allowLocalDnsResolvers;
1387 config.enableLegacyAlgorithms = enableLegacyAlgorithms;
1388 config.enableNonPreferredDCAlgorithms = enableNonPreferredDCO;
1389 config.ssoMethods = ssoMethods;
1390 config.appCustomProtocols = appCustomProtocols;
1391#ifdef OPENVPN_OVPNCLI_SINGLE_THREAD
1392 config.clockTickMS = 250;
1395 if (!epki_cert_fn.empty())
1396 config.externalPkiAlias =
"epki";
1403 if (!
config.serverOverride.empty())
1409 if (
config.serverOverride == se.friendlyName)
1411 config.serverOverride = se.server;
1421 std::cout <<
"EVAL PROFILE\n";
1422 std::cout <<
"error=" << cfg_eval.
error <<
"\n";
1423 std::cout <<
"message=" << cfg_eval.
message <<
"\n";
1425 std::cout <<
"profileName=" << cfg_eval.
profileName <<
"\n";
1426 std::cout <<
"friendlyName=" << cfg_eval.
friendlyName <<
"\n";
1427 std::cout <<
"autologin=" << cfg_eval.
autologin <<
"\n";
1428 std::cout <<
"externalPki=" << cfg_eval.
externalPki <<
"\n";
1434 if (!
config.serverOverride.empty())
1435 std::cout <<
"server=" <<
config.serverOverride <<
"\n";
1437 for (
size_t i = 0; i < cfg_eval.
serverList.size(); ++i)
1446 auto dbus_system = DBus::Connection::Create(DBus::BusType::SYSTEM);
1447 NetCfgTunBuilder<Client> client(dbus_system);
1456 if (!username.empty() || !password.empty())
1457 std::cout <<
"NOTE: creds were not needed\n";
1460 if (!proxyUsername.empty())
1466 if (creds_status.
error)
1472 if (username.empty())
1475 if (password.empty() && dynamicChallengeCookie.empty())
1484 if (creds_status.
error)
1488 client.certcheck_clientca_fn = certcheck_clientca;
1491 if (!epki_cert_fn.empty())
1494 if (!epki_ca_fn.empty())
1496#if defined(USE_MBEDTLS) || defined(USE_OPENSSL)
1497 if (!epki_key_fn.empty())
1502 auto mbedrng = std::make_unique<MbedTLSRandom>();
1503 client.epki_ctx.parse(epki_key_txt,
"EPKI", privateKeyPassword, *mbedrng);
1505 client.epki_pkey.parse_pem(epki_key_txt,
"epki private key",
nullptr);
1514 if (!certcheck_cert_fn.empty())
1517 const std::string epki_key_txt =
read_text_utf8(certcheck_pkey_fn);
1519 client.certcheck_pkey.parse_pem(epki_key_txt,
"certcheck private key",
nullptr);
1521 auto mbedrng = std::make_unique<MbedTLSRandom>();
1522 client.certcheck_pkey.parse(epki_key_txt,
"Certcheck", privateKeyPassword, *mbedrng);
1526#ifdef OPENVPN_REMOTE_OVERRIDE
1527 client.set_remote_override_cmd(remote_override_cmd);
1530 client.set_write_url_fn(write_url_fn);
1532 std::cout <<
"CONNECTING...\n";
1538 if (client.is_dynamic_challenge())
1540 std::cout <<
"ENTER RESPONSE\n";
1541 std::getline(std::cin, response);
1542 if (!response.empty())
1544 dynamicChallengeCookie = client.dynamic_challenge_cookie();
1551 client.print_stats();
1558 if (ERR_peek_error())
1569 catch (
const usage &)
1571 std::cout <<
"OpenVPN Client (ovpncli)\n";
1572 std::cout <<
"usage: cli [options] <config-file> [extra-config-directives...]\n";
1573 std::cout <<
"--version, -v : show version info\n";
1574 std::cout <<
"--eval, -e : evaluate profile only (standalone)\n";
1575 std::cout <<
"--merge, -m : merge profile into unified format (standalone)\n";
1576 std::cout <<
"--username, -u : username\n";
1577 std::cout <<
"--password, -p : password\n";
1578 std::cout <<
"--response, -r : static response\n";
1579 std::cout <<
"--dc, -D : dynamic challenge/response cookie\n";
1580 std::cout <<
"--proto, -P : protocol override (udp|tcp)\n";
1581 std::cout <<
"--server, -s : server override\n";
1582 std::cout <<
"--port, -R : port override\n";
1583#ifdef OPENVPN_REMOTE_OVERRIDE
1584 std::cout <<
"--remote-override : command to run to generate next remote (returning host,ip,port,proto)\n";
1586 std::cout <<
"--allowAF, -6 : Allow unused address families (yes|no|default)\n";
1587 std::cout <<
"--timeout, -t : timeout\n";
1588 std::cout <<
"--compress, -c : compression mode (yes|no|asym)\n";
1589 std::cout <<
"--pk-password, -z : private key password\n";
1590 std::cout <<
"--tvm-override, -M : tls-version-min override (disabled, default, tls_1_x)\n";
1591 std::cout <<
"--legacy-algorithms, -L: Enable legacy algorithm (OpenSSL legacy provider)\n";
1592 std::cout <<
"--non-preferred-algorithms, -Q: Enables non preferred data channel algorithms\n";
1593 std::cout <<
"--tcprof-override, -X : tls-cert-profile override ("
1595#ifdef OPENVPN_ALLOW_INSECURE_CERTPROFILE
1599 "legacy, preferred, etc.)\n";
1600 std::cout <<
"--proxy-host, -h : HTTP proxy hostname/IP\n";
1601 std::cout <<
"--proxy-port, -q : HTTP proxy port\n";
1602 std::cout <<
"--proxy-username, -U : HTTP proxy username\n";
1603 std::cout <<
"--proxy-password, -W : HTTP proxy password\n";
1604 std::cout <<
"--proxy-basic, -B : allow HTTP basic auth\n";
1605 std::cout <<
"--alt-proxy, -A : enable alternative proxy module\n";
1606#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1607 std::cout <<
"--no-dco, -d : disable data channel offload\n";
1609 std::cout <<
"--cache-password, -C : cache password\n";
1610 std::cout <<
"--no-cert, -x : disable client certificate\n";
1611 std::cout <<
"--def-keydir, -k : default key direction ('bi', '0', or '1')\n";
1612 std::cout <<
"--ssl-debug : SSL debug level\n";
1613 std::cout <<
"--google-dns, -g : enable Google DNS fallback\n";
1614 std::cout <<
"--auto-sess, -a : request autologin session\n";
1615 std::cout <<
"--auth-retry, -Y : retry connection on auth failure\n";
1616 std::cout <<
"--persist-tun, -j : keep TUN interface open across reconnects\n";
1617 std::cout <<
"--wintun, -w : use WinTun instead of TAP-Windows6 on Windows\n";
1618 std::cout <<
"--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,... or @kv.json\n";
1619 std::cout <<
"--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob)\n";
1620 std::cout <<
"--epki-ca : simulate external PKI cert supporting intermediate/root certs\n";
1621 std::cout <<
"--epki-cert : simulate external PKI cert\n";
1622 std::cout <<
"--epki-key : simulate external PKI private key\n";
1623 std::cout <<
"--sso-methods : auth pending methods to announce via IV_SSO\n";
1624 std::cout <<
"--write-url, -Z : write INFO URL to file\n";
1625 std::cout <<
"--tbc : generate INFO_JSON/TUN_BUILDER_CAPTURE event\n";
1626 std::cout <<
"--app-custom-protocols, -K : ACC protocols to advertise\n";
1627 std::cout <<
"--certcheck-cert, -o : path to certificate PEM for certcheck\n";
1628 std::cout <<
"--certcheck-pkey, -O : path to decrypted pkey PEM for certcheck\n";
1629 std::cout <<
"--certcheck-clientca, -b : path to decrypted pkey PEM for certcheck CA\n";