File stunnel-CVE-2015-3644.patch of Package stunnel.6450
diff -u -r stunnel-5.00-orig/src/client.c stunnel-5.00-patched/src/client.c
--- stunnel-5.00-orig/src/client.c 2014-03-06 00:25:00.000000000 +0100
+++ stunnel-5.00-patched/src/client.c 2015-05-26 10:44:03.219628792 +0200
@@ -75,6 +75,7 @@
c->opt=opt;
c->local_rfd.fd=rfd;
c->local_wfd.fd=wfd;
+ c->redirect=REDIRECT_OFF;
return c;
}
@@ -142,9 +143,17 @@
c->fd=-1;
c->ssl=NULL;
c->sock_bytes=c->ssl_bytes=0;
+ if(c->opt->option.client) {
+ c->sock_rfd=&(c->local_rfd);
+ c->sock_wfd=&(c->local_wfd);
+ c->ssl_rfd=c->ssl_wfd=&(c->remote_fd);
+ } else {
+ c->sock_rfd=c->sock_wfd=&(c->remote_fd);
+ c->ssl_rfd=&(c->local_rfd);
+ c->ssl_wfd=&(c->local_wfd);
+ }
c->fds=s_poll_alloc();
- c->connect_addr.num=0;
- c->connect_addr.addr=NULL;
+ addrlist_init(&c->connect_addr, 1);
err=setjmp(c->err);
if(!err)
@@ -207,9 +216,9 @@
c->opt->servname, num_clients_copy);
#endif
- /* free remaining memory structures */
- if(c->connect_addr.addr)
- str_free(c->connect_addr.addr);
+ /* free the client context */
+ str_free(c->connect_addr.addr);
+
s_poll_free(c->fds);
c->fds=NULL;
}
@@ -365,17 +374,6 @@
SSL_set_accept_state(c->ssl);
}
- /* setup some values for transfer() function */
- if(c->opt->option.client) {
- c->sock_rfd=&(c->local_rfd);
- c->sock_wfd=&(c->local_wfd);
- c->ssl_rfd=c->ssl_wfd=&(c->remote_fd);
- } else {
- c->sock_rfd=c->sock_wfd=&(c->remote_fd);
- c->ssl_rfd=&(c->local_rfd);
- c->ssl_wfd=&(c->local_wfd);
- }
-
unsafe_openssl=SSLeay()<0x0090810fL ||
(SSLeay()>=0x10000000L && SSLeay()<0x1000002fL);
while(1) {
@@ -435,21 +433,31 @@
sslerror("SSL_accept");
longjmp(c->err, 1);
}
+ s_log(LOG_INFO, "SSL %s: %s",
+ c->opt->option.client ? "connected" : "accepted",
+ SSL_session_reused(c->ssl) ?
+ "previous session reused" : "new session negotiated");
if(SSL_session_reused(c->ssl)) {
- s_log(LOG_INFO, "SSL %s: previous session reused",
- c->opt->option.client ? "connected" : "accepted");
+ c->redirect=(uintptr_t)SSL_SESSION_get_ex_data(SSL_get_session(c->ssl),
+ redirect_index);
+ if(c->opt->redirect_addr.names && !c->redirect) {
+ s_log(LOG_ERR, "No application data found in the reused session");
+ longjmp(c->err, 1);
+ }
} else { /* a new session was negotiated */
new_chain(c);
+ SSL_SESSION_set_ex_data(SSL_get_session(c->ssl),
+ redirect_index, (void *)c->redirect);
if(c->opt->option.client) {
- s_log(LOG_INFO, "SSL connected: new session negotiated");
enter_critical_section(CRIT_SESSION);
old_session=c->opt->session;
c->opt->session=SSL_get1_session(c->ssl); /* store it */
if(old_session)
SSL_SESSION_free(old_session); /* release the old one */
leave_critical_section(CRIT_SESSION);
- } else
- s_log(LOG_INFO, "SSL accepted: new session negotiated");
+ } else { /* SSL server */
+ SSL_CTX_add_session(c->opt->ctx, SSL_get_session(c->ssl));
+ }
print_cipher(c);
}
}
@@ -679,6 +687,24 @@
}
}
+ /****************************** write to socket */
+ if(sock_open_wr && sock_can_wr) {
+ num=writesocket(c->sock_wfd->fd, c->ssl_buff, c->ssl_ptr);
+ switch(num) {
+ case -1: /* error */
+ if(parse_socket_error(c, "writesocket"))
+ break; /* a non-critical error: retry */
+ sock_open_rd=sock_open_wr=0;
+ break;
+ default:
+ memmove(c->ssl_buff, c->ssl_buff+num, c->ssl_ptr-num);
+ c->ssl_ptr-=num;
+ memset(c->ssl_buff+c->ssl_ptr, 0, num); /* paranoia */
+ c->sock_bytes+=num;
+ watchdog=0; /* reset watchdog */
+ }
+ }
+
/****************************** read from socket */
if(sock_open_rd && sock_can_rd) {
num=readsocket(c->sock_rfd->fd,
@@ -699,23 +725,6 @@
}
}
- /****************************** write to socket */
- if(sock_open_wr && sock_can_wr) {
- num=writesocket(c->sock_wfd->fd, c->ssl_buff, c->ssl_ptr);
- switch(num) {
- case -1: /* error */
- if(parse_socket_error(c, "writesocket"))
- break; /* a non-critical error: retry */
- sock_open_rd=sock_open_wr=0;
- break;
- default:
- memmove(c->ssl_buff, c->ssl_buff+num, c->ssl_ptr-num);
- c->ssl_ptr-=num;
- c->sock_bytes+=num;
- watchdog=0; /* reset watchdog */
- }
- }
-
/****************************** update *_wants_* based on new *_ptr */
/* this update is also required for SSL_pending() to be used */
read_wants_read=!(SSL_get_shutdown(c->ssl)&SSL_RECEIVED_SHUTDOWN)
@@ -1153,6 +1162,10 @@
int fd, ind_start, ind_try, ind_cur;
setup_connect_addr(c);
+ if(!c->connect_addr.num) {
+ s_log(LOG_ERR, "No host resolved");
+ longjmp(c->err, 1);
+ }
ind_start=c->connect_addr.cur;
/* the race condition here can be safely ignored */
if(c->opt->failover==FAILOVER_RR)
@@ -1188,13 +1201,21 @@
socklen_t addrlen=sizeof(SOCKADDR_UNION);
#endif /* SO_ORIGINAL_DST */
- /* check if the address was already set by the verify callback,
- * or a dynamic protocol
- * implemented protocols: CONNECT
- * protocols to be implemented: SOCKS4 */
+ /* process "redirect" first */
+ if(c->redirect==REDIRECT_ON) {
+ s_log(LOG_NOTICE, "Redirecting connection");
+ if(c->connect_addr.addr) /* allocated in protocol negotiations */
+ str_free(c->connect_addr.addr);
+ addrlist_dup(&c->connect_addr, &c->opt->redirect_addr);
+ return;
+ }
+
+ /* check if the address was already set in protocol negotiations */
+ /* used by the following protocols: CONNECT */
if(c->connect_addr.num)
return;
+ /* transparent destination */
#ifdef SO_ORIGINAL_DST
if(c->opt->option.transparent_dst) {
c->connect_addr.num=1;
@@ -1207,19 +1228,8 @@
return;
}
#endif /* SO_ORIGINAL_DST */
-
- if(c->opt->connect_addr.num) { /* pre-resolved addresses */
- addrlist_dup(&c->connect_addr, &c->opt->connect_addr);
- return;
- }
-
- /* delayed lookup */
- if(namelist2addrlist(&c->connect_addr,
- c->opt->connect_list, DEFAULT_LOOPBACK))
- return;
-
- s_log(LOG_ERR, "No host resolved");
- longjmp(c->err, 1);
+ /* default "connect" target */
+ addrlist_dup(&c->connect_addr, &c->opt->connect_addr);
}
NOEXPORT void local_bind(CLI *c) {
diff -u -r stunnel-5.00-orig/src/options.c stunnel-5.00-patched/src/options.c
--- stunnel-5.00-orig/src/options.c 2015-05-26 10:42:20.431950948 +0200
+++ stunnel-5.00-patched/src/options.c 2015-05-26 10:42:55.651896451 +0200
@@ -85,6 +85,8 @@
#endif
NOEXPORT void print_syntax(void);
+
+NOEXPORT void name_list_append(NAME_LIST **, char *);
#ifndef USE_WIN32
NOEXPORT char **argalloc(char *);
#endif
@@ -805,7 +807,6 @@
char *opt, char *arg) {
char *tmpstr;
int tmpnum, endpoints=0;
- NAME_LIST *tmplist;
if(cmd==CMD_DEFAULT || cmd==CMD_HELP) {
s_log(LOG_NOTICE, " ");
@@ -991,23 +992,18 @@
switch(cmd) {
case CMD_BEGIN:
section->option.remote=0;
- section->connect_list=NULL;
- section->connect_addr.num=0;
+ addrlist_init(§ion->connect_addr, 1);
break;
case CMD_EXEC:
if(strcasecmp(opt, "connect"))
break;
section->option.remote=1;
- tmplist=str_alloc(sizeof(NAME_LIST));
- tmplist->name=str_dup(arg);
- tmplist->next=section->connect_list;
- section->connect_list=tmplist;
+ name_list_append(§ion->connect_addr.names, arg);
return NULL; /* OK */
case CMD_END:
if(!section->option.delayed_lookup &&
- section->connect_list &&
- !namelist2addrlist(§ion->connect_addr,
- section->connect_list, DEFAULT_LOOPBACK)) {
+ section->connect_addr.names &&
+ !addrlist_resolve(§ion->connect_addr)) {
s_log(LOG_INFO,
"Cannot resolve connect target - delaying DNS lookup");
section->option.delayed_lookup=1;
@@ -1382,6 +1378,10 @@
case CMD_HELP:
s_log(LOG_NOTICE, "%-15s = defines the maximum length the queue of pending connections may grow to (max SOMAXCONN)", "listenqueue");
break;
+ case CMD_END:
+ break;
+ case CMD_FREE:
+ break;
}
#ifdef HAVE_OSSL_OCSP_H
@@ -1606,23 +1606,20 @@
/* redirect */
switch(cmd) {
case CMD_BEGIN:
- section->redirect_list=NULL;
- section->redirect_addr.num=0;
+ addrlist_init(§ion->redirect_addr, 1);
break;
case CMD_EXEC:
if(strcasecmp(opt, "redirect"))
break;
- tmplist=str_alloc(sizeof(NAME_LIST));
- tmplist->name=str_dup(arg);
- tmplist->next=section->redirect_list;
- section->redirect_list=tmplist;
+ name_list_append(§ion->redirect_addr.names, arg);
return NULL; /* OK */
case CMD_END:
- if(section->redirect_list &&
- !namelist2addrlist(§ion->redirect_addr,
- section->redirect_list, DEFAULT_LOOPBACK)) {
+ if(!section->option.delayed_lookup &&
+ section->redirect_addr.names &&
+ !addrlist_resolve(§ion->redirect_addr)) {
s_log(LOG_INFO,
"Cannot resolve redirect target - delaying DNS lookup");
+ section->option.delayed_lookup=1;
}
break;
case CMD_FREE:
@@ -2373,8 +2370,8 @@
/* setup host_name for SNI, prefer SNI and protocolHost if specified */
if(section->protocol_host) /* 'protocolHost' option */
section->sni=str_dup(section->protocol_host);
- else if(section->connect_list) /* 'connect' option */
- section->sni=str_dup(section->connect_list->name); /* first hostname */
+ else if(section->connect_addr.names) /* 'connect' option */
+ section->sni=str_dup(section->connect_addr.names->name); /* first hostname */
if(section->sni) { /* either 'protocolHost' or 'connect' specified */
tmpstr=strrchr(section->sni, ':');
if(tmpstr) { /* 'host:port' -> drop ':port' */
@@ -2976,6 +2973,14 @@
/**************************************** various supporting functions */
+NOEXPORT void name_list_append(NAME_LIST **ptr, char *name) {
+ while(*ptr) /* find the null pointer */
+ ptr=&(*ptr)->next;
+ *ptr=str_alloc(sizeof(NAME_LIST));
+ (*ptr)->name=str_dup(name);
+ (*ptr)->next=NULL;
+}
+
#ifndef USE_WIN32
NOEXPORT char **argalloc(char *str) { /* allocate 'exec' argumets */
diff -u -r stunnel-5.00-orig/src/protocol.c stunnel-5.00-patched/src/protocol.c
--- stunnel-5.00-orig/src/protocol.c 2014-03-06 00:25:58.000000000 +0100
+++ stunnel-5.00-patched/src/protocol.c 2015-05-26 10:42:55.651896451 +0200
@@ -546,7 +546,7 @@
host_list.name=request+8;
host_list.next=NULL;
- if(!namelist2addrlist(&c->connect_addr, &host_list, DEFAULT_LOOPBACK)) {
+ if(!name2addrlist(&c->connect_addr, &host_list, DEFAULT_LOOPBACK)) {
fd_putline(c, c->local_wfd.fd, "HTTP/1.0 404 Not Found");
fd_putline(c, c->local_wfd.fd, "Server: stunnel/" STUNNEL_VERSION);
fd_putline(c, c->local_wfd.fd, "");
diff -u -r stunnel-5.00-orig/src/prototypes.h stunnel-5.00-patched/src/prototypes.h
--- stunnel-5.00-orig/src/prototypes.h 2015-05-26 10:42:20.431950948 +0200
+++ stunnel-5.00-patched/src/prototypes.h 2015-05-26 10:42:55.652896506 +0200
@@ -42,6 +42,10 @@
/**************************************** data structures */
+/* non-zero constants for the "redirect" option */
+#define REDIRECT_ON 1
+#define REDIRECT_OFF 2
+
#if defined (USE_WIN32)
#define ICON_IMAGE HICON
#elif defined(__APPLE__)
@@ -86,8 +90,10 @@
typedef struct sockaddr_list { /* list of addresses */
SOCKADDR_UNION *addr; /* the list of addresses */
+ unsigned *rr_ptr, rr_val; /* current address for round-robin */
u16 cur; /* current address for round-robin */
u16 num; /* how many addresses are used */
+ NAME_LIST *names;
} SOCKADDR_LIST;
#ifndef OPENSSL_NO_COMP
@@ -202,7 +208,6 @@
#endif
SOCKADDR_UNION local_addr, source_addr;
SOCKADDR_LIST connect_addr, redirect_addr;
- NAME_LIST *connect_list, *redirect_list;
int timeout_busy; /* maximum waiting for data time */
int timeout_close; /* maximum close_notify time */
int timeout_connect; /* maximum connect() time */
@@ -380,7 +385,7 @@
/**************************************** prototypes for ssl.c */
-extern int cli_index, opt_index;
+extern int cli_index, opt_index, redirect_index;
int ssl_init(void);
int ssl_configure(GLOBAL_OPTIONS *);
@@ -464,6 +469,7 @@
FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */
int sock_bytes, ssl_bytes; /* bytes written to socket and SSL */
s_poll_set *fds; /* file descriptors */
+ uintptr_t redirect; /* redirect to another destination after failed auth */
} CLI;
CLI *alloc_client_session(SERVICE_OPTIONS *, int, int);
@@ -484,6 +490,9 @@
#else
;
#endif
+void s_ssl_write(CLI *, const void *, int);
+void s_ssl_read(CLI *, void *, int);
+char *ssl_getstring(CLI *c);
/**************************************** prototype for protocol.c */
@@ -500,10 +509,15 @@
/**************************************** prototypes for resolver.c */
void resolver_init();
+
int name2addr(SOCKADDR_UNION *, char *, char *);
int hostport2addr(SOCKADDR_UNION *, char *, char *);
-int namelist2addrlist(SOCKADDR_LIST *, NAME_LIST *, char *);
-void addrlist_dup(SOCKADDR_LIST *, const SOCKADDR_LIST *);
+unsigned name2addrlist(SOCKADDR_LIST *, char *, char *);
+int hostport2addrlist(SOCKADDR_LIST *, char *, char *);
+void addrlist_init(SOCKADDR_LIST *, int);
+unsigned addrlist_dup(SOCKADDR_LIST *, const SOCKADDR_LIST *);
+unsigned addrlist_resolve(SOCKADDR_LIST *);
+
char *s_ntop(SOCKADDR_UNION *, socklen_t);
socklen_t addr_len(const SOCKADDR_UNION *);
const char *s_gai_strerror(int);
diff -u -r stunnel-5.00-orig/src/resolver.c stunnel-5.00-patched/src/resolver.c
--- stunnel-5.00-orig/src/resolver.c 2014-03-06 00:26:04.000000000 +0100
+++ stunnel-5.00-patched/src/resolver.c 2015-05-26 10:42:55.652896506 +0200
@@ -40,8 +40,8 @@
/**************************************** prototypes */
-NOEXPORT int name2addrlist(SOCKADDR_LIST *, char *, char *);
NOEXPORT int hostport2addrlist(SOCKADDR_LIST *, char *, char *);
+NOEXPORT void addrlist2addr(SOCKADDR_UNION *, SOCKADDR_LIST *);
#ifndef HAVE_GETADDRINFO
@@ -119,46 +119,60 @@
/**************************************** stunnel resolver API */
int name2addr(SOCKADDR_UNION *addr, char *name, char *default_host) {
- SOCKADDR_LIST addr_list;
+ SOCKADDR_LIST *addr_list;
int retval;
- addr_list.num=0;
- addr_list.addr=NULL;
- retval=name2addrlist(&addr_list, name, default_host);
- if(retval>0)
- memcpy(addr, &addr_list.addr[0], sizeof *addr);
- if(addr_list.addr)
- str_free(addr_list.addr);
+ addr_list=str_alloc(sizeof(SOCKADDR_LIST));
+ addrlist_init(addr_list, 1);
+ retval=name2addrlist(addr_list, name, default_host);
+ if(retval)
+ addrlist2addr(addr, addr_list);
+ if(addr_list->addr)
+ str_free(addr_list->addr);
+ str_free(addr_list);
return retval;
}
-int hostport2addr(SOCKADDR_UNION *addr, char *hostname, char *portname) {
- SOCKADDR_LIST addr_list;
+int hostport2addr(SOCKADDR_UNION *addr, char *host_name, char *port_name) {
+ SOCKADDR_LIST *addr_list;
int retval;
- addr_list.num=0;
- addr_list.addr=NULL;
- retval=hostport2addrlist(&addr_list, hostname, portname);
- if(retval>0)
- memcpy(addr, &addr_list.addr[0], sizeof *addr);
- if(addr_list.addr)
- str_free(addr_list.addr);
+ addr_list=str_alloc(sizeof(SOCKADDR_LIST));
+ addrlist_init(addr_list, 1);
+ retval=hostport2addrlist(addr_list, host_name, port_name);
+ if(retval)
+ addrlist2addr(addr, addr_list);
+ if(addr_list->addr)
+ str_free(addr_list->addr);
+ str_free(addr_list);
return retval;
}
-int namelist2addrlist(SOCKADDR_LIST *addr_list, NAME_LIST *name_list, char *default_host) {
- /* recursive implementation to reverse the list */
- if(!name_list)
- return 0;
- return namelist2addrlist(addr_list, name_list->next, default_host) +
- name2addrlist(addr_list, name_list->name, default_host);
-}
+NOEXPORT void addrlist2addr(SOCKADDR_UNION *addr, SOCKADDR_LIST *addr_list) {
+ int i;
-NOEXPORT int name2addrlist(SOCKADDR_LIST *addr_list, char *name, char *default_host) {
- char *tmp, *hostname, *portname;
- int retval;
+ for(i=0; i<addr_list->num; ++i) { /* find the first IPv4 address */
+ if(addr_list->addr[i].in.sin_family==AF_INET) {
+ memcpy(addr, &addr_list->addr[i], sizeof(SOCKADDR_UNION));
+ return;
+ }
+ }
+#ifdef USE_IPv6
+ for(i=0; i<addr_list->num; ++i) { /* find the first IPv6 address */
+ if(addr_list->addr[i].in.sin_family==AF_INET6) {
+ memcpy(addr, &addr_list->addr[i], sizeof(SOCKADDR_UNION));
+ return;
+ }
+ }
+#endif
+ /* copy the first address resolved (curently AF_UNIX) */
+ memcpy(addr, &addr_list->addr[0], sizeof(SOCKADDR_UNION));
+}
- addr_list->cur=0; /* reset round-robin counter */
+unsigned name2addrlist(SOCKADDR_LIST *addr_list, char *name, char *default_host)
+{
+ char *tmp, *host_name, *port_name;
+ unsigned retval;
/* first check if this is a UNIX socket */
#ifdef HAVE_STRUCT_SOCKADDR_UN
@@ -176,25 +190,25 @@
}
#endif
- /* set hostname and portname */
+ /* set host_name and port_name */
tmp=str_dup(name);
- portname=strrchr(tmp, ':');
- if(portname) {
- hostname=tmp;
- *portname++='\0';
+ port_name=strrchr(tmp, ':');
+ if(port_name) {
+ host_name=tmp;
+ *port_name++='\0';
} else { /* no ':' - use default host IP */
- hostname=default_host;
- portname=tmp;
+ host_name=default_host;
+ port_name=tmp;
}
/* fill addr_list structure */
- retval=hostport2addrlist(addr_list, hostname, portname);
+ retval=hostport2addrlist(addr_list, host_name, port_name);
str_free(tmp);
return retval;
}
NOEXPORT int hostport2addrlist(SOCKADDR_LIST *addr_list,
- char *hostname, char *portname) {
+ char *host_name, char *port_name) {
struct addrinfo hints, *res=NULL, *cur;
int err, retries=0;
@@ -207,7 +221,7 @@
hints.ai_socktype=SOCK_STREAM;
hints.ai_protocol=IPPROTO_TCP;
for(;;) {
- err=getaddrinfo(hostname, portname, &hints, &res);
+ err=getaddrinfo(host_name, port_name, &hints, &res);
if(err && res)
freeaddrinfo(res);
if(err!=EAI_AGAIN || ++retries>=3)
@@ -219,11 +233,11 @@
case 0:
break; /* success */
case EAI_SERVICE:
- s_log(LOG_ERR, "Unknown TCP service '%s'", portname);
+ s_log(LOG_ERR, "Unknown TCP service '%s'", port_name);
return 0; /* error */
default:
s_log(LOG_ERR, "Error resolving '%s': %s",
- hostname, s_gai_strerror(err));
+ host_name, s_gai_strerror(err));
return 0; /* error */
}
@@ -243,12 +257,38 @@
return addr_list->num; /* ok - return the number of addresses */
}
-void addrlist_dup(SOCKADDR_LIST *dst, const SOCKADDR_LIST *src) {
+void addrlist_init(SOCKADDR_LIST *addr_list, int clear_names) {
+ addr_list->num=0;
+ if(addr_list->addr)
+ str_free(addr_list->addr);
+ addr_list->addr=NULL;
+ addr_list->rr_val=0; /* reset round-robin counter */
+ /* allow structures created with sockaddr_dup() to modify
+ * the original rr_val rather than its local copy */
+ addr_list->rr_ptr=&addr_list->rr_val;
+ if(clear_names)
+ addr_list->names=NULL;
+}
+
+unsigned addrlist_dup(SOCKADDR_LIST *dst, const SOCKADDR_LIST *src) {
memcpy(dst, src, sizeof(SOCKADDR_LIST));
- if(src->addr) {
+ if(src->num) {
dst->addr=str_alloc(src->num*sizeof(SOCKADDR_UNION));
memcpy(dst->addr, src->addr, src->num*sizeof(SOCKADDR_UNION));
+ } else { /* delayed resolver */
+ addrlist_resolve(dst);
}
+ return dst->num;
+}
+
+unsigned addrlist_resolve(SOCKADDR_LIST *addr_list) {
+ unsigned num=0;
+ NAME_LIST *host;
+
+ addrlist_init(addr_list, 0);
+ for(host=addr_list->names; host; host=host->next)
+ num+=name2addrlist(addr_list, host->name, DEFAULT_LOOPBACK);
+ return num;
}
char *s_ntop(SOCKADDR_UNION *addr, socklen_t addrlen) {
diff -u -r stunnel-5.00-orig/src/ssl.c stunnel-5.00-patched/src/ssl.c
--- stunnel-5.00-orig/src/ssl.c 2014-03-06 00:26:08.000000000 +0100
+++ stunnel-5.00-patched/src/ssl.c 2015-05-26 10:42:55.652896506 +0200
@@ -43,15 +43,21 @@
NOEXPORT int init_prng(GLOBAL_OPTIONS *);
NOEXPORT int add_rand_file(GLOBAL_OPTIONS *, const char *);
-int cli_index, opt_index; /* to keep structure for callbacks */
+int cli_index, opt_index, redirect_index; /* to keep structure for callbacks */
int ssl_init(void) { /* init SSL before parsing configuration file */
SSL_load_error_strings();
SSL_library_init();
- cli_index=SSL_get_ex_new_index(0, "cli index", NULL, NULL, NULL);
- opt_index=SSL_CTX_get_ex_new_index(0, "opt index", NULL, NULL, NULL);
- if(cli_index<0 || opt_index<0)
+ cli_index=SSL_get_ex_new_index(0, "cli pointer index",
+ NULL, NULL, NULL);
+ opt_index=SSL_CTX_get_ex_new_index(0, "opt pointer index",
+ NULL, NULL, NULL);
+ redirect_index=SSL_SESSION_get_ex_new_index(0, "redirect value index",
+ NULL, NULL, NULL);
+ if(cli_index<0 || opt_index<0 || redirect_index<0) {
+ s_log(LOG_ERR, "Application specific data initialization failed");
return 1;
+ }
#ifdef HAVE_OSSL_ENGINE_H
ENGINE_load_builtin_engines();
#endif
diff -u -r stunnel-5.00-orig/src/verify.c stunnel-5.00-patched/src/verify.c
--- stunnel-5.00-orig/src/verify.c 2014-03-06 00:26:39.000000000 +0100
+++ stunnel-5.00-patched/src/verify.c 2015-05-26 10:42:55.652896506 +0200
@@ -188,15 +188,8 @@
return 1; /* accept */
if(c->opt->option.client || c->opt->protocol>=0)
return 0; /* reject */
- if(c->opt->redirect_addr.num) { /* pre-resolved addresses */
- addrlist_dup(&c->connect_addr, &c->opt->redirect_addr);
- s_log(LOG_INFO, "Redirecting connection");
- return 1; /* accept */
- }
- /* delayed lookup */
- if(namelist2addrlist(&c->connect_addr,
- c->opt->redirect_list, DEFAULT_LOOPBACK)) {
- s_log(LOG_INFO, "Redirecting connection");
+ if(c->opt->redirect_addr.names) {
+ c->redirect=REDIRECT_ON;
return 1; /* accept */
}
return 0; /* reject */