aboutsummaryrefslogtreecommitdiff
path: root/apps/s_server.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2016-02-03 00:47:42 +0100
committerRichard Levitte <levitte@openssl.org>2016-02-03 20:36:49 +0100
commitab69ac00f3c7a04151662813794ac82bc591a89b (patch)
tree8f06f8c8c3b867449d621d3394c9da301e5e751a /apps/s_server.c
parentd858c87653257185ead1c5baf3d84cd7276dd912 (diff)
downloadopenssl-ab69ac00f3c7a04151662813794ac82bc591a89b.zip
openssl-ab69ac00f3c7a04151662813794ac82bc591a89b.tar.gz
openssl-ab69ac00f3c7a04151662813794ac82bc591a89b.tar.bz2
Refactoring BIO: Adapt s_client and s_server
s_socket.c gets brutally cleaned out and now consists of only two functions, one for client and the other for server. They both handle AF_INET, AF_INET6 and additionally AF_UNIX where supported. The rest is just easy adaptation. Both s_client and s_server get the new flags -4 and -6 to force the use of IPv4 or IPv6 only. Also, the default host "localhost" in s_client is removed. It's not certain that this host is set up for both IPv4 and IPv6. For example, Debian has "ip6-localhost" as the default hostname for [::1]. The better way is to default |host| to NULL and rely on BIO_lookup() to return a BIO_ADDRINFO with the appropriate loopback address for IPv4 or IPv6 as indicated by the |family| parameter. Reviewed-by: Kurt Roeckx <kurt@openssl.org>
Diffstat (limited to 'apps/s_server.c')
-rw-r--r--apps/s_server.c131
1 files changed, 94 insertions, 37 deletions
diff --git a/apps/s_server.c b/apps/s_server.c
index 848ba1f..1a54f08 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -191,9 +191,12 @@ typedef unsigned int u_int;
#endif
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
-static int sv_body(char *hostname, int s, int stype, unsigned char *context);
-static int www_body(char *hostname, int s, int stype, unsigned char *context);
-static int rev_body(char *hostname, int s, int stype, unsigned char *context);
+static int sv_body(const char *hostname, int s, int stype,
+ unsigned char *context);
+static int www_body(const char *hostname, int s, int stype,
+ unsigned char *context);
+static int rev_body(const char *hostname, int s, int stype,
+ unsigned char *context);
static void close_accept_socket(void);
static int init_ssl_connection(SSL *s);
static void print_stats(BIO *bp, SSL_CTX *ctx);
@@ -791,8 +794,8 @@ static char *srtp_profiles = NULL;
#endif
typedef enum OPTION_choice {
- OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
- OPT_ENGINE, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
+ OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
+ OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
@@ -821,9 +824,13 @@ typedef enum OPTION_choice {
OPTIONS s_server_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"port", OPT_PORT, 'p'},
- {"accept", OPT_PORT, 'p',
- "TCP/IP port to accept on (default is " PORT_STR ")"},
+ {"accept", OPT_ACCEPT, 's',
+ "TCP/IP port or service to accept on (default is " PORT ")"},
+#ifdef AF_UNIX
{"unix", OPT_UNIX, 's', "Unix domain socket to accept on"},
+#endif
+ {"4", OPT_4, '-', "Use IPv4 only"},
+ {"6", OPT_6, '-', "Use IPv6 only"},
{"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"},
{"context", OPT_CONTEXT, 's', "Set session ID context"},
{"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"},
@@ -998,11 +1005,10 @@ int s_server_main(int argc, char *argv[])
#ifndef OPENSSL_NO_PSK
char *p;
#endif
- const char *unix_path = NULL;
-#ifndef NO_SYS_UN_H
+#ifdef AF_UNIX
int unlink_unix_path = 0;
#endif
- int (*server_cb) (char *hostname, int s, int stype,
+ int (*server_cb) (const char *hostname, int s, int stype,
unsigned char *context);
int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0;
#ifndef OPENSSL_NO_DH
@@ -1012,9 +1018,11 @@ int s_server_main(int argc, char *argv[])
int noCApath = 0, noCAfile = 0;
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
- int rev = 0, naccept = -1, sdebug = 0, socket_type = SOCK_STREAM;
+ int rev = 0, naccept = -1, sdebug = 0;
+ int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
- unsigned short port = PORT;
+ char *host = NULL;
+ char *port = BUF_strdup(PORT);
unsigned char *context = NULL;
OPTION_CHOICE o;
EVP_PKEY *s_key2 = NULL;
@@ -1059,26 +1067,71 @@ int s_server_main(int argc, char *argv[])
ret = 0;
goto end;
+ case OPT_4:
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX) {
+ OPENSSL_free(host); host = NULL;
+ OPENSSL_free(port); port = NULL;
+ }
+#endif
+ socket_family = AF_INET;
+ break;
+ case OPT_6:
+ if (1) {
+#ifdef AF_INET6
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX) {
+ OPENSSL_free(host); host = NULL;
+ OPENSSL_free(port); port = NULL;
+ }
+#endif
+ socket_family = AF_INET6;
+ } else {
+#endif
+ BIO_printf(bio_err, "%s: IPv6 domain sockets unsupported\n", prog);
+ goto end;
+ }
+ break;
case OPT_PORT:
- if (!extract_port(opt_arg(), &port))
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX) {
+ socket_family = AF_UNSPEC;
+ }
+#endif
+ OPENSSL_free(port); port = NULL;
+ OPENSSL_free(host); host = NULL;
+ if (BIO_parse_hostserv(opt_arg(), NULL, &port, BIO_PARSE_PRIO_SERV) < 1) {
+ BIO_printf(bio_err,
+ "%s: -port argument malformed or ambiguous\n",
+ port);
+ goto end;
+ }
+ break;
+ case OPT_ACCEPT:
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX) {
+ socket_family = AF_UNSPEC;
+ }
+#endif
+ OPENSSL_free(port); port = NULL;
+ OPENSSL_free(host); host = NULL;
+ if (BIO_parse_hostserv(opt_arg(), &host, &port, BIO_PARSE_PRIO_SERV) < 1) {
+ BIO_printf(bio_err,
+ "%s: -accept argument malformed or ambiguous\n",
+ port);
goto end;
+ }
break;
+#ifdef AF_UNIX
case OPT_UNIX:
-#ifdef NO_SYS_UN_H
- BIO_printf(bio_err, "unix domain sockets unsupported\n");
- goto end;
-#else
- unix_path = opt_arg();
-#endif
+ socket_family = AF_UNIX;
+ OPENSSL_free(host); host = BUF_strdup(opt_arg());
+ OPENSSL_free(port); port = NULL;
break;
case OPT_UNLINK:
-#ifdef NO_SYS_UN_H
- BIO_printf(bio_err, "unix domain sockets unsupported\n");
- goto end;
-#else
unlink_unix_path = 1;
-#endif
break;
+#endif
case OPT_NACCEPT:
naccept = atol(opt_arg());
break;
@@ -1462,11 +1515,13 @@ int s_server_main(int argc, char *argv[])
}
#endif
- if (unix_path && (socket_type != SOCK_STREAM)) {
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) {
BIO_printf(bio_err,
"Can't use unix sockets and datagrams together\n");
goto end;
}
+#endif
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
if (jpake_secret) {
if (psk_key) {
@@ -1929,16 +1984,13 @@ int s_server_main(int argc, char *argv[])
server_cb = www_body;
else
server_cb = sv_body;
-#ifndef NO_SYS_UN_H
- if (unix_path) {
- if (unlink_unix_path)
- unlink(unix_path);
- do_server_unix(unix_path, &accept_socket, server_cb, context,
- naccept);
- } else
+#ifdef AF_UNIX
+ if (socket_family == AF_UNIX
+ && unlink_unix_path)
+ unlink(host);
#endif
- do_server(port, socket_type, &accept_socket, server_cb, context,
- naccept);
+ do_server(&accept_socket, host, port, socket_family, socket_type,
+ server_cb, context, naccept);
print_stats(bio_s_out, ctx);
ret = 0;
end:
@@ -1952,6 +2004,8 @@ int s_server_main(int argc, char *argv[])
sk_X509_pop_free(s_dchain, X509_free);
OPENSSL_free(pass);
OPENSSL_free(dpass);
+ OPENSSL_free(host);
+ OPENSSL_free(port);
X509_VERIFY_PARAM_free(vpm);
free_sessions();
OPENSSL_free(tlscstatp.host);
@@ -2006,7 +2060,8 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
SSL_CTX_sess_get_cache_size(ssl_ctx));
}
-static int sv_body(char *hostname, int s, int stype, unsigned char *context)
+static int sv_body(const char *hostname, int s, int stype,
+ unsigned char *context)
{
char *buf = NULL;
fd_set readfds;
@@ -2599,7 +2654,8 @@ static DH *load_dh_param(const char *dhfile)
}
#endif
-static int www_body(char *hostname, int s, int stype, unsigned char *context)
+static int www_body(const char *hostname, int s, int stype,
+ unsigned char *context)
{
char *buf = NULL;
int ret = 1;
@@ -2986,7 +3042,8 @@ static int www_body(char *hostname, int s, int stype, unsigned char *context)
return (ret);
}
-static int rev_body(char *hostname, int s, int stype, unsigned char *context)
+static int rev_body(const char *hostname, int s, int stype,
+ unsigned char *context)
{
char *buf = NULL;
int i;