version 1.59, 2022/11/11 17:07:39 |
version 1.60, 2023/03/06 14:32:06 |
|
|
int verify; |
int verify; |
X509_VERIFY_PARAM *vpm; |
X509_VERIFY_PARAM *vpm; |
char *xmpphost; |
char *xmpphost; |
} s_client_config; |
} cfg; |
|
|
static int |
static int |
s_client_opt_keymatexportlen(char *arg) |
s_client_opt_keymatexportlen(char *arg) |
{ |
{ |
s_client_config.keymatexportlen = strtonum(arg, 1, INT_MAX, |
cfg.keymatexportlen = strtonum(arg, 1, INT_MAX, |
&s_client_config.errstr); |
&cfg.errstr); |
if (s_client_config.errstr != NULL) { |
if (cfg.errstr != NULL) { |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
arg, s_client_config.errstr); |
arg, cfg.errstr); |
return (1); |
return (1); |
} |
} |
return (0); |
return (0); |
|
|
static int |
static int |
s_client_opt_mtu(char *arg) |
s_client_opt_mtu(char *arg) |
{ |
{ |
s_client_config.socket_mtu = strtonum(arg, 0, LONG_MAX, |
cfg.socket_mtu = strtonum(arg, 0, LONG_MAX, |
&s_client_config.errstr); |
&cfg.errstr); |
if (s_client_config.errstr != NULL) { |
if (cfg.errstr != NULL) { |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
arg, s_client_config.errstr); |
arg, cfg.errstr); |
return (1); |
return (1); |
} |
} |
return (0); |
return (0); |
|
|
if (*arg == '\0') |
if (*arg == '\0') |
return (1); |
return (1); |
|
|
s_client_config.port = arg; |
cfg.port = arg; |
return (0); |
return (0); |
} |
} |
|
|
|
|
static int |
static int |
s_client_opt_protocol_version_dtls(void) |
s_client_opt_protocol_version_dtls(void) |
{ |
{ |
s_client_config.meth = DTLS_client_method(); |
cfg.meth = DTLS_client_method(); |
s_client_config.socket_type = SOCK_DGRAM; |
cfg.socket_type = SOCK_DGRAM; |
return (0); |
return (0); |
} |
} |
#endif |
#endif |
|
|
static int |
static int |
s_client_opt_protocol_version_dtls1(void) |
s_client_opt_protocol_version_dtls1(void) |
{ |
{ |
s_client_config.meth = DTLS_client_method(); |
cfg.meth = DTLS_client_method(); |
s_client_config.min_version = DTLS1_VERSION; |
cfg.min_version = DTLS1_VERSION; |
s_client_config.max_version = DTLS1_VERSION; |
cfg.max_version = DTLS1_VERSION; |
s_client_config.socket_type = SOCK_DGRAM; |
cfg.socket_type = SOCK_DGRAM; |
return (0); |
return (0); |
} |
} |
#endif |
#endif |
|
|
static int |
static int |
s_client_opt_protocol_version_dtls1_2(void) |
s_client_opt_protocol_version_dtls1_2(void) |
{ |
{ |
s_client_config.meth = DTLS_client_method(); |
cfg.meth = DTLS_client_method(); |
s_client_config.min_version = DTLS1_2_VERSION; |
cfg.min_version = DTLS1_2_VERSION; |
s_client_config.max_version = DTLS1_2_VERSION; |
cfg.max_version = DTLS1_2_VERSION; |
s_client_config.socket_type = SOCK_DGRAM; |
cfg.socket_type = SOCK_DGRAM; |
return (0); |
return (0); |
} |
} |
#endif |
#endif |
|
|
static int |
static int |
s_client_opt_protocol_version_tls1(void) |
s_client_opt_protocol_version_tls1(void) |
{ |
{ |
s_client_config.min_version = TLS1_VERSION; |
cfg.min_version = TLS1_VERSION; |
s_client_config.max_version = TLS1_VERSION; |
cfg.max_version = TLS1_VERSION; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
s_client_opt_protocol_version_tls1_1(void) |
s_client_opt_protocol_version_tls1_1(void) |
{ |
{ |
s_client_config.min_version = TLS1_1_VERSION; |
cfg.min_version = TLS1_1_VERSION; |
s_client_config.max_version = TLS1_1_VERSION; |
cfg.max_version = TLS1_1_VERSION; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
s_client_opt_protocol_version_tls1_2(void) |
s_client_opt_protocol_version_tls1_2(void) |
{ |
{ |
s_client_config.min_version = TLS1_2_VERSION; |
cfg.min_version = TLS1_2_VERSION; |
s_client_config.max_version = TLS1_2_VERSION; |
cfg.max_version = TLS1_2_VERSION; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
s_client_opt_protocol_version_tls1_3(void) |
s_client_opt_protocol_version_tls1_3(void) |
{ |
{ |
s_client_config.min_version = TLS1_3_VERSION; |
cfg.min_version = TLS1_3_VERSION; |
s_client_config.max_version = TLS1_3_VERSION; |
cfg.max_version = TLS1_3_VERSION; |
return (0); |
return (0); |
} |
} |
|
|
static int |
static int |
s_client_opt_quiet(void) |
s_client_opt_quiet(void) |
{ |
{ |
s_client_config.quiet = 1; |
cfg.quiet = 1; |
s_client_config.ign_eof = 1; |
cfg.ign_eof = 1; |
return (0); |
return (0); |
} |
} |
|
|
|
|
s_client_opt_starttls(char *arg) |
s_client_opt_starttls(char *arg) |
{ |
{ |
if (strcmp(arg, "smtp") == 0) |
if (strcmp(arg, "smtp") == 0) |
s_client_config.starttls_proto = PROTO_SMTP; |
cfg.starttls_proto = PROTO_SMTP; |
else if (strcmp(arg, "lmtp") == 0) |
else if (strcmp(arg, "lmtp") == 0) |
s_client_config.starttls_proto = PROTO_LMTP; |
cfg.starttls_proto = PROTO_LMTP; |
else if (strcmp(arg, "pop3") == 0) |
else if (strcmp(arg, "pop3") == 0) |
s_client_config.starttls_proto = PROTO_POP3; |
cfg.starttls_proto = PROTO_POP3; |
else if (strcmp(arg, "imap") == 0) |
else if (strcmp(arg, "imap") == 0) |
s_client_config.starttls_proto = PROTO_IMAP; |
cfg.starttls_proto = PROTO_IMAP; |
else if (strcmp(arg, "ftp") == 0) |
else if (strcmp(arg, "ftp") == 0) |
s_client_config.starttls_proto = PROTO_FTP; |
cfg.starttls_proto = PROTO_FTP; |
else if (strcmp(arg, "xmpp") == 0) |
else if (strcmp(arg, "xmpp") == 0) |
s_client_config.starttls_proto = PROTO_XMPP; |
cfg.starttls_proto = PROTO_XMPP; |
else |
else |
return (1); |
return (1); |
return (0); |
return (0); |
|
|
static int |
static int |
s_client_opt_verify(char *arg) |
s_client_opt_verify(char *arg) |
{ |
{ |
s_client_config.verify = SSL_VERIFY_PEER; |
cfg.verify = SSL_VERIFY_PEER; |
|
|
verify_depth = strtonum(arg, 0, INT_MAX, &s_client_config.errstr); |
verify_depth = strtonum(arg, 0, INT_MAX, &cfg.errstr); |
if (s_client_config.errstr != NULL) { |
if (cfg.errstr != NULL) { |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
BIO_printf(bio_err, "invalid argument %s: %s\n", |
arg, s_client_config.errstr); |
arg, cfg.errstr); |
return (1); |
return (1); |
} |
} |
BIO_printf(bio_err, "verify depth is %d\n", verify_depth); |
BIO_printf(bio_err, "verify depth is %d\n", verify_depth); |
|
|
int badarg = 0; |
int badarg = 0; |
|
|
if (!args_verify(&pargs, &pargc, &badarg, bio_err, |
if (!args_verify(&pargs, &pargc, &badarg, bio_err, |
&s_client_config.vpm)) { |
&cfg.vpm)) { |
BIO_printf(bio_err, "unknown option %s\n", *argv); |
BIO_printf(bio_err, "unknown option %s\n", *argv); |
return (1); |
return (1); |
} |
} |
|
|
.name = "4", |
.name = "4", |
.desc = "Use IPv4 only", |
.desc = "Use IPv4 only", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &s_client_config.af, |
.opt.value = &cfg.af, |
.value = AF_INET, |
.value = AF_INET, |
}, |
}, |
{ |
{ |
.name = "6", |
.name = "6", |
.desc = "Use IPv6 only", |
.desc = "Use IPv6 only", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &s_client_config.af, |
.opt.value = &cfg.af, |
.value = AF_INET6, |
.value = AF_INET6, |
}, |
}, |
{ |
{ |
|
|
.desc = "Set the advertised protocols for ALPN" |
.desc = "Set the advertised protocols for ALPN" |
" (comma-separated list)", |
" (comma-separated list)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.alpn_in, |
.opt.arg = &cfg.alpn_in, |
}, |
}, |
{ |
{ |
.name = "bugs", |
.name = "bugs", |
.desc = "Enable various workarounds for buggy implementations", |
.desc = "Enable various workarounds for buggy implementations", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.bugs, |
.opt.flag = &cfg.bugs, |
}, |
}, |
{ |
{ |
.name = "CAfile", |
.name = "CAfile", |
.argname = "file", |
.argname = "file", |
.desc = "PEM format file of CA certificates", |
.desc = "PEM format file of CA certificates", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.CAfile, |
.opt.arg = &cfg.CAfile, |
}, |
}, |
{ |
{ |
.name = "CApath", |
.name = "CApath", |
.argname = "directory", |
.argname = "directory", |
.desc = "PEM format directory of CA certificates", |
.desc = "PEM format directory of CA certificates", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.CApath, |
.opt.arg = &cfg.CApath, |
}, |
}, |
{ |
{ |
.name = "cert", |
.name = "cert", |
.argname = "file", |
.argname = "file", |
.desc = "Certificate file to use, PEM format assumed", |
.desc = "Certificate file to use, PEM format assumed", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.cert_file, |
.opt.arg = &cfg.cert_file, |
}, |
}, |
{ |
{ |
.name = "certform", |
.name = "certform", |
.argname = "fmt", |
.argname = "fmt", |
.desc = "Certificate format (PEM or DER) PEM default", |
.desc = "Certificate format (PEM or DER) PEM default", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &s_client_config.cert_format, |
.opt.value = &cfg.cert_format, |
}, |
}, |
{ |
{ |
.name = "cipher", |
.name = "cipher", |
.argname = "cipherlist", |
.argname = "cipherlist", |
.desc = "Preferred cipher to use (see 'openssl ciphers')", |
.desc = "Preferred cipher to use (see 'openssl ciphers')", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.cipher, |
.opt.arg = &cfg.cipher, |
}, |
}, |
{ |
{ |
.name = "connect", |
.name = "connect", |
.argname = "host:port", |
.argname = "host:port", |
.desc = "Who to connect to (default is localhost:4433)", |
.desc = "Who to connect to (default is localhost:4433)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.connect, |
.opt.arg = &cfg.connect, |
}, |
}, |
{ |
{ |
.name = "crlf", |
.name = "crlf", |
.desc = "Convert LF from terminal into CRLF", |
.desc = "Convert LF from terminal into CRLF", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.crlf, |
.opt.flag = &cfg.crlf, |
}, |
}, |
{ |
{ |
.name = "debug", |
.name = "debug", |
.desc = "Print extensive debugging information", |
.desc = "Print extensive debugging information", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.debug, |
.opt.flag = &cfg.debug, |
}, |
}, |
#ifndef OPENSSL_NO_DTLS |
#ifndef OPENSSL_NO_DTLS |
{ |
{ |
|
|
.argname = "list", |
.argname = "list", |
.desc = "Specify EC groups (colon-separated list)", |
.desc = "Specify EC groups (colon-separated list)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.groups_in, |
.opt.arg = &cfg.groups_in, |
}, |
}, |
{ |
{ |
.name = "host", |
.name = "host", |
.argname = "host", |
.argname = "host", |
.desc = "Use -connect instead", |
.desc = "Use -connect instead", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.host, |
.opt.arg = &cfg.host, |
}, |
}, |
{ |
{ |
.name = "ign_eof", |
.name = "ign_eof", |
.desc = "Ignore input EOF (default when -quiet)", |
.desc = "Ignore input EOF (default when -quiet)", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &s_client_config.ign_eof, |
.opt.value = &cfg.ign_eof, |
.value = 1, |
.value = 1, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "Private key file to use, if not, -cert file is used", |
.desc = "Private key file to use, if not, -cert file is used", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.key_file, |
.opt.arg = &cfg.key_file, |
}, |
}, |
{ |
{ |
.name = "keyform", |
.name = "keyform", |
.argname = "fmt", |
.argname = "fmt", |
.desc = "Key format (PEM or DER) PEM default", |
.desc = "Key format (PEM or DER) PEM default", |
.type = OPTION_ARG_FORMAT, |
.type = OPTION_ARG_FORMAT, |
.opt.value = &s_client_config.key_format, |
.opt.value = &cfg.key_format, |
}, |
}, |
{ |
{ |
.name = "keymatexport", |
.name = "keymatexport", |
.argname = "label", |
.argname = "label", |
.desc = "Export keying material using label", |
.desc = "Export keying material using label", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.keymatexportlabel, |
.opt.arg = &cfg.keymatexportlabel, |
}, |
}, |
{ |
{ |
.name = "keymatexportlen", |
.name = "keymatexportlen", |
|
|
.name = "legacy_server_connect", |
.name = "legacy_server_connect", |
.desc = "Allow initial connection to servers that don't support RI", |
.desc = "Allow initial connection to servers that don't support RI", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_LEGACY_SERVER_CONNECT, |
.value = SSL_OP_LEGACY_SERVER_CONNECT, |
}, |
}, |
{ |
{ |
.name = "msg", |
.name = "msg", |
.desc = "Show all protocol messages with hex dump", |
.desc = "Show all protocol messages with hex dump", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.msg, |
.opt.flag = &cfg.msg, |
}, |
}, |
#ifndef OPENSSL_NO_DTLS |
#ifndef OPENSSL_NO_DTLS |
{ |
{ |
|
|
.name = "nbio", |
.name = "nbio", |
.desc = "Turn on non-blocking I/O", |
.desc = "Turn on non-blocking I/O", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.nbio, |
.opt.flag = &cfg.nbio, |
}, |
}, |
{ |
{ |
.name = "nbio_test", |
.name = "nbio_test", |
.desc = "Test non-blocking I/O", |
.desc = "Test non-blocking I/O", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.nbio_test, |
.opt.flag = &cfg.nbio_test, |
}, |
}, |
{ |
{ |
.name = "nextprotoneg", |
.name = "nextprotoneg", |
.argname = "protocols", |
.argname = "protocols", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.npn_in, /* Ignored. */ |
.opt.arg = &cfg.npn_in, /* Ignored. */ |
}, |
}, |
{ |
{ |
.name = "no_comp", |
.name = "no_comp", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_COMPRESSION, |
.value = SSL_OP_NO_COMPRESSION, |
}, |
}, |
{ |
{ |
.name = "no_ign_eof", |
.name = "no_ign_eof", |
.desc = "Don't ignore input EOF", |
.desc = "Don't ignore input EOF", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &s_client_config.ign_eof, |
.opt.value = &cfg.ign_eof, |
.value = 0, |
.value = 0, |
}, |
}, |
{ |
{ |
.name = "no_legacy_server_connect", |
.name = "no_legacy_server_connect", |
.desc = "Disallow initial connection to servers that don't support RI", |
.desc = "Disallow initial connection to servers that don't support RI", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.clr, |
.opt.value = &cfg.clr, |
.value = SSL_OP_LEGACY_SERVER_CONNECT, |
.value = SSL_OP_LEGACY_SERVER_CONNECT, |
}, |
}, |
{ |
{ |
.name = "no_servername", |
.name = "no_servername", |
.desc = "Do not send a Server Name Indication (SNI) extension", |
.desc = "Do not send a Server Name Indication (SNI) extension", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.value = &s_client_config.no_servername, |
.opt.value = &cfg.no_servername, |
}, |
}, |
{ |
{ |
.name = "no_ssl2", |
.name = "no_ssl2", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_SSLv2, |
.value = SSL_OP_NO_SSLv2, |
}, |
}, |
{ |
{ |
.name = "no_ssl3", |
.name = "no_ssl3", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_SSLv3, |
.value = SSL_OP_NO_SSLv3, |
}, |
}, |
{ |
{ |
.name = "no_ticket", |
.name = "no_ticket", |
.desc = "Disable use of RFC4507 session ticket support", |
.desc = "Disable use of RFC4507 session ticket support", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_TICKET, |
.value = SSL_OP_NO_TICKET, |
}, |
}, |
{ |
{ |
.name = "no_tls1", |
.name = "no_tls1", |
.desc = "Disable the use of TLSv1", |
.desc = "Disable the use of TLSv1", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_TLSv1, |
.value = SSL_OP_NO_TLSv1, |
}, |
}, |
{ |
{ |
.name = "no_tls1_1", |
.name = "no_tls1_1", |
.desc = "Disable the use of TLSv1.1", |
.desc = "Disable the use of TLSv1.1", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_TLSv1_1, |
.value = SSL_OP_NO_TLSv1_1, |
}, |
}, |
{ |
{ |
.name = "no_tls1_2", |
.name = "no_tls1_2", |
.desc = "Disable the use of TLSv1.2", |
.desc = "Disable the use of TLSv1.2", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_TLSv1_2, |
.value = SSL_OP_NO_TLSv1_2, |
}, |
}, |
{ |
{ |
.name = "no_tls1_3", |
.name = "no_tls1_3", |
.desc = "Disable the use of TLSv1.3", |
.desc = "Disable the use of TLSv1.3", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_NO_TLSv1_3, |
.value = SSL_OP_NO_TLSv1_3, |
}, |
}, |
{ |
{ |
.name = "noservername", |
.name = "noservername", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.value = &s_client_config.no_servername, |
.opt.value = &cfg.no_servername, |
}, |
}, |
{ |
{ |
.name = "pass", |
.name = "pass", |
.argname = "arg", |
.argname = "arg", |
.desc = "Private key file pass phrase source", |
.desc = "Private key file pass phrase source", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.passarg, |
.opt.arg = &cfg.passarg, |
}, |
}, |
{ |
{ |
.name = "pause", |
.name = "pause", |
.desc = "Pause 1 second between each read and write call", |
.desc = "Pause 1 second between each read and write call", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.pause, |
.opt.flag = &cfg.pause, |
}, |
}, |
{ |
{ |
.name = "peekaboo", |
.name = "peekaboo", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.peekaboo, |
.opt.flag = &cfg.peekaboo, |
}, |
}, |
{ |
{ |
.name = "port", |
.name = "port", |
|
|
.name = "prexit", |
.name = "prexit", |
.desc = "Print session information when the program exits", |
.desc = "Print session information when the program exits", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.prexit, |
.opt.flag = &cfg.prexit, |
}, |
}, |
{ |
{ |
.name = "proxy", |
.name = "proxy", |
.argname = "host:port", |
.argname = "host:port", |
.desc = "Connect to http proxy", |
.desc = "Connect to http proxy", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.proxy, |
.opt.arg = &cfg.proxy, |
}, |
}, |
{ |
{ |
.name = "quiet", |
.name = "quiet", |
|
|
.name = "reconnect", |
.name = "reconnect", |
.desc = "Drop and re-make the connection with the same Session-ID", |
.desc = "Drop and re-make the connection with the same Session-ID", |
.type = OPTION_VALUE, |
.type = OPTION_VALUE, |
.opt.value = &s_client_config.reconnect, |
.opt.value = &cfg.reconnect, |
.value = 5, |
.value = 5, |
}, |
}, |
{ |
{ |
|
|
.argname = "name", |
.argname = "name", |
.desc = "Set TLS extension servername in ClientHello (SNI)", |
.desc = "Set TLS extension servername in ClientHello (SNI)", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.servername, |
.opt.arg = &cfg.servername, |
}, |
}, |
{ |
{ |
.name = "serverpref", |
.name = "serverpref", |
.desc = "Use server's cipher preferences", |
.desc = "Use server's cipher preferences", |
.type = OPTION_VALUE_OR, |
.type = OPTION_VALUE_OR, |
.opt.value = &s_client_config.off, |
.opt.value = &cfg.off, |
.value = SSL_OP_CIPHER_SERVER_PREFERENCE, |
.value = SSL_OP_CIPHER_SERVER_PREFERENCE, |
}, |
}, |
{ |
{ |
|
|
.argname = "file", |
.argname = "file", |
.desc = "File to read TLS session from", |
.desc = "File to read TLS session from", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.sess_in, |
.opt.arg = &cfg.sess_in, |
}, |
}, |
{ |
{ |
.name = "sess_out", |
.name = "sess_out", |
.argname = "file", |
.argname = "file", |
.desc = "File to write TLS session to", |
.desc = "File to write TLS session to", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.sess_out, |
.opt.arg = &cfg.sess_out, |
}, |
}, |
{ |
{ |
.name = "showcerts", |
.name = "showcerts", |
.desc = "Show all server certificates in the chain", |
.desc = "Show all server certificates in the chain", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.showcerts, |
.opt.flag = &cfg.showcerts, |
}, |
}, |
{ |
{ |
.name = "starttls", |
.name = "starttls", |
|
|
.name = "state", |
.name = "state", |
.desc = "Print the TLS session states", |
.desc = "Print the TLS session states", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.state, |
.opt.flag = &cfg.state, |
}, |
}, |
{ |
{ |
.name = "status", |
.name = "status", |
.desc = "Send a certificate status request to the server (OCSP)", |
.desc = "Send a certificate status request to the server (OCSP)", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.status_req, |
.opt.flag = &cfg.status_req, |
}, |
}, |
#ifndef OPENSSL_NO_DTLS |
#ifndef OPENSSL_NO_DTLS |
{ |
{ |
.name = "timeout", |
.name = "timeout", |
.desc = "Enable send/receive timeout on DTLS connections", |
.desc = "Enable send/receive timeout on DTLS connections", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.enable_timeouts, |
.opt.flag = &cfg.enable_timeouts, |
}, |
}, |
#endif |
#endif |
{ |
{ |
|
|
.name = "tlsextdebug", |
.name = "tlsextdebug", |
.desc = "Hex dump of all TLS extensions received", |
.desc = "Hex dump of all TLS extensions received", |
.type = OPTION_FLAG, |
.type = OPTION_FLAG, |
.opt.flag = &s_client_config.tlsextdebug, |
.opt.flag = &cfg.tlsextdebug, |
}, |
}, |
#ifndef OPENSSL_NO_SRTP |
#ifndef OPENSSL_NO_SRTP |
{ |
{ |
|
|
.argname = "profiles", |
.argname = "profiles", |
.desc = "Offer SRTP key management with a colon-separated profiles", |
.desc = "Offer SRTP key management with a colon-separated profiles", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.srtp_profiles, |
.opt.arg = &cfg.srtp_profiles, |
}, |
}, |
#endif |
#endif |
{ |
{ |
|
|
.argname = "host", |
.argname = "host", |
.desc = "Connect to this virtual host on the xmpp server", |
.desc = "Connect to this virtual host on the xmpp server", |
.type = OPTION_ARG, |
.type = OPTION_ARG, |
.opt.arg = &s_client_config.xmpphost, |
.opt.arg = &cfg.xmpphost, |
}, |
}, |
{ |
{ |
.name = NULL, |
.name = NULL, |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
memset(&s_client_config, 0, sizeof(s_client_config)); |
memset(&cfg, 0, sizeof(cfg)); |
s_client_config.af = AF_UNSPEC; |
cfg.af = AF_UNSPEC; |
s_client_config.cert_format = FORMAT_PEM; |
cfg.cert_format = FORMAT_PEM; |
s_client_config.host = SSL_HOST_NAME; |
cfg.host = SSL_HOST_NAME; |
s_client_config.key_format = FORMAT_PEM; |
cfg.key_format = FORMAT_PEM; |
s_client_config.keymatexportlen = 20; |
cfg.keymatexportlen = 20; |
s_client_config.meth = TLS_client_method(); |
cfg.meth = TLS_client_method(); |
s_client_config.port = PORT_STR; |
cfg.port = PORT_STR; |
s_client_config.socket_type = SOCK_STREAM; |
cfg.socket_type = SOCK_STREAM; |
s_client_config.starttls_proto = PROTO_OFF; |
cfg.starttls_proto = PROTO_OFF; |
s_client_config.verify = SSL_VERIFY_NONE; |
cfg.verify = SSL_VERIFY_NONE; |
|
|
if (((cbuf = malloc(BUFSIZZ)) == NULL) || |
if (((cbuf = malloc(BUFSIZZ)) == NULL) || |
((sbuf = malloc(BUFSIZZ)) == NULL) || |
((sbuf = malloc(BUFSIZZ)) == NULL) || |
|
|
badop = 1; |
badop = 1; |
goto bad; |
goto bad; |
} |
} |
if (s_client_config.proxy != NULL) { |
if (cfg.proxy != NULL) { |
if (!extract_host_port(s_client_config.proxy, |
if (!extract_host_port(cfg.proxy, |
&s_client_config.host, NULL, &s_client_config.port)) |
&cfg.host, NULL, &cfg.port)) |
goto bad; |
goto bad; |
if (s_client_config.connect == NULL) |
if (cfg.connect == NULL) |
s_client_config.connect = SSL_HOST_NAME; |
cfg.connect = SSL_HOST_NAME; |
} else if (s_client_config.connect != NULL) { |
} else if (cfg.connect != NULL) { |
if (!extract_host_port(s_client_config.connect, |
if (!extract_host_port(cfg.connect, |
&s_client_config.host, NULL, &s_client_config.port)) |
&cfg.host, NULL, &cfg.port)) |
goto bad; |
goto bad; |
} |
} |
if (badop) { |
if (badop) { |
bad: |
bad: |
if (s_client_config.errstr == NULL) |
if (cfg.errstr == NULL) |
sc_usage(); |
sc_usage(); |
goto end; |
goto end; |
} |
} |
|
|
if (!app_passwd(bio_err, s_client_config.passarg, NULL, &pass, NULL)) { |
if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) { |
BIO_printf(bio_err, "Error getting password\n"); |
BIO_printf(bio_err, "Error getting password\n"); |
goto end; |
goto end; |
} |
} |
if (s_client_config.key_file == NULL) |
if (cfg.key_file == NULL) |
s_client_config.key_file = s_client_config.cert_file; |
cfg.key_file = cfg.cert_file; |
|
|
|
|
if (s_client_config.key_file) { |
if (cfg.key_file) { |
|
|
key = load_key(bio_err, s_client_config.key_file, |
key = load_key(bio_err, cfg.key_file, |
s_client_config.key_format, 0, pass, |
cfg.key_format, 0, pass, |
"client certificate private key file"); |
"client certificate private key file"); |
if (!key) { |
if (!key) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
if (s_client_config.cert_file) { |
if (cfg.cert_file) { |
cert = load_cert(bio_err, s_client_config.cert_file, |
cert = load_cert(bio_err, cfg.cert_file, |
s_client_config.cert_format, |
cfg.cert_format, |
NULL, "client certificate file"); |
NULL, "client certificate file"); |
|
|
if (!cert) { |
if (!cert) { |
|
|
goto end; |
goto end; |
} |
} |
} |
} |
if (s_client_config.quiet && !s_client_config.debug && |
if (cfg.quiet && !cfg.debug && |
!s_client_config.msg) { |
!cfg.msg) { |
if ((bio_c_out = BIO_new(BIO_s_null())) == NULL) |
if ((bio_c_out = BIO_new(BIO_s_null())) == NULL) |
goto end; |
goto end; |
} else { |
} else { |
|
|
goto end; |
goto end; |
} |
} |
|
|
ctx = SSL_CTX_new(s_client_config.meth); |
ctx = SSL_CTX_new(cfg.meth); |
if (ctx == NULL) { |
if (ctx == NULL) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
|
|
|
|
SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); |
SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY); |
|
|
if (s_client_config.vpm) |
if (cfg.vpm) |
SSL_CTX_set1_param(ctx, s_client_config.vpm); |
SSL_CTX_set1_param(ctx, cfg.vpm); |
|
|
if (!SSL_CTX_set_min_proto_version(ctx, s_client_config.min_version)) |
if (!SSL_CTX_set_min_proto_version(ctx, cfg.min_version)) |
goto end; |
goto end; |
if (!SSL_CTX_set_max_proto_version(ctx, s_client_config.max_version)) |
if (!SSL_CTX_set_max_proto_version(ctx, cfg.max_version)) |
goto end; |
goto end; |
|
|
#ifndef OPENSSL_NO_SRTP |
#ifndef OPENSSL_NO_SRTP |
if (s_client_config.srtp_profiles != NULL) |
if (cfg.srtp_profiles != NULL) |
SSL_CTX_set_tlsext_use_srtp(ctx, s_client_config.srtp_profiles); |
SSL_CTX_set_tlsext_use_srtp(ctx, cfg.srtp_profiles); |
#endif |
#endif |
if (s_client_config.bugs) |
if (cfg.bugs) |
SSL_CTX_set_options(ctx, SSL_OP_ALL | s_client_config.off); |
SSL_CTX_set_options(ctx, SSL_OP_ALL | cfg.off); |
else |
else |
SSL_CTX_set_options(ctx, s_client_config.off); |
SSL_CTX_set_options(ctx, cfg.off); |
|
|
if (s_client_config.clr) |
if (cfg.clr) |
SSL_CTX_clear_options(ctx, s_client_config.clr); |
SSL_CTX_clear_options(ctx, cfg.clr); |
|
|
if (s_client_config.alpn_in) { |
if (cfg.alpn_in) { |
unsigned short alpn_len; |
unsigned short alpn_len; |
unsigned char *alpn; |
unsigned char *alpn; |
|
|
alpn = next_protos_parse(&alpn_len, s_client_config.alpn_in); |
alpn = next_protos_parse(&alpn_len, cfg.alpn_in); |
if (alpn == NULL) { |
if (alpn == NULL) { |
BIO_printf(bio_err, "Error parsing -alpn argument\n"); |
BIO_printf(bio_err, "Error parsing -alpn argument\n"); |
goto end; |
goto end; |
|
|
SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); |
SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len); |
free(alpn); |
free(alpn); |
} |
} |
if (s_client_config.groups_in != NULL) { |
if (cfg.groups_in != NULL) { |
if (SSL_CTX_set1_groups_list(ctx, s_client_config.groups_in) != 1) { |
if (SSL_CTX_set1_groups_list(ctx, cfg.groups_in) != 1) { |
BIO_printf(bio_err, "Failed to set groups '%s'\n", |
BIO_printf(bio_err, "Failed to set groups '%s'\n", |
s_client_config.groups_in); |
cfg.groups_in); |
goto end; |
goto end; |
} |
} |
} |
} |
|
|
if (s_client_config.state) |
if (cfg.state) |
SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); |
SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); |
if (s_client_config.cipher != NULL) |
if (cfg.cipher != NULL) |
if (!SSL_CTX_set_cipher_list(ctx, s_client_config.cipher)) { |
if (!SSL_CTX_set_cipher_list(ctx, cfg.cipher)) { |
BIO_printf(bio_err, "error setting cipher list\n"); |
BIO_printf(bio_err, "error setting cipher list\n"); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
SSL_CTX_set_verify(ctx, s_client_config.verify, verify_callback); |
SSL_CTX_set_verify(ctx, cfg.verify, verify_callback); |
if (!set_cert_key_stuff(ctx, cert, key)) |
if (!set_cert_key_stuff(ctx, cert, key)) |
goto end; |
goto end; |
|
|
if ((s_client_config.CAfile || s_client_config.CApath) |
if ((cfg.CAfile || cfg.CApath) |
&& !SSL_CTX_load_verify_locations(ctx, s_client_config.CAfile, |
&& !SSL_CTX_load_verify_locations(ctx, cfg.CAfile, |
s_client_config.CApath)) |
cfg.CApath)) |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
|
|
if (!SSL_CTX_set_default_verify_paths(ctx)) |
if (!SSL_CTX_set_default_verify_paths(ctx)) |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
|
|
con = SSL_new(ctx); |
con = SSL_new(ctx); |
if (s_client_config.sess_in) { |
if (cfg.sess_in) { |
SSL_SESSION *sess; |
SSL_SESSION *sess; |
BIO *stmp = BIO_new_file(s_client_config.sess_in, "r"); |
BIO *stmp = BIO_new_file(cfg.sess_in, "r"); |
if (!stmp) { |
if (!stmp) { |
BIO_printf(bio_err, "Can't open session file %s\n", |
BIO_printf(bio_err, "Can't open session file %s\n", |
s_client_config.sess_in); |
cfg.sess_in); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
BIO_free(stmp); |
BIO_free(stmp); |
if (!sess) { |
if (!sess) { |
BIO_printf(bio_err, "Can't open session file %s\n", |
BIO_printf(bio_err, "Can't open session file %s\n", |
s_client_config.sess_in); |
cfg.sess_in); |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
|
|
} |
} |
|
|
/* Attempt to opportunistically use the host name for SNI. */ |
/* Attempt to opportunistically use the host name for SNI. */ |
servername = s_client_config.servername; |
servername = cfg.servername; |
if (servername == NULL) |
if (servername == NULL) |
servername = s_client_config.host; |
servername = cfg.host; |
|
|
if (!s_client_config.no_servername && servername != NULL && |
if (!cfg.no_servername && servername != NULL && |
!SSL_set_tlsext_host_name(con, servername)) { |
!SSL_set_tlsext_host_name(con, servername)) { |
long ssl_err = ERR_peek_error(); |
long ssl_err = ERR_peek_error(); |
|
|
if (s_client_config.servername != NULL || |
if (cfg.servername != NULL || |
ERR_GET_LIB(ssl_err) != ERR_LIB_SSL || |
ERR_GET_LIB(ssl_err) != ERR_LIB_SSL || |
ERR_GET_REASON(ssl_err) != SSL_R_SSL3_EXT_INVALID_SERVERNAME) { |
ERR_GET_REASON(ssl_err) != SSL_R_SSL3_EXT_INVALID_SERVERNAME) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
servername = NULL; |
servername = NULL; |
ERR_clear_error(); |
ERR_clear_error(); |
} |
} |
if (!s_client_config.no_servername && servername != NULL) { |
if (!cfg.no_servername && servername != NULL) { |
tlsextcbp.biodebug = bio_err; |
tlsextcbp.biodebug = bio_err; |
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); |
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); |
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); |
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp); |
|
|
|
|
re_start: |
re_start: |
|
|
if (init_client(&s, s_client_config.host, s_client_config.port, |
if (init_client(&s, cfg.host, cfg.port, |
s_client_config.socket_type, s_client_config.af) == 0) { |
cfg.socket_type, cfg.af) == 0) { |
BIO_printf(bio_err, "connect:errno=%d\n", errno); |
BIO_printf(bio_err, "connect:errno=%d\n", errno); |
goto end; |
goto end; |
} |
} |
BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); |
BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); |
|
|
if (s_client_config.nbio) { |
if (cfg.nbio) { |
if (!s_client_config.quiet) |
if (!cfg.quiet) |
BIO_printf(bio_c_out, "turning on non blocking io\n"); |
BIO_printf(bio_c_out, "turning on non blocking io\n"); |
if (!BIO_socket_nbio(s, 1)) { |
if (!BIO_socket_nbio(s, 1)) { |
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto end; |
goto end; |
} |
} |
} |
} |
if (s_client_config.pause & 0x01) |
if (cfg.pause & 0x01) |
SSL_set_debug(con, 1); |
SSL_set_debug(con, 1); |
|
|
if (SSL_is_dtls(con)) { |
if (SSL_is_dtls(con)) { |
|
|
} |
} |
(void) BIO_ctrl_set_connected(sbio, 1, &peer); |
(void) BIO_ctrl_set_connected(sbio, 1, &peer); |
|
|
if (s_client_config.enable_timeouts) { |
if (cfg.enable_timeouts) { |
timeout.tv_sec = 0; |
timeout.tv_sec = 0; |
timeout.tv_usec = DGRAM_RCV_TIMEOUT; |
timeout.tv_usec = DGRAM_RCV_TIMEOUT; |
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, |
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, |
|
|
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, |
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, |
&timeout); |
&timeout); |
} |
} |
if (s_client_config.socket_mtu > 28) { |
if (cfg.socket_mtu > 28) { |
SSL_set_options(con, SSL_OP_NO_QUERY_MTU); |
SSL_set_options(con, SSL_OP_NO_QUERY_MTU); |
SSL_set_mtu(con, s_client_config.socket_mtu - 28); |
SSL_set_mtu(con, cfg.socket_mtu - 28); |
} else |
} else |
/* want to do MTU discovery */ |
/* want to do MTU discovery */ |
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); |
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); |
} else |
} else |
sbio = BIO_new_socket(s, BIO_NOCLOSE); |
sbio = BIO_new_socket(s, BIO_NOCLOSE); |
|
|
if (s_client_config.nbio_test) { |
if (cfg.nbio_test) { |
BIO *test; |
BIO *test; |
|
|
test = BIO_new(BIO_f_nbio_test()); |
test = BIO_new(BIO_f_nbio_test()); |
sbio = BIO_push(test, sbio); |
sbio = BIO_push(test, sbio); |
} |
} |
if (s_client_config.debug) { |
if (cfg.debug) { |
SSL_set_debug(con, 1); |
SSL_set_debug(con, 1); |
BIO_set_callback(sbio, bio_dump_callback); |
BIO_set_callback(sbio, bio_dump_callback); |
BIO_set_callback_arg(sbio, (char *) bio_c_out); |
BIO_set_callback_arg(sbio, (char *) bio_c_out); |
} |
} |
if (s_client_config.msg) { |
if (cfg.msg) { |
SSL_set_msg_callback(con, msg_cb); |
SSL_set_msg_callback(con, msg_cb); |
SSL_set_msg_callback_arg(con, bio_c_out); |
SSL_set_msg_callback_arg(con, bio_c_out); |
} |
} |
if (s_client_config.tlsextdebug) { |
if (cfg.tlsextdebug) { |
SSL_set_tlsext_debug_callback(con, tlsext_cb); |
SSL_set_tlsext_debug_callback(con, tlsext_cb); |
SSL_set_tlsext_debug_arg(con, bio_c_out); |
SSL_set_tlsext_debug_arg(con, bio_c_out); |
} |
} |
if (s_client_config.status_req) { |
if (cfg.status_req) { |
SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); |
SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp); |
SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); |
SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb); |
SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); |
SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out); |
|
|
* push a buffering BIO into the chain that is removed again later on |
* push a buffering BIO into the chain that is removed again later on |
* to not disturb the rest of the s_client operation. |
* to not disturb the rest of the s_client operation. |
*/ |
*/ |
if (s_client_config.starttls_proto == PROTO_SMTP || |
if (cfg.starttls_proto == PROTO_SMTP || |
s_client_config.starttls_proto == PROTO_LMTP) { |
cfg.starttls_proto == PROTO_LMTP) { |
int foundit = 0; |
int foundit = 0; |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO_push(fbio, sbio); |
BIO_push(fbio, sbio); |
|
|
while (mbuf_len > 3 && mbuf[3] == '-'); |
while (mbuf_len > 3 && mbuf[3] == '-'); |
/* STARTTLS command requires EHLO... */ |
/* STARTTLS command requires EHLO... */ |
BIO_printf(fbio, "%cHLO openssl.client.net\r\n", |
BIO_printf(fbio, "%cHLO openssl.client.net\r\n", |
s_client_config.starttls_proto == PROTO_SMTP ? 'E' : 'L'); |
cfg.starttls_proto == PROTO_SMTP ? 'E' : 'L'); |
(void) BIO_flush(fbio); |
(void) BIO_flush(fbio); |
/* wait for multi-line response to end EHLO SMTP response */ |
/* wait for multi-line response to end EHLO SMTP response */ |
do { |
do { |
|
|
" try anyway...\n"); |
" try anyway...\n"); |
BIO_printf(sbio, "STARTTLS\r\n"); |
BIO_printf(sbio, "STARTTLS\r\n"); |
BIO_read(sbio, sbuf, BUFSIZZ); |
BIO_read(sbio, sbuf, BUFSIZZ); |
} else if (s_client_config.starttls_proto == PROTO_POP3) { |
} else if (cfg.starttls_proto == PROTO_POP3) { |
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
if (mbuf_len == -1) { |
if (mbuf_len == -1) { |
BIO_printf(bio_err, "BIO_read failed\n"); |
BIO_printf(bio_err, "BIO_read failed\n"); |
|
|
} |
} |
BIO_printf(sbio, "STLS\r\n"); |
BIO_printf(sbio, "STLS\r\n"); |
BIO_read(sbio, sbuf, BUFSIZZ); |
BIO_read(sbio, sbuf, BUFSIZZ); |
} else if (s_client_config.starttls_proto == PROTO_IMAP) { |
} else if (cfg.starttls_proto == PROTO_IMAP) { |
int foundit = 0; |
int foundit = 0; |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO_push(fbio, sbio); |
BIO_push(fbio, sbio); |
|
|
" try anyway...\n"); |
" try anyway...\n"); |
BIO_printf(sbio, ". STARTTLS\r\n"); |
BIO_printf(sbio, ". STARTTLS\r\n"); |
BIO_read(sbio, sbuf, BUFSIZZ); |
BIO_read(sbio, sbuf, BUFSIZZ); |
} else if (s_client_config.starttls_proto == PROTO_FTP) { |
} else if (cfg.starttls_proto == PROTO_FTP) { |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO *fbio = BIO_new(BIO_f_buffer()); |
BIO_push(fbio, sbio); |
BIO_push(fbio, sbio); |
/* wait for multi-line response to end from FTP */ |
/* wait for multi-line response to end from FTP */ |
|
|
BIO_free(fbio); |
BIO_free(fbio); |
BIO_printf(sbio, "AUTH TLS\r\n"); |
BIO_printf(sbio, "AUTH TLS\r\n"); |
BIO_read(sbio, sbuf, BUFSIZZ); |
BIO_read(sbio, sbuf, BUFSIZZ); |
} else if (s_client_config.starttls_proto == PROTO_XMPP) { |
} else if (cfg.starttls_proto == PROTO_XMPP) { |
int seen = 0; |
int seen = 0; |
BIO_printf(sbio, "<stream:stream " |
BIO_printf(sbio, "<stream:stream " |
"xmlns:stream='http://etherx.jabber.org/streams' " |
"xmlns:stream='http://etherx.jabber.org/streams' " |
"xmlns='jabber:client' to='%s' version='1.0'>", |
"xmlns='jabber:client' to='%s' version='1.0'>", |
s_client_config.xmpphost ? |
cfg.xmpphost ? |
s_client_config.xmpphost : s_client_config.host); |
cfg.xmpphost : cfg.host); |
seen = BIO_read(sbio, mbuf, BUFSIZZ); |
seen = BIO_read(sbio, mbuf, BUFSIZZ); |
|
|
if (seen <= 0) |
if (seen <= 0) |
|
|
if (!strstr(sbuf, "<proceed")) |
if (!strstr(sbuf, "<proceed")) |
goto shut; |
goto shut; |
mbuf[0] = 0; |
mbuf[0] = 0; |
} else if (s_client_config.proxy != NULL) { |
} else if (cfg.proxy != NULL) { |
BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n", |
BIO_printf(sbio, "CONNECT %s HTTP/1.0\r\n\r\n", |
s_client_config.connect); |
cfg.connect); |
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ); |
if (mbuf_len == -1) { |
if (mbuf_len == -1) { |
BIO_printf(bio_err, "BIO_read failed\n"); |
BIO_printf(bio_err, "BIO_read failed\n"); |
|
|
tty_on = 1; |
tty_on = 1; |
if (in_init) { |
if (in_init) { |
in_init = 0; |
in_init = 0; |
if (s_client_config.sess_out) { |
if (cfg.sess_out) { |
BIO *stmp = BIO_new_file( |
BIO *stmp = BIO_new_file( |
s_client_config.sess_out, "w"); |
cfg.sess_out, "w"); |
if (stmp) { |
if (stmp) { |
PEM_write_bio_SSL_SESSION(stmp, |
PEM_write_bio_SSL_SESSION(stmp, |
SSL_get_session(con)); |
SSL_get_session(con)); |
|
|
} else |
} else |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
"Error writing session file %s\n", |
"Error writing session file %s\n", |
s_client_config.sess_out); |
cfg.sess_out); |
} |
} |
print_stuff(bio_c_out, con, full_log); |
print_stuff(bio_c_out, con, full_log); |
if (full_log > 0) |
if (full_log > 0) |
full_log--; |
full_log--; |
|
|
if (s_client_config.starttls_proto) { |
if (cfg.starttls_proto) { |
BIO_write(bio_err, mbuf, mbuf_len); |
BIO_write(bio_err, mbuf, mbuf_len); |
/* We don't need to know any more */ |
/* We don't need to know any more */ |
s_client_config.starttls_proto = PROTO_OFF; |
cfg.starttls_proto = PROTO_OFF; |
} |
} |
if (s_client_config.reconnect) { |
if (cfg.reconnect) { |
s_client_config.reconnect--; |
cfg.reconnect--; |
BIO_printf(bio_c_out, |
BIO_printf(bio_c_out, |
"drop connection and then reconnect\n"); |
"drop connection and then reconnect\n"); |
SSL_shutdown(con); |
SSL_shutdown(con); |
|
|
} |
} |
} |
} |
#endif |
#endif |
if (s_client_config.peekaboo) { |
if (cfg.peekaboo) { |
k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ ); |
k = p = SSL_peek(con, pbuf, 1024 /* BUFSIZZ */ ); |
pending = SSL_pending(con); |
pending = SSL_pending(con); |
if (SSL_get_error(con, p) == SSL_ERROR_NONE) { |
if (SSL_get_error(con, p) == SSL_ERROR_NONE) { |
|
|
goto end; |
goto end; |
sbuf_off = 0; |
sbuf_off = 0; |
sbuf_len = k; |
sbuf_len = k; |
if (s_client_config.peekaboo) { |
if (cfg.peekaboo) { |
if (p != pending) { |
if (p != pending) { |
ret = -1; |
ret = -1; |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
BIO_printf(bio_err, "poll error"); |
BIO_printf(bio_err, "poll error"); |
goto shut; |
goto shut; |
} |
} |
if (s_client_config.crlf) { |
if (cfg.crlf) { |
int j, lf_num; |
int j, lf_num; |
|
|
i = read(fileno(stdin), cbuf, BUFSIZZ / 2); |
i = read(fileno(stdin), cbuf, BUFSIZZ / 2); |
|
|
} else |
} else |
i = read(fileno(stdin), cbuf, BUFSIZZ); |
i = read(fileno(stdin), cbuf, BUFSIZZ); |
|
|
if ((!s_client_config.ign_eof) && |
if ((!cfg.ign_eof) && |
((i <= 0) || (cbuf[0] == 'Q'))) { |
((i <= 0) || (cbuf[0] == 'Q'))) { |
BIO_printf(bio_err, "DONE\n"); |
BIO_printf(bio_err, "DONE\n"); |
ret = 0; |
ret = 0; |
goto shut; |
goto shut; |
} |
} |
if ((!s_client_config.ign_eof) && (cbuf[0] == 'R')) { |
if ((!cfg.ign_eof) && (cbuf[0] == 'R')) { |
BIO_printf(bio_err, "RENEGOTIATING\n"); |
BIO_printf(bio_err, "RENEGOTIATING\n"); |
SSL_renegotiate(con); |
SSL_renegotiate(con); |
cbuf_len = 0; |
cbuf_len = 0; |
|
|
close(SSL_get_fd(con)); |
close(SSL_get_fd(con)); |
end: |
end: |
if (con != NULL) { |
if (con != NULL) { |
if (s_client_config.prexit != 0) |
if (cfg.prexit != 0) |
print_stuff(bio_c_out, con, 1); |
print_stuff(bio_c_out, con, 1); |
SSL_free(con); |
SSL_free(con); |
} |
} |
|
|
X509_free(cert); |
X509_free(cert); |
EVP_PKEY_free(key); |
EVP_PKEY_free(key); |
free(pass); |
free(pass); |
X509_VERIFY_PARAM_free(s_client_config.vpm); |
X509_VERIFY_PARAM_free(cfg.vpm); |
freezero(cbuf, BUFSIZZ); |
freezero(cbuf, BUFSIZZ); |
freezero(sbuf, BUFSIZZ); |
freezero(sbuf, BUFSIZZ); |
freezero(pbuf, BUFSIZZ); |
freezero(pbuf, BUFSIZZ); |
|
|
X509_NAME_oneline(X509_get_issuer_name( |
X509_NAME_oneline(X509_get_issuer_name( |
sk_X509_value(sk, i)), buf, sizeof buf); |
sk_X509_value(sk, i)), buf, sizeof buf); |
BIO_printf(bio, " i:%s\n", buf); |
BIO_printf(bio, " i:%s\n", buf); |
if (s_client_config.showcerts) |
if (cfg.showcerts) |
PEM_write_bio_X509(bio, |
PEM_write_bio_X509(bio, |
sk_X509_value(sk, i)); |
sk_X509_value(sk, i)); |
} |
} |
|
|
peer = SSL_get_peer_certificate(s); |
peer = SSL_get_peer_certificate(s); |
if (peer != NULL) { |
if (peer != NULL) { |
BIO_printf(bio, "Server certificate\n"); |
BIO_printf(bio, "Server certificate\n"); |
if (!(s_client_config.showcerts && got_a_chain)) { |
if (!(cfg.showcerts && got_a_chain)) { |
/* Redundant if we showed the whole chain */ |
/* Redundant if we showed the whole chain */ |
PEM_write_bio_X509(bio, peer); |
PEM_write_bio_X509(bio, peer); |
} |
} |
|
|
#endif |
#endif |
|
|
SSL_SESSION_print(bio, SSL_get_session(s)); |
SSL_SESSION_print(bio, SSL_get_session(s)); |
if (s_client_config.keymatexportlabel != NULL) { |
if (cfg.keymatexportlabel != NULL) { |
BIO_printf(bio, "Keying material exporter:\n"); |
BIO_printf(bio, "Keying material exporter:\n"); |
BIO_printf(bio, " Label: '%s'\n", |
BIO_printf(bio, " Label: '%s'\n", |
s_client_config.keymatexportlabel); |
cfg.keymatexportlabel); |
BIO_printf(bio, " Length: %i bytes\n", |
BIO_printf(bio, " Length: %i bytes\n", |
s_client_config.keymatexportlen); |
cfg.keymatexportlen); |
exportedkeymat = malloc(s_client_config.keymatexportlen); |
exportedkeymat = malloc(cfg.keymatexportlen); |
if (exportedkeymat != NULL) { |
if (exportedkeymat != NULL) { |
if (!SSL_export_keying_material(s, exportedkeymat, |
if (!SSL_export_keying_material(s, exportedkeymat, |
s_client_config.keymatexportlen, |
cfg.keymatexportlen, |
s_client_config.keymatexportlabel, |
cfg.keymatexportlabel, |
strlen(s_client_config.keymatexportlabel), |
strlen(cfg.keymatexportlabel), |
NULL, 0, 0)) { |
NULL, 0, 0)) { |
BIO_printf(bio, " Error\n"); |
BIO_printf(bio, " Error\n"); |
} else { |
} else { |
BIO_printf(bio, " Keying material: "); |
BIO_printf(bio, " Keying material: "); |
for (i = 0; i < s_client_config.keymatexportlen; i++) |
for (i = 0; i < cfg.keymatexportlen; i++) |
BIO_printf(bio, "%02X", |
BIO_printf(bio, "%02X", |
exportedkeymat[i]); |
exportedkeymat[i]); |
BIO_printf(bio, "\n"); |
BIO_printf(bio, "\n"); |