#define BUFSIZZ 1024*8
#define S_CLIENT_IRC_READ_TIMEOUT 8
-extern int verify_depth;
-extern int verify_error;
-extern int verify_return_error;
-extern int verify_quiet;
-
static char *prog;
-static int c_nbio = 0;
-static int c_tlsextdebug = 0;
-static int c_status_req = 0;
static int c_debug = 0;
-static int c_msg = 0;
static int c_showcerts = 0;
static char *keymatexportlabel = NULL;
static int keymatexportlen = 20;
static BIO *bio_c_out = NULL;
-static BIO *bio_c_msg = NULL;
static int c_quiet = 0;
-static int c_ign_eof = 0;
-static int c_brief = 0;
static void print_stuff(BIO *berr, SSL *con, int full);
#ifndef OPENSSL_NO_OCSP
} while (ret < 0);
}
-
#ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */
static char *psk_identity = "Client_identity";
BIGNUM *r = BN_new();
int ret =
g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
- BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 &&
p != NULL && BN_rshift1(p, N) &&
/* p = (N-1)/2 */
- BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) &&
+ BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 &&
r != NULL &&
/* verify g^((N-1)/2) == -1 (mod N) */
BN_mod_exp(r, g, p, N, bn_ctx) &&
{
unsigned char **out = (unsigned char **)result;
const char *in = *inptr;
- unsigned char *ret = app_malloc(strlen(in)/2, "hexdecode");
+ unsigned char *ret = app_malloc(strlen(in) / 2, "hexdecode");
unsigned char *cp = ret;
uint8_t byte;
int nibble = 0;
OPT_SSL3, OPT_SSL_CONFIG,
OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
- OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
+ OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH,
+ OPT_VERIFYCAPATH,
OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE,
OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
#ifndef OPENSSL_NO_CT
OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
#endif
- OPT_DANE_TLSA_RRDATA
+ OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME
} OPTION_CHOICE;
-OPTIONS s_client_options[] = {
+const OPTIONS s_client_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"host", OPT_HOST, 's', "Use -connect instead"},
{"port", OPT_PORT, 'p', "Use -connect instead"},
{"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"},
{"certform", OPT_CERTFORM, 'F',
"Certificate format (PEM or DER) PEM default"},
- {"key", OPT_KEY, '<', "Private key file to use, if not in -cert file"},
- {"keyform", OPT_KEYFORM, 'F', "Key format (PEM or DER) PEM default"},
+ {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"},
+ {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"},
{"pass", OPT_PASS, 's', "Private key file pass phrase source"},
{"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
{"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
{"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
{"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's',
"DANE TLSA rrdata presentation form"},
+ {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-',
+ "Disable name checks when matching DANE-EE(3) TLSA records"},
{"reconnect", OPT_RECONNECT, '-',
"Drop and re-make the connection with the same Session-ID"},
{"showcerts", OPT_SHOWCERTS, '-', "Show all certificates in the chain"},
PROTO_XMPP,
PROTO_XMPP_SERVER,
PROTO_CONNECT,
- PROTO_IRC
+ PROTO_IRC,
+ PROTO_POSTGRES
} PROTOCOL_CHOICE;
static const OPT_PAIR services[] = {
{"xmpp-server", PROTO_XMPP_SERVER},
{"telnet", PROTO_TELNET},
{"irc", PROTO_IRC},
+ {"postgres", PROTO_POSTGRES},
{NULL, 0}
};
(o == OPT_4 || o == OPT_6 || o == OPT_HOST || o == OPT_PORT || o == OPT_CONNECT)
#define IS_UNIX_FLAG(o) (o == OPT_UNIX)
+#define IS_PROT_FLAG(o) \
+ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
+ || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
+
/* Free |*dest| and optionally set it to a copy of |source|. */
static void freeandcopy(char **dest, const char *source)
{
STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
char *dane_tlsa_domain = NULL;
STACK_OF(OPENSSL_STRING) *dane_tlsa_rrset = NULL;
+ int dane_ee_no_name = 0;
STACK_OF(X509_CRL) *crls = NULL;
const SSL_METHOD *meth = TLS_client_method();
- char *CApath = NULL, *CAfile = NULL, *cbuf = NULL, *sbuf = NULL;
+ const char *CApath = NULL, *CAfile = NULL;
+ char *cbuf = NULL, *sbuf = NULL;
char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL;
char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
int at_eof = 0;
+#endif
int read_buf_len = 0;
int fallback_scsv = 0;
long randamt = 0;
char *ctlog_file = NULL;
int ct_validation = 0;
#endif
- int min_version = 0, max_version = 0;
+ int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int async = 0;
unsigned int split_send_fragment = 0;
unsigned int max_pipelines = 0;
enum { use_inet, use_unix, use_unknown } connect_type = use_unknown;
int count4or6 = 0;
+ int c_nbio = 0, c_msg = 0, c_ign_eof = 0, c_brief = 0;
+ int c_tlsextdebug = 0;
+#ifndef OPENSSL_NO_OCSP
+ int c_status_req = 0;
+#endif
+ BIO *bio_c_msg = NULL;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
prog = opt_progname(argv[0]);
c_quiet = 0;
- c_ign_eof = 0;
c_debug = 0;
- c_msg = 0;
c_showcerts = 0;
c_nbio = 0;
- verify_depth = 0;
- verify_error = X509_V_OK;
vpm = X509_VERIFY_PARAM_new();
- cbuf = app_malloc(BUFSIZZ, "cbuf");
- sbuf = app_malloc(BUFSIZZ, "sbuf");
- mbuf = app_malloc(BUFSIZZ, "mbuf");
cctx = SSL_CONF_CTX_new();
if (vpm == NULL || cctx == NULL) {
goto end;
}
+ cbuf = app_malloc(BUFSIZZ, "cbuf");
+ sbuf = app_malloc(BUFSIZZ, "sbuf");
+ mbuf = app_malloc(BUFSIZZ, "mbuf");
+
SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CMDLINE);
prog = opt_init(argc, argv, s_client_options);
/* Check for intermixing flags. */
if (connect_type == use_unix && IS_INET_FLAG(o)) {
BIO_printf(bio_err,
- "%s: Intermixed protocol flags (unix and internet domains)\n",
- prog);
+ "%s: Intermixed protocol flags (unix and internet domains)\n",
+ prog);
goto end;
}
if (connect_type == use_inet && IS_UNIX_FLAG(o)) {
BIO_printf(bio_err,
- "%s: Intermixed protocol flags (internet and unix domains)\n",
- prog);
+ "%s: Intermixed protocol flags (internet and unix domains)\n",
+ prog);
+ goto end;
+ }
+
+ if (IS_PROT_FLAG(o) && ++prot_opt > 1) {
+ BIO_printf(bio_err, "Cannot supply multiple protocol flags\n");
+ goto end;
+ }
+ if (IS_NO_PROT_FLAG(o))
+ no_prot_opt++;
+ if (prot_opt == 1 && no_prot_opt) {
+ BIO_printf(bio_err,
+ "Cannot supply both a protocol flag and '-no_<prot>'\n");
goto end;
}
+
switch (o) {
case OPT_EOF:
case OPT_ERR:
break;
case OPT_VERIFY:
verify = SSL_VERIFY_PEER;
- verify_depth = atoi(opt_arg());
+ verify_args.depth = atoi(opt_arg());
if (!c_quiet)
- BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
+ BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth);
break;
case OPT_CERT:
cert_file = opt_arg();
goto opthelp;
break;
case OPT_VERIFY_RET_ERROR:
- verify_return_error = 1;
+ verify_args.return_error = 1;
break;
case OPT_VERIFY_QUIET:
- verify_quiet = 1;
+ verify_args.quiet = 1;
break;
case OPT_BRIEF:
- c_brief = verify_quiet = c_quiet = 1;
+ c_brief = verify_args.quiet = c_quiet = 1;
break;
case OPT_S_CASES:
if (ssl_args == NULL)
c_tlsextdebug = 1;
break;
case OPT_STATUS:
+#ifndef OPENSSL_NO_OCSP
c_status_req = 1;
+#endif
break;
case OPT_WDEBUG:
#ifdef WATT32
fallback_scsv = 1;
break;
case OPT_KEYFORM:
- if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &key_format))
+ if (!opt_format(opt_arg(), OPT_FMT_PDE, &key_format))
goto opthelp;
break;
case OPT_PASS:
goto end;
}
break;
+ case OPT_DANE_EE_NO_NAME:
+ dane_ee_no_name = 1;
+ break;
case OPT_NEXTPROTONEG:
#ifndef OPENSSL_NO_NEXTPROTONEG
next_proto_neg_in = opt_arg();
if (tmp_port != port)
OPENSSL_free(tmp_port);
if (!res) {
- BIO_printf(bio_err, "%s: -proxy argument malformed or ambiguous\n",
- prog);
+ BIO_printf(bio_err,
+ "%s: -proxy argument malformed or ambiguous\n", prog);
goto end;
}
} else {
if (SSL_CTX_config(ctx, ssl_config) == 0) {
BIO_printf(bio_err, "Error using configuration \"%s\"\n",
ssl_config);
- ERR_print_errors(bio_err);
- goto end;
+ ERR_print_errors(bio_err);
+ goto end;
}
}
#ifndef OPENSSL_NO_PSK
if (psk_key != NULL) {
if (c_debug)
- BIO_printf(bio_c_out,
- "PSK key given, setting client callback\n");
+ BIO_printf(bio_c_out, "PSK key given, setting client callback\n");
SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
}
#endif
}
/* Returns 0 on success! */
if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0) {
- BIO_printf(bio_err, "Error setting ALPN\n");
+ BIO_printf(bio_err, "Error setting ALPN\n");
goto end;
}
OPENSSL_free(alpn);
NULL, NULL, NULL,
serverinfo_cli_parse_cb, NULL)) {
BIO_printf(bio_err,
- "Warning: Unable to add custom extension %u, skipping\n",
- serverinfo_types[i]);
+ "Warning: Unable to add custom extension %u, skipping\n",
+ serverinfo_types[i]);
}
}
if (dane_tlsa_domain != NULL) {
if (SSL_CTX_dane_enable(ctx) <= 0) {
BIO_printf(bio_err,
- "%s: Error enabling DANE TLSA authentication.\n", prog);
+ "%s: Error enabling DANE TLSA authentication.\n",
+ prog);
ERR_print_errors(bio_err);
goto end;
}
}
if (dane_tlsa_rrset == NULL) {
BIO_printf(bio_err, "%s: DANE TLSA authentication requires at "
- "least one -dane_tlsa_rrset option.\n", prog);
+ "least one -dane_tlsa_rrdata option.\n", prog);
goto end;
}
if (tlsa_import_rrset(con, dane_tlsa_rrset) <= 0) {
"records.\n", prog);
goto end;
}
+ if (dane_ee_no_name)
+ SSL_dane_set_flags(con, DANE_FLAG_NO_DANE_EE_NAMECHECKS);
} else if (dane_tlsa_rrset != NULL) {
BIO_printf(bio_err, "%s: DANE TLSA authentication requires the "
"-dane_tlsa_domain option.\n", prog);
}
re_start:
- if (init_client(&s, host, port, socket_family, socket_type) == 0)
- {
+ if (init_client(&s, host, port, socket_family, socket_type) == 0) {
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
BIO_closesocket(s);
goto end;
}
#ifndef OPENSSL_NO_DTLS
if (socket_type == SOCK_DGRAM) {
- struct sockaddr peer;
- int peerlen = sizeof peer;
+ union BIO_sock_info_u peer_info;
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
- if (getsockname(s, &peer, (void *)&peerlen) < 0) {
+ if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
+ BIO_printf(bio_err, "memory allocation failure\n");
+ BIO_closesocket(s);
+ goto end;
+ }
+ if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
BIO_printf(bio_err, "getsockname:errno=%d\n",
get_last_socket_error());
+ BIO_ADDR_free(peer_info.addr);
BIO_closesocket(s);
goto end;
}
- (void)BIO_ctrl_set_connected(sbio, &peer);
+ (void)BIO_ctrl_set_connected(sbio, peer_info.addr);
+ BIO_ADDR_free(peer_info.addr);
+ peer_info.addr = NULL;
if (enable_timeouts) {
timeout.tv_sec = 0;
SSL_set_connect_state(con);
/* ok, lets connect */
- width = SSL_get_fd(con) + 1;
+ if (fileno_stdin() > SSL_get_fd(con))
+ width = fileno_stdin() + 1;
+ else
+ width = SSL_get_fd(con) + 1;
read_tty = 1;
write_tty = 0;
goto shut;
}
}
+ break;
+ case PROTO_POSTGRES:
+ {
+ static const unsigned char ssl_request[] = {
+ /* Length SSLRequest */
+ 0, 0, 0, 8, 4, 210, 22, 47
+ };
+ int bytes;
+
+ /* Send SSLRequest packet */
+ BIO_write(sbio, ssl_request, 8);
+ (void)BIO_flush(sbio);
+
+ /* Reply will be a single S if SSL is enabled */
+ bytes = BIO_read(sbio, sbuf, BUFSIZZ);
+ if (bytes != 1 || sbuf[0] != 'S')
+ goto shut;
+ }
+ break;
}
for (;;) {
* set the flag so we exit.
*/
if (read_tty && !at_eof)
- openssl_fdset(fileno(stdin), &readfds);
+ openssl_fdset(fileno_stdin(), &readfds);
+#if !defined(OPENSSL_SYS_VMS)
if (write_tty)
- openssl_fdset(fileno(stdout), &writefds);
+ openssl_fdset(fileno_stdout(), &writefds);
+#endif
}
if (read_ssl)
openssl_fdset(SSL_get_fd(con), &readfds);
goto shut;
}
}
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VMS)
/* Assume Windows/DOS/BeOS can always write */
else if (!ssl_pending && write_tty)
#else
- else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds))
+ else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds))
#endif
{
#ifdef CHARSET_EBCDIC
#if defined(OPENSSL_SYS_MSDOS)
else if (has_stdin_waiting())
#else
- else if (FD_ISSET(fileno(stdin), &readfds))
+ else if (FD_ISSET(fileno_stdin(), &readfds))
#endif
{
if (crlf) {
assert(lf_num == 0);
} else
i = raw_read_stdin(cbuf, BUFSIZZ);
-
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
if (i == 0)
at_eof = 1;
+#endif
if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) {
BIO_printf(bio_err, "DONE\n");
#ifndef OPENSSL_NO_SRP
OPENSSL_free(srp_arg.srppassin);
#endif
+ OPENSSL_free(connectstr);
OPENSSL_free(host);
OPENSSL_free(port);
X509_VERIFY_PARAM_free(vpm);
OPENSSL_clear_free(cbuf, BUFSIZZ);
OPENSSL_clear_free(sbuf, BUFSIZZ);
OPENSSL_clear_free(mbuf, BUFSIZZ);
+ release_engine(e);
BIO_free(bio_c_out);
bio_c_out = NULL;
BIO_free(bio_c_msg);
#endif
BIO_printf(bio,
- "---\nSSL handshake has read %"PRIu64" bytes and written %"PRIu64" bytes\n",
+ "---\nSSL handshake has read %" PRIu64
+ " bytes and written %" PRIu64 " bytes\n",
BIO_number_read(SSL_get_rbio(s)),
BIO_number_written(SSL_get_wbio(s)));
}
{
/* Print out local port of connection: useful for debugging */
int sock;
- struct sockaddr_in ladd;
- socklen_t ladd_size = sizeof(ladd);
+ union BIO_sock_info_u info;
+
sock = SSL_get_fd(s);
- getsockname(sock, (struct sockaddr *)&ladd, &ladd_size);
- BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
+ if ((info.addr = BIO_ADDR_new()) != NULL
+ && BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &info)) {
+ BIO_printf(bio_c_out, "LOCAL PORT is %u\n",
+ ntohs(BIO_ADDR_rawport(info.addr)));
+ }
+ BIO_ADDR_free(info.addr);
}
#endif
#endif
SSL_SESSION_print(bio, SSL_get_session(s));
- if (keymatexportlabel != NULL) {
+ if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) {
BIO_printf(bio, "Keying material exporter:\n");
BIO_printf(bio, " Label: '%s'\n", keymatexportlabel);
BIO_printf(bio, " Length: %i bytes\n", keymatexportlen);
}
# endif
-#endif /* OPENSSL_NO_SOCK */
+#endif /* OPENSSL_NO_SOCK */