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 =
"proxy-basic", .has_arg = no_argument, .flag =
nullptr, .val =
'B'},
1047 {.name =
"alt-proxy", .has_arg = no_argument, .flag =
nullptr, .val =
'A'},
1048#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1049 {.name =
"no-dco", .has_arg = no_argument, .flag =
nullptr, .val =
'd'},
1051 {.name =
"eval", .has_arg = no_argument, .flag =
nullptr, .val =
'e'},
1052 {.name =
"self-test", .has_arg = no_argument, .flag =
nullptr, .val =
'T'},
1053 {.name =
"cache-password", .has_arg = no_argument, .flag =
nullptr, .val =
'C'},
1054 {.name =
"no-cert", .has_arg = no_argument, .flag =
nullptr, .val =
'x'},
1055 {.name =
"force-aes-cbc", .has_arg = no_argument, .flag =
nullptr, .val =
'f'},
1056 {.name =
"google-dns", .has_arg = no_argument, .flag =
nullptr, .val =
'g'},
1057 {.name =
"persist-tun", .has_arg = no_argument, .flag =
nullptr, .val =
'j'},
1058 {.name =
"wintun", .has_arg = no_argument, .flag =
nullptr, .val =
'w'},
1059 {.name =
"allow-local-dns-resolvers", .has_arg = no_argument, .flag =
nullptr, .val =
'l'},
1060 {.name =
"def-keydir", .has_arg = required_argument, .flag =
nullptr, .val =
'k'},
1061 {.name =
"merge", .has_arg = no_argument, .flag =
nullptr, .val =
'm'},
1062 {.name =
"version", .has_arg = no_argument, .flag =
nullptr, .val =
'v'},
1063 {.name =
"auto-sess", .has_arg = no_argument, .flag =
nullptr, .val =
'a'},
1064 {.name =
"auth-retry", .has_arg = no_argument, .flag =
nullptr, .val =
'Y'},
1065 {.name =
"tcprof-override", .has_arg = required_argument, .flag =
nullptr, .val =
'X'},
1066 {.name =
"write-url", .has_arg = required_argument, .flag =
nullptr, .val =
'Z'},
1067 {.name =
"sso-methods", .has_arg = required_argument, .flag =
nullptr, .val =
'S'},
1068 {.name =
"ssl-debug", .has_arg = required_argument, .flag =
nullptr, .val = 1 },
1069 {.name =
"epki-cert", .has_arg = required_argument, .flag =
nullptr, .val = 2 },
1070 {.name =
"epki-ca", .has_arg = required_argument, .flag =
nullptr, .val = 3 },
1071 {.name =
"epki-key", .has_arg = required_argument, .flag =
nullptr, .val = 4 },
1072 {.name =
"legacy-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'L'},
1073 {.name =
"non-preferred-algorithms", .has_arg = no_argument, .flag =
nullptr, .val =
'Q'},
1074#ifdef OPENVPN_REMOTE_OVERRIDE
1075 {.name =
"remote-override", .has_arg = required_argument, .flag =
nullptr, .val = 5 },
1077 {.name =
"tbc", .has_arg = no_argument, .flag =
nullptr, .val = 6 },
1078 {.name =
"app-custom-protocols", .has_arg = required_argument, .flag =
nullptr, .val =
'K'},
1079 {.name =
"certcheck-cert", .has_arg = required_argument, .flag =
nullptr, .val =
'o'},
1080 {.name =
"certcheck-pkey", .has_arg = required_argument, .flag =
nullptr, .val =
'O'},
1081 {.name =
"certcheck-clientca", .has_arg = required_argument, .flag =
nullptr, .val =
'b'},
1082 {.name =
nullptr, .has_arg = 0, .flag =
nullptr, .val = 0 }
1094 std::string username;
1095 std::string password;
1096 std::string response;
1097 std::string dynamicChallengeCookie;
1099 std::string allowUnusedAddrFamilies;
1103 std::string compress;
1104 std::string privateKeyPassword;
1105 std::string tlsVersionMinOverride;
1106 std::string tlsCertProfileOverride;
1107 std::string proxyHost;
1108 std::string proxyPort;
1109 std::string proxyUsername;
1110 std::string proxyPassword;
1111 std::string peer_info;
1112 std::string gremlin;
1113 std::string ssoMethods;
1114 std::string appCustomProtocols;
1115 std::string certcheck_cert_fn;
1116 std::string certcheck_pkey_fn;
1117 std::string certcheck_clientca;
1119 bool self_test =
false;
1120 bool disableClientCert =
false;
1121 bool proxyAllowCleartextAuth =
false;
1122 int defaultKeyDirection = -1;
1123 int sslDebugLevel = 0;
1124 bool googleDnsFallback =
false;
1125 bool autologinSessions =
false;
1126 bool retryOnAuthFailed =
false;
1127 bool tunPersist =
false;
1128 bool wintun =
false;
1129 bool allowLocalDnsResolvers =
false;
1130 bool enableLegacyAlgorithms =
false;
1131 bool enableNonPreferredDCO =
false;
1133 bool version =
false;
1134 bool altProxy =
false;
1135#if defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1140 bool generateTunBuilderCaptureEvent =
false;
1141 std::string epki_cert_fn;
1142 std::string epki_ca_fn;
1143 std::string epki_key_fn;
1145#ifdef OPENVPN_REMOTE_OVERRIDE
1146 std::string remote_override_cmd;
1148 std::string write_url_fn;
1153 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)
1158 sslDebugLevel = ::atoi(optarg);
1161 epki_cert_fn = optarg;
1164 epki_ca_fn = optarg;
1167 epki_key_fn = optarg;
1169#ifdef OPENVPN_REMOTE_OVERRIDE
1171 remote_override_cmd = optarg;
1175 generateTunBuilderCaptureEvent =
true;
1184 disableClientCert =
true;
1199 allowUnusedAddrFamilies = optarg;
1208 ssoMethods = optarg;
1211 timeout = ::atoi(optarg);
1217 privateKeyPassword = optarg;
1220 tlsVersionMinOverride = optarg;
1223 tlsCertProfileOverride = optarg;
1232 enableNonPreferredDCO =
true;
1235 proxyUsername = optarg;
1238 proxyPassword = optarg;
1241 proxyAllowCleartextAuth =
true;
1250 googleDnsFallback =
true;
1253 autologinSessions =
true;
1256 retryOnAuthFailed =
true;
1265 allowLocalDnsResolvers =
true;
1275 const std::string arg = optarg;
1276 if (arg ==
"bi" || arg ==
"bidirectional")
1277 defaultKeyDirection = -1;
1278 else if (arg ==
"0")
1279 defaultKeyDirection = 0;
1280 else if (arg ==
"1")
1281 defaultKeyDirection = 1;
1287 dynamicChallengeCookie = optarg;
1296 appCustomProtocols = optarg;
1299 certcheck_cert_fn = optarg;
1302 certcheck_pkey_fn = optarg;
1305 certcheck_clientca = optarg;
1308 enableLegacyAlgorithms =
true;
1311 write_url_fn = optarg;
1322 std::cout <<
"OpenVPN cli 1.0\n";
1349#ifdef OPENVPN_PLATFORM_WIN
1351 auto argvw = CommandLineToArgvW(GetCommandLineW(), &nargs);
1357 for (
int i = 1; i < argc; ++i)
1359 config.content += argv[i];
1362 config.serverOverride = server;
1363 config.portOverride = port;
1364 config.protoOverride = proto;
1365 config.connTimeout = timeout;
1366 config.compressionMode = compress;
1367 config.allowUnusedAddrFamilies = allowUnusedAddrFamilies;
1368 config.privateKeyPassword = privateKeyPassword;
1369 config.tlsVersionMinOverride = tlsVersionMinOverride;
1370 config.tlsCertProfileOverride = tlsCertProfileOverride;
1371 config.disableClientCert = disableClientCert;
1372 config.proxyHost = proxyHost;
1373 config.proxyPort = proxyPort;
1374 config.proxyUsername = proxyUsername;
1375 config.proxyPassword = proxyPassword;
1376 config.proxyAllowCleartextAuth = proxyAllowCleartextAuth;
1377 config.altProxy = altProxy;
1379 config.generateTunBuilderCaptureEvent = generateTunBuilderCaptureEvent;
1380 config.defaultKeyDirection = defaultKeyDirection;
1381 config.sslDebugLevel = sslDebugLevel;
1382 config.googleDnsFallback = googleDnsFallback;
1383 config.autologinSessions = autologinSessions;
1384 config.retryOnAuthFailed = retryOnAuthFailed;
1385 config.tunPersist = tunPersist;
1386 config.gremlinConfig = gremlin;
1389 config.allowLocalDnsResolvers = allowLocalDnsResolvers;
1390 config.enableLegacyAlgorithms = enableLegacyAlgorithms;
1391 config.enableNonPreferredDCAlgorithms = enableNonPreferredDCO;
1392 config.ssoMethods = ssoMethods;
1393 config.appCustomProtocols = appCustomProtocols;
1394#ifdef OPENVPN_OVPNCLI_SINGLE_THREAD
1395 config.clockTickMS = 250;
1398 if (!epki_cert_fn.empty())
1399 config.externalPkiAlias =
"epki";
1406 if (!
config.serverOverride.empty())
1412 if (
config.serverOverride == se.friendlyName)
1414 config.serverOverride = se.server;
1424 std::cout <<
"EVAL PROFILE\n";
1425 std::cout <<
"error=" << cfg_eval.
error <<
"\n";
1426 std::cout <<
"message=" << cfg_eval.
message <<
"\n";
1428 std::cout <<
"profileName=" << cfg_eval.
profileName <<
"\n";
1429 std::cout <<
"friendlyName=" << cfg_eval.
friendlyName <<
"\n";
1430 std::cout <<
"autologin=" << cfg_eval.
autologin <<
"\n";
1431 std::cout <<
"externalPki=" << cfg_eval.
externalPki <<
"\n";
1437 if (!
config.serverOverride.empty())
1438 std::cout <<
"server=" <<
config.serverOverride <<
"\n";
1440 for (
size_t i = 0; i < cfg_eval.
serverList.size(); ++i)
1449 auto dbus_system = DBus::Connection::Create(DBus::BusType::SYSTEM);
1450 NetCfgTunBuilder<Client> client(dbus_system);
1459 if (!username.empty() || !password.empty())
1460 std::cout <<
"NOTE: creds were not needed\n";
1463 if (!proxyUsername.empty())
1469 if (creds_status.
error)
1475 if (username.empty())
1478 if (password.empty() && dynamicChallengeCookie.empty())
1487 if (creds_status.
error)
1491 client.certcheck_clientca_fn = certcheck_clientca;
1494 if (!epki_cert_fn.empty())
1497 if (!epki_ca_fn.empty())
1499#if defined(USE_MBEDTLS) || defined(USE_OPENSSL)
1500 if (!epki_key_fn.empty())
1505 auto mbedrng = std::make_unique<MbedTLSRandom>();
1506 client.epki_ctx.parse(epki_key_txt,
"EPKI", privateKeyPassword, *mbedrng);
1508 client.epki_pkey.parse_pem(epki_key_txt,
"epki private key",
nullptr);
1517 if (!certcheck_cert_fn.empty())
1520 const std::string epki_key_txt =
read_text_utf8(certcheck_pkey_fn);
1522 client.certcheck_pkey.parse_pem(epki_key_txt,
"certcheck private key",
nullptr);
1524 auto mbedrng = std::make_unique<MbedTLSRandom>();
1525 client.certcheck_pkey.parse(epki_key_txt,
"Certcheck", privateKeyPassword, *mbedrng);
1529#ifdef OPENVPN_REMOTE_OVERRIDE
1530 client.set_remote_override_cmd(remote_override_cmd);
1533 client.set_write_url_fn(write_url_fn);
1535 std::cout <<
"CONNECTING...\n";
1541 if (client.is_dynamic_challenge())
1543 std::cout <<
"ENTER RESPONSE\n";
1544 std::getline(std::cin, response);
1545 if (!response.empty())
1547 dynamicChallengeCookie = client.dynamic_challenge_cookie();
1554 client.print_stats();
1561 if (ERR_peek_error())
1572 catch (
const usage &)
1574 std::cout <<
"OpenVPN Client (ovpncli)\n";
1575 std::cout <<
"usage: cli [options] <config-file> [extra-config-directives...]\n";
1576 std::cout <<
"--version, -v : show version info\n";
1577 std::cout <<
"--eval, -e : evaluate profile only (standalone)\n";
1578 std::cout <<
"--merge, -m : merge profile into unified format (standalone)\n";
1579 std::cout <<
"--username, -u : username\n";
1580 std::cout <<
"--password, -p : password\n";
1581 std::cout <<
"--response, -r : static response\n";
1582 std::cout <<
"--dc, -D : dynamic challenge/response cookie\n";
1583 std::cout <<
"--proto, -P : protocol override (udp|tcp)\n";
1584 std::cout <<
"--server, -s : server override\n";
1585 std::cout <<
"--port, -R : port override\n";
1586#ifdef OPENVPN_REMOTE_OVERRIDE
1587 std::cout <<
"--remote-override : command to run to generate next remote (returning host,ip,port,proto)\n";
1589 std::cout <<
"--allowAF, -6 : Allow unused address families (yes|no|default)\n";
1590 std::cout <<
"--timeout, -t : timeout\n";
1591 std::cout <<
"--compress, -c : compression mode (yes|no|asym)\n";
1592 std::cout <<
"--pk-password, -z : private key password\n";
1593 std::cout <<
"--tvm-override, -M : tls-version-min override (disabled, default, tls_1_x)\n";
1594 std::cout <<
"--legacy-algorithms, -L: Enable legacy algorithm (OpenSSL legacy provider)\n";
1595 std::cout <<
"--non-preferred-algorithms, -Q: Enables non preferred data channel algorithms\n";
1596 std::cout <<
"--tcprof-override, -X : tls-cert-profile override ("
1598#ifdef OPENVPN_ALLOW_INSECURE_CERTPROFILE
1602 "legacy, preferred, etc.)\n";
1603 std::cout <<
"--proxy-host, -h : HTTP proxy hostname/IP\n";
1604 std::cout <<
"--proxy-port, -q : HTTP proxy port\n";
1605 std::cout <<
"--proxy-username, -U : HTTP proxy username\n";
1606 std::cout <<
"--proxy-password, -W : HTTP proxy password\n";
1607 std::cout <<
"--proxy-basic, -B : allow HTTP basic auth\n";
1608 std::cout <<
"--alt-proxy, -A : enable alternative proxy module\n";
1609#if defined(ENABLE_KOVPN) || defined(ENABLE_OVPNDCO) || defined(ENABLE_OVPNDCOWIN)
1610 std::cout <<
"--no-dco, -d : disable data channel offload\n";
1612 std::cout <<
"--cache-password, -C : cache password\n";
1613 std::cout <<
"--no-cert, -x : disable client certificate\n";
1614 std::cout <<
"--def-keydir, -k : default key direction ('bi', '0', or '1')\n";
1615 std::cout <<
"--ssl-debug : SSL debug level\n";
1616 std::cout <<
"--google-dns, -g : enable Google DNS fallback\n";
1617 std::cout <<
"--auto-sess, -a : request autologin session\n";
1618 std::cout <<
"--auth-retry, -Y : retry connection on auth failure\n";
1619 std::cout <<
"--persist-tun, -j : keep TUN interface open across reconnects\n";
1620 std::cout <<
"--wintun, -w : use WinTun instead of TAP-Windows6 on Windows\n";
1621 std::cout <<
"--peer-info, -I : peer info key/value list in the form K1=V1,K2=V2,... or @kv.json\n";
1622 std::cout <<
"--gremlin, -G : gremlin info (send_delay_ms, recv_delay_ms, send_drop_prob, recv_drop_prob)\n";
1623 std::cout <<
"--epki-ca : simulate external PKI cert supporting intermediate/root certs\n";
1624 std::cout <<
"--epki-cert : simulate external PKI cert\n";
1625 std::cout <<
"--epki-key : simulate external PKI private key\n";
1626 std::cout <<
"--sso-methods : auth pending methods to announce via IV_SSO\n";
1627 std::cout <<
"--write-url, -Z : write INFO URL to file\n";
1628 std::cout <<
"--tbc : generate INFO_JSON/TUN_BUILDER_CAPTURE event\n";
1629 std::cout <<
"--app-custom-protocols, -K : ACC protocols to advertise\n";
1630 std::cout <<
"--certcheck-cert, -o : path to certificate PEM for certcheck\n";
1631 std::cout <<
"--certcheck-pkey, -O : path to decrypted pkey PEM for certcheck\n";
1632 std::cout <<
"--certcheck-clientca, -b : path to decrypted pkey PEM for certcheck CA\n";