summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-26 10:33:24 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-07-26 14:23:55 +0200
commit7e051ae28c288c218584f75dbc6c097a3b2564c9 (patch)
tree9456e41b15aac3333770d58715c7487607318af3
parente9b7e84870bc1bfea4969a57d15e523133b46ecb (diff)
downloadgnutls-7e051ae28c288c218584f75dbc6c097a3b2564c9.tar.gz
tools: TLS handling has been incorporated into socket_open()
This is of particular usage to the server IP address loop, since we can detect fast open errors and retry handshake to the next IP address.
-rw-r--r--src/Makefile.am3
-rw-r--r--src/cli-debug.c35
-rw-r--r--src/cli.c58
-rw-r--r--src/common.c22
-rw-r--r--src/common.h2
-rw-r--r--src/danetool.c70
-rw-r--r--src/ocsptool-common.c3
-rw-r--r--src/ocsptool.c10
-rw-r--r--src/socket.c88
-rw-r--r--src/socket.h19
10 files changed, 185 insertions, 125 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 37a9bea71e..182f3a5035 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -96,7 +96,7 @@ libcmd_psk_la_SOURCES = psktool-args.def psktool-args.c psktool-args.h
if ENABLE_OCSP
ocsptool_SOURCES = ocsptool.c ocsptool-common.h ocsptool-common.c \
- socket.c socket.h
+ socket.c common.c common.h socket.h
ocsptool_LDADD = ../lib/libgnutls.la libcmd-ocsp.la $(LIBOPTS) ../gl/libgnu.la
ocsptool_LDADD += $(LTLIBINTL) $(GETADDRINFO_LIB) gl/libgnu_gpl.la $(LIBIDN_LIBS)
noinst_LTLIBRARIES += libcmd-ocsp.la
@@ -105,7 +105,6 @@ libcmd_ocsp_la_SOURCES = ocsptool-args.def ocsptool-args.h ocsptool-args.c
gnutls_serv_SOURCES = \
list.h serv.c \
udp-serv.c udp-serv.h \
- socket.c socket.h \
common.h common.c \
certtool-common.h
gnutls_serv_LDADD = ../lib/libgnutls.la
diff --git a/src/cli-debug.c b/src/cli-debug.c
index 22020eb818..3323b4804e 100644
--- a/src/cli-debug.c
+++ b/src/cli-debug.c
@@ -188,11 +188,28 @@ static const TLS_TEST tls_tests[] = {
const char *ip;
+gnutls_session_t init_tls_session(const char *host)
+{
+ gnutls_session_t state = NULL;
+ gnutls_init(&state, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
+
+ set_read_funcs(state);
+ if (host && is_ip(host) == 0)
+ gnutls_server_name_set(state, GNUTLS_NAME_DNS,
+ host, strlen(host));
+
+ return state;
+}
+
+int do_handshake(socket_st * socket)
+{
+ return 0; /* we do it locally */
+}
+
int main(int argc, char **argv)
{
int ret;
int i;
- gnutls_session_t state;
char portname[6];
socket_st hd;
char app_proto[32] = "";
@@ -268,26 +285,16 @@ int main(int argc, char **argv)
break;
}
- socket_open(&hd, hostname, portname, 0, NULL);
+ socket_open(&hd, hostname, portname, app_proto, SOCKET_FLAG_STARTTLS, NULL, NULL);
hd.verbose = verbose;
- socket_starttls(&hd, app_proto);
-
- gnutls_init(&state, GNUTLS_CLIENT | GNUTLS_NO_EXTENSIONS);
-
- gnutls_transport_set_int(state, hd.fd);
- set_read_funcs(state);
- if (hostname && is_ip(hostname) == 0)
- gnutls_server_name_set(state, GNUTLS_NAME_DNS,
- hostname, strlen(hostname));
-
do {
if (strcmp(app_proto, "https") != 0 && tls_tests[i].https_only != 0) {
i++;
break;
}
- ret = tls_tests[i].func(state);
+ ret = tls_tests[i].func(hd.session);
if (ret != TEST_IGNORE) {
printf("%58s...", tls_tests[i].test_name);
@@ -313,8 +320,6 @@ int main(int argc, char **argv)
while (ret == TEST_IGNORE
&& tls_tests[i].test_name != NULL);
- gnutls_deinit(state);
-
socket_bye(&hd);
i++;
diff --git a/src/cli.c b/src/cli.c
index 98d1c598e0..93d6fc65e8 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -121,7 +121,6 @@ static gnutls_certificate_credentials_t xcred;
/* prototypes */
static void check_rehandshake(socket_st * socket, int ret);
-static int do_handshake(socket_st * socket);
static void init_global_tls_stuff(void);
static int cert_verify_ocsp(gnutls_session_t session);
@@ -660,7 +659,7 @@ cert_callback(gnutls_session_t session,
/* initializes a gnutls_session_t with some defaults.
*/
-static gnutls_session_t init_tls_session(const char *host)
+gnutls_session_t init_tls_session(const char *host)
{
const char *err;
int ret;
@@ -892,7 +891,7 @@ static int try_rehandshake(socket_st * hd)
static int try_resume(socket_st * hd)
{
- int ret;
+ int ret, socket_flags = 0;
gnutls_datum_t rdata = {NULL, 0};
if (gnutls_session_is_resumed(hd->session) == 0) {
@@ -915,25 +914,15 @@ static int try_resume(socket_st * hd)
printf
("\n\n- Connecting again- trying to resume previous session\n");
- socket_open(hd, hostname, service, udp | (fastopen << 1), CONNECT_MSG);
-
if (HAVE_OPT(STARTTLS_PROTO))
- socket_starttls(hd, OPT_ARG(STARTTLS_PROTO));
+ socket_flags |= SOCKET_FLAG_STARTTLS;
+ else if (fastopen)
+ socket_flags |= SOCKET_FLAG_FASTOPEN;
- hd->session = init_tls_session(hostname);
- if (rdata.data) {
- hd->rdata.data = rdata.data;
- hd->rdata.size = rdata.size;
+ if (udp)
+ socket_flags |= SOCKET_FLAG_UDP;
- gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size);
- }
-
- ret = do_handshake(hd);
- if (ret < 0) {
- fprintf(stderr, "*** Resume handshake has failed\n");
- gnutls_perror(ret);
- return ret;
- }
+ socket_open(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), socket_flags, CONNECT_MSG, &rdata);
printf("- Resume Handshake was completed\n");
if (gnutls_session_is_resumed(hd->session) != 0)
@@ -1193,6 +1182,7 @@ int main(int argc, char **argv)
char *keyboard_buffer_ptr;
inline_cmds_st inline_cmds;
unsigned last_op_is_write = 0;
+ int socket_flags = 0;
#ifndef _WIN32
struct sigaction new_action;
#endif
@@ -1218,26 +1208,15 @@ int main(int argc, char **argv)
canonicalize_host(hostname, service, sizeof(service));
- socket_open(&hd, hostname, service, udp | (fastopen << 1), CONNECT_MSG);
- hd.verbose = verbose;
-
- if (HAVE_OPT(STARTTLS_PROTO))
- socket_starttls(&hd, OPT_ARG(STARTTLS_PROTO));
-
- hd.session = init_tls_session(hostname);
+ if (udp)
+ socket_flags |= SOCKET_FLAG_UDP;
+ if (fastopen)
+ socket_flags |= SOCKET_FLAG_FASTOPEN;
if (starttls)
- goto after_handshake;
-
- ret = do_handshake(&hd);
+ socket_flags |= SOCKET_FLAG_STARTTLS;
- if (ret < 0) {
- fprintf(stderr, "*** Handshake has failed\n");
- gnutls_perror(ret);
- print_other_info(hd.session);
- gnutls_deinit(hd.session);
- return 1;
- } else
- printf("- Handshake was completed\n");
+ socket_open(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO), socket_flags, CONNECT_MSG, NULL);
+ hd.verbose = verbose;
if (resume != 0)
if (try_resume(&hd))
@@ -1245,8 +1224,6 @@ int main(int argc, char **argv)
print_other_info(hd.session);
- after_handshake:
-
/* Warning! Do not touch this text string, it is used by external
programs to search for when gnutls-cli has reached this point. */
printf("\n- Simple Client Mode:\n\n");
@@ -1670,7 +1647,7 @@ static void check_rehandshake(socket_st * socket, int ret)
}
-static int do_handshake(socket_st * socket)
+int do_handshake(socket_st * socket)
{
int ret;
@@ -1680,7 +1657,6 @@ static int do_handshake(socket_st * socket)
socket->connect_addrlen);
socket->connect_addrlen = 0;
} else {
- gnutls_transport_set_int(socket->session, socket->fd);
set_read_funcs(socket->session);
}
diff --git a/src/common.c b/src/common.c
index 066022f00d..15376d4b05 100644
--- a/src/common.c
+++ b/src/common.c
@@ -37,6 +37,13 @@
#include <gnutls/crypto.h>
#include <time.h>
#include <common.h>
+#include <unistd.h>
+
+#ifndef _WIN32
+# include <signal.h>
+#else
+#include <ws2tcpip.h>
+#endif
#ifdef ENABLE_PKCS11
#include <gnutls/pkcs11.h>
@@ -1124,3 +1131,18 @@ void pkcs11_common(common_info_st *c)
}
#endif
+
+void sockets_init(void)
+{
+#ifdef _WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(1, 1);
+ if (WSAStartup(wVersionRequested, &wsaData) != 0) {
+ perror("WSA_STARTUP_ERROR");
+ }
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif
+}
diff --git a/src/common.h b/src/common.h
index 7c14434b95..8cd321e040 100644
--- a/src/common.h
+++ b/src/common.h
@@ -87,6 +87,8 @@ int len = strlen(hostname);
return 0;
}
+void sockets_init(void);
+
#ifdef _WIN32
static int system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
{
diff --git a/src/danetool.c b/src/danetool.c
index bdccbb3c8b..4c35964178 100644
--- a/src/danetool.c
+++ b/src/danetool.c
@@ -614,23 +614,18 @@ static int cert_callback(gnutls_session_t session)
return -1;
}
-static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd)
+static gnutls_certificate_credentials_t xcred;
+static int file_fd = -1;
+static unsigned udp = 0;
+
+gnutls_session_t init_tls_session(const char *hostname)
{
- gnutls_certificate_credentials_t xcred;
gnutls_session_t session;
int ret;
- struct priv_st priv;
+ static struct priv_st priv;
priv.found = 0;
- priv.fd = fd;
-
- ret = gnutls_certificate_allocate_credentials(&xcred);
- if (ret < 0) {
- fprintf(stderr, "error[%d]: %s\n", __LINE__,
- gnutls_strerror(ret));
- exit(1);
- }
- gnutls_certificate_set_verify_function(xcred, cert_callback);
+ priv.fd = file_fd;
ret = gnutls_init(&session, (udp?GNUTLS_DATAGRAM:0)|GNUTLS_CLIENT);
if (ret < 0) {
@@ -639,7 +634,6 @@ static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd)
exit(1);
}
gnutls_session_set_ptr(session, &priv);
- gnutls_transport_set_int(session, hd->fd);
gnutls_set_default_priority(session);
if (hostname && is_ip(hostname)==0) {
@@ -647,29 +641,40 @@ static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd)
}
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+ return session;
+}
+
+int do_handshake(socket_st * socket)
+{
+ int ret;
+
do {
- ret = gnutls_handshake(session);
+ ret = gnutls_handshake(socket->session);
} while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED);
/* we don't care on the result */
- gnutls_deinit(session);
- gnutls_certificate_free_credentials(xcred);
-
- if (priv.found == 0)
- return -1;
-
return 0;
}
+
static const char *obtain_cert(const char *hostname, const char *proto, const char *service,
const char *app_proto, unsigned quiet)
{
socket_st hd;
const char *txt_service;
- unsigned udp = 0;
static char tmpfile[32];
- int fd, ret;
+ int ret;
const char *str = "Obtaining certificate from";
+ int socket_flags = 0;
+ struct priv_st *priv;
+
+ ret = gnutls_certificate_allocate_credentials(&xcred);
+ if (ret < 0) {
+ fprintf(stderr, "error[%d]: %s\n", __LINE__,
+ gnutls_strerror(ret));
+ exit(1);
+ }
+ gnutls_certificate_set_verify_function(xcred, cert_callback);
if (strcmp(proto, "udp") == 0)
udp = 1;
@@ -685,24 +690,33 @@ static const char *obtain_cert(const char *hostname, const char *proto, const ch
if (quiet)
str = NULL;
- socket_open(&hd, hostname, txt_service, udp, str);
if (app_proto == NULL) app_proto = txt_service;
- socket_starttls(&hd, app_proto);
+
+ if (udp)
+ socket_flags |= SOCKET_FLAG_UDP;
+
umask(066);
- fd = mkstemp(tmpfile);
- if (fd == -1) {
+ file_fd = mkstemp(tmpfile);
+ if (file_fd == -1) {
int e = errno;
fprintf(stderr, "error[%d]: %s\n", __LINE__,
strerror(e));
exit(1);
}
- ret = get_cert(&hd, hostname, udp, fd);
- close(fd);
+ socket_open(&hd, hostname, txt_service, app_proto, socket_flags|SOCKET_FLAG_STARTTLS, str, NULL);
+
+ close(file_fd);
+
+ ret = 0;
+ priv = gnutls_session_get_ptr(hd.session);
+ if (priv->found == 0)
+ ret = -1;
socket_bye(&hd);
+ gnutls_certificate_free_credentials(xcred);
if (ret == -1)
return NULL;
diff --git a/src/ocsptool-common.c b/src/ocsptool-common.c
index beab82b27a..5ab753cf84 100644
--- a/src/ocsptool-common.c
+++ b/src/ocsptool-common.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include "common.h"
#include <gnutls/gnutls.h>
#include <gnutls/ocsp.h>
@@ -204,7 +205,7 @@ int send_ocsp_request(const char *server,
(unsigned int) req.size);
headers_size = strlen(headers);
- socket_open(&hd, hostname, service, 0, CONNECT_MSG);
+ socket_open(&hd, hostname, service, NULL, SOCKET_FLAG_RAW, CONNECT_MSG, NULL);
socket_send(&hd, headers, headers_size);
socket_send(&hd, req.data, req.size);
diff --git a/src/ocsptool.c b/src/ocsptool.c
index 5ada2003c2..9493a8d436 100644
--- a/src/ocsptool.c
+++ b/src/ocsptool.c
@@ -47,6 +47,16 @@ static void tls_log_func(int level, const char *str)
fprintf(stderr, "|<%d>| %s", level, str);
}
+gnutls_session_t init_tls_session(const char *host)
+{
+ return NULL;
+}
+
+int do_handshake(socket_st * socket)
+{
+ return -1;
+}
+
static void request_info(void)
{
gnutls_ocsp_req_t req;
diff --git a/src/socket.c b/src/socket.c
index 35fd61534e..aae9ee7403 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2000-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2000-2016 Free Software Foundation, Inc.
+ * Copyright (C) 2015-2016 Red Hat, Inc.
*
* This file is part of GnuTLS.
*
@@ -201,18 +202,18 @@ ssize_t wait_for_text(socket_st * socket, const char *txt, unsigned txt_size)
return ret;
}
-void
-socket_starttls(socket_st * socket, const char *app_proto)
+static void
+socket_starttls(socket_st * socket)
{
char buf[512];
if (socket->secure)
return;
- if (app_proto == NULL || strcasecmp(app_proto, "https") == 0)
+ if (socket->app_proto == NULL || strcasecmp(socket->app_proto, "https") == 0)
return;
- if (strcasecmp(app_proto, "smtp") == 0 || strcasecmp(app_proto, "submission") == 0) {
+ if (strcasecmp(socket->app_proto, "smtp") == 0 || strcasecmp(socket->app_proto, "submission") == 0) {
if (socket->verbose)
printf("Negotiating SMTP STARTTLS\n");
@@ -222,7 +223,7 @@ socket_starttls(socket_st * socket, const char *app_proto)
wait_for_text(socket, "250 ", 4);
send_line(socket, "STARTTLS\n");
wait_for_text(socket, "220 ", 4);
- } else if (strcasecmp(app_proto, "imap") == 0 || strcasecmp(app_proto, "imap2") == 0) {
+ } else if (strcasecmp(socket->app_proto, "imap") == 0 || strcasecmp(socket->app_proto, "imap2") == 0) {
if (socket->verbose)
printf("Negotiating IMAP STARTTLS\n");
@@ -230,7 +231,7 @@ socket_starttls(socket_st * socket, const char *app_proto)
wait_for_text(socket, "a OK", 4);
send_line(socket, "a STARTTLS\r\n");
wait_for_text(socket, "a OK", 4);
- } else if (strcasecmp(app_proto, "xmpp") == 0) {
+ } else if (strcasecmp(socket->app_proto, "xmpp") == 0) {
if (socket->verbose)
printf("Negotiating XMPP STARTTLS\n");
@@ -239,13 +240,13 @@ socket_starttls(socket_st * socket, const char *app_proto)
wait_for_text(socket, "<?", 2);
send_line(socket, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
wait_for_text(socket, "<proceed", 8);
- } else if (strcasecmp(app_proto, "ldap") == 0) {
+ } else if (strcasecmp(socket->app_proto, "ldap") == 0) {
if (socket->verbose)
printf("Negotiating LDAP STARTTLS\n");
#define LDAP_STR "\x30\x1d\x02\x01\x01\x77\x18\x80\x16\x31\x2e\x33\x2e\x36\x2e\x31\x2e\x34\x2e\x31\x2e\x31\x34\x36\x36\x2e\x32\x30\x30\x33\x37"
send(socket->fd, LDAP_STR, sizeof(LDAP_STR)-1, 0);
wait_for_text(socket, NULL, 0);
- } else if (strcasecmp(app_proto, "ftp") == 0 || strcasecmp(app_proto, "ftps") == 0) {
+ } else if (strcasecmp(socket->app_proto, "ftp") == 0 || strcasecmp(socket->app_proto, "ftps") == 0) {
if (socket->verbose)
printf("Negotiating FTP STARTTLS\n");
@@ -254,10 +255,10 @@ socket_starttls(socket_st * socket, const char *app_proto)
send_line(socket, "AUTH TLS\r\n");
wait_for_text(socket, "234", 3);
} else {
- if (!c_isdigit(app_proto[0])) {
+ if (!c_isdigit(socket->app_proto[0])) {
static int warned = 0;
if (warned == 0) {
- fprintf(stderr, "unknown protocol '%s'\n", app_proto);
+ fprintf(stderr, "unknown protocol '%s'\n", socket->app_proto);
warned = 1;
}
}
@@ -309,7 +310,7 @@ void socket_bye(socket_st * socket)
ret = gnutls_bye(socket->session, GNUTLS_SHUT_WR);
while (ret == GNUTLS_E_INTERRUPTED
|| ret == GNUTLS_E_AGAIN);
- if (ret < 0)
+ if (socket->verbose && ret < 0)
fprintf(stderr, "*** gnutls_bye() error: %s\n",
gnutls_strerror(ret));
gnutls_deinit(socket->session);
@@ -352,20 +353,26 @@ void canonicalize_host(char *hostname, char *service, unsigned service_size)
snprintf(service, service_size, "%s", p+1);
}
+
void
socket_open(socket_st * hd, const char *hostname, const char *service,
- int flags, const char *msg)
+ const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata)
{
struct addrinfo hints, *res, *ptr;
int sd, err = 0;
- int udp = flags & 1;
- int fastopen = flags & 2;
+ int udp = flags & SOCKET_FLAG_UDP;
+ int fastopen = flags & SOCKET_FLAG_FASTOPEN;
char buffer[MAX_BUF + 1];
char portname[16] = { 0 };
char *a_hostname = (char*)hostname;
memset(hd, 0, sizeof(*hd));
+ if (rdata) {
+ hd->rdata.data = rdata->data;
+ hd->rdata.size = rdata->size;
+ }
+
#ifdef HAVE_LIBIDN
err = idna_to_ascii_8z(hostname, &a_hostname, IDNA_ALLOW_UNASSIGNED);
if (err != IDNA_SUCCESS) {
@@ -374,6 +381,7 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
exit(1);
}
#endif
+ hd->hostname = strdup(hostname);
if (msg != NULL)
printf("Resolving '%s:%s'...\n", a_hostname,service);
@@ -426,6 +434,7 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
if (msg)
printf("%s '%s:%s' (TFO)...\n", msg, buffer, portname);
+
} else {
if (msg)
printf("%s '%s:%s'...\n", msg, buffer, portname);
@@ -434,6 +443,32 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
continue;
}
+ if (!(flags & SOCKET_FLAG_RAW)) {
+ if (flags & SOCKET_FLAG_STARTTLS) {
+ socket_starttls(hd);
+ }
+
+ hd->session = init_tls_session(hostname);
+ if (hd->rdata.data) {
+ gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size);
+ }
+
+ hd->fd = sd;
+ gnutls_transport_set_int(hd->session, sd);
+
+ err = do_handshake(hd);
+ if (err == GNUTLS_E_PUSH_ERROR) { /* failed connecting */
+ gnutls_deinit(hd->session);
+ hd->session = NULL;
+ continue;
+ }
+ else if (err < 0) {
+ fprintf(stderr, "*** handshake has failed: %s\n", gnutls_strerror(err));
+ exit(1);
+ } else if (hd->verbose)
+ printf("- Handshake was completed\n");
+ }
+
break;
}
@@ -449,9 +484,12 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
exit(1);
}
- hd->secure = 0;
+ if (flags & SOCKET_FLAG_RAW)
+ hd->secure = 0;
+ else
+ hd->secure = 1;
+
hd->fd = sd;
- hd->hostname = strdup(hostname);
hd->ip = strdup(buffer);
hd->service = strdup(portname);
hd->ptr = ptr;
@@ -463,22 +501,6 @@ socket_open(socket_st * hd, const char *hostname, const char *service,
return;
}
-void sockets_init(void)
-{
-#ifdef _WIN32
- WORD wVersionRequested;
- WSADATA wsaData;
-
- wVersionRequested = MAKEWORD(1, 1);
- if (WSAStartup(wVersionRequested, &wsaData) != 0) {
- perror("WSA_STARTUP_ERROR");
- }
-#else
- signal(SIGPIPE, SIG_IGN);
-#endif
-
-}
-
/* converts a textual service or port to
* a service.
*/
diff --git a/src/socket.h b/src/socket.h
index 1f1394f812..55e7230300 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -1,11 +1,18 @@
#include <gnutls/gnutls.h>
#include <gnutls/socket.h>
+#define SOCKET_FLAG_UDP 1
+#define SOCKET_FLAG_FASTOPEN (1<<1)
+#define SOCKET_FLAG_STARTTLS (1<<2)
+#define SOCKET_FLAG_RAW (1<<3) /* unencrypted */
+
+
typedef struct {
int fd;
gnutls_session_t session;
int secure;
char *hostname;
+ const char *app_proto;
char *ip;
char *service;
struct addrinfo *ptr;
@@ -20,6 +27,10 @@ typedef struct {
gnutls_datum_t rdata;
} socket_st;
+/* calling program must provide that */
+extern gnutls_session_t init_tls_session(const char *host);
+extern int do_handshake(socket_st * socket);
+
ssize_t socket_recv(const socket_st * socket, void *buffer,
int buffer_size);
ssize_t socket_recv_timeout(const socket_st * socket, void *buffer,
@@ -28,14 +39,12 @@ ssize_t socket_send(const socket_st * socket, const void *buffer,
int buffer_size);
ssize_t socket_send_range(const socket_st * socket, const void *buffer,
int buffer_size, gnutls_range_st * range);
-void socket_open(socket_st * hd, const char *hostname, const char *service,
- int flags, const char *msg);
+void
+socket_open(socket_st * hd, const char *hostname, const char *service,
+ const char *app_proto, int flags, const char *msg, gnutls_datum_t *rdata);
-void socket_starttls(socket_st * hd, const char *app_proto);
void socket_bye(socket_st * socket);
-void sockets_init(void);
-
int service_to_port(const char *service, const char *proto);
const char *port_to_service(const char *sport, const char *proto);
int starttls_proto_to_port(const char *app_proto);