From 9b570cba762c72fbb67662768e8bfd4d6c534586179b8383f9332c2a84df2715 Mon Sep 17 00:00:00 2001 From: Daniel Rahn Date: Wed, 29 Jun 2011 06:12:14 +0000 Subject: [PATCH] - update package to 4.38 * New features: - Server-side SNI implemented (RFC 3546 section 3.1) with a new service-level option "nsi". - "socket" option also accepts "yes" and "no" for flags. - Nagle's algorithm is now disabled by default for improved interactivity. * Bugfixes: - A compilation fix was added for OpenSSL version < 1.0.0. - Signal pipe set to non-blocking mode. This bug caused hangs of stunnel features based on signals, e.g. local mode, FORK threading, or configuration file reload on Unix. OBS-URL: https://build.opensuse.org/package/show/security:Stunnel/stunnel?expand=0&rev=46 --- fix-ucontext-handling.patch | 785 ----------------------------- non-blocking-socket-handling.patch | 110 ---- stunnel-4.36.tar.bz2 | 3 - stunnel-4.38.tar.gz | 3 + stunnel.changes | 16 + stunnel.spec | 8 +- 6 files changed, 21 insertions(+), 904 deletions(-) delete mode 100644 fix-ucontext-handling.patch delete mode 100644 non-blocking-socket-handling.patch delete mode 100644 stunnel-4.36.tar.bz2 create mode 100644 stunnel-4.38.tar.gz diff --git a/fix-ucontext-handling.patch b/fix-ucontext-handling.patch deleted file mode 100644 index b4500b1..0000000 --- a/fix-ucontext-handling.patch +++ /dev/null @@ -1,785 +0,0 @@ ---- src/network.c 2011-05-01 23:28:59.000000000 +0200 -+++ src/network.c 2011-05-08 09:45:04.000000000 +0200 -@@ -119,10 +119,10 @@ - int retval, retry; - CONTEXT *context, *prev; - int min_timeout; -- int nfds, i; -+ unsigned int nfds, i; - time_t now; - short *signal_revents; -- static int max_nfds=0; -+ static unsigned int max_nfds=0; - static struct pollfd *ufds=NULL; - - time(&now); -@@ -216,51 +216,56 @@ - } - - int s_poll_wait(s_poll_set *fds, int sec, int msec) { -- /* FIXME: msec parameter is currently ignored with UCONTEXT threads */ - CONTEXT *context; /* current context */ - static CONTEXT *to_free=NULL; /* delayed memory deallocation */ - -+ /* FIXME: msec parameter is currently ignored with UCONTEXT threads */ -+ (void)msec; /* skip warning about unused parameter */ -+ - /* remove the current context from ready queue */ - context=ready_head; - ready_head=ready_head->next; - if(!ready_head) /* the queue is empty */ - ready_tail=NULL; -+ /* it it safe to s_log() after new ready_head is set */ -+ -+ /* it's illegal to deallocate the stack of the current context */ -+ if(to_free) { /* a delayed deallocation is scheduled */ -+ s_log(LOG_DEBUG, "Releasing context %ld", to_free->id); -+ free(to_free->stack); -+ free(to_free); -+ to_free=NULL; -+ } - -+ /* manage the current thread */ - if(fds) { /* something to wait for -> swap the context */ - context->fds=fds; /* set file descriptors to wait for */ - context->finish=sec<0 ? -1 : time(NULL)+sec; -- /* move (append) the current context to the waiting queue */ -+ -+ /* append the current context to the waiting queue */ - context->next=NULL; - if(waiting_tail) - waiting_tail->next=context; - waiting_tail=context; - if(!waiting_head) - waiting_head=context; -- while(!ready_head) /* no context ready */ -- scan_waiting_queue(); -+ } else { /* nothing to wait for -> drop the context */ -+ to_free=context; /* schedule for delayed deallocation */ -+ } -+ -+ while(!ready_head) /* wait until there is a thread to switch to */ -+ scan_waiting_queue(); -+ -+ /* switch threads */ -+ if(fds) { /* swap the current context */ - if(context->id!=ready_head->id) { - s_log(LOG_DEBUG, "Context swap: %ld -> %ld", - context->id, ready_head->id); - swapcontext(&context->context, &ready_head->context); - s_log(LOG_DEBUG, "Current context: %ld", ready_head->id); -- if(to_free) { -- s_log(LOG_DEBUG, "Releasing context %ld", to_free->id); -- free(to_free->stack); -- free(to_free); -- to_free=NULL; -- } - } - return ready_head->ready; -- } else { /* nothing to wait for -> drop the context */ -- /* it's illegal to deallocate the stack of the current context */ -- if(to_free) { -- s_log(LOG_DEBUG, "Releasing context %ld", to_free->id); -- free(to_free->stack); -- free(to_free); -- } -- to_free=context; -- while(!ready_head) /* no context ready */ -- scan_waiting_queue(); -+ } else { /* drop the current context */ - s_log(LOG_DEBUG, "Context set: %ld (dropped) -> %ld", - context->id, ready_head->id); - setcontext(&ready_head->context); -@@ -701,6 +706,10 @@ - longjmp(c->err, 1); /* error */ - } - line=str_realloc(line, ptr+1); -+ if(!line) { -+ s_log(LOG_CRIT, "Memory allocation failed"); -+ longjmp(c->err, 1); /* error */ -+ } - switch(readsocket(fd, line+ptr, 1)) { - case -1: /* error */ - sockerror("readsocket (fdgetline)"); ---- src/sthreads.c 2011-05-02 23:58:45.000000000 +0200 -+++ src/sthreads.c 2011-05-10 11:45:18.000000000 +0200 -@@ -47,10 +47,12 @@ - /* no need for critical sections */ - - void enter_critical_section(SECTION_CODE i) { -+ (void)i; /* skip warning about unused parameter */ - /* empty */ - } - - void leave_critical_section(SECTION_CODE i) { -+ (void)i; /* skip warning about unused parameter */ - /* empty */ - } - -@@ -76,7 +78,6 @@ - /* first context on the ready list is the active context */ - CONTEXT *ready_head=NULL, *ready_tail=NULL; /* ready to execute */ - CONTEXT *waiting_head=NULL, *waiting_tail=NULL; /* waiting on poll() */ --int next_id=1; - - unsigned long stunnel_process_id(void) { - return (unsigned long)getpid(); -@@ -86,63 +87,48 @@ - return ready_head ? ready_head->id : 0; - } - --static CONTEXT *new_context(int stack_size) { -+static CONTEXT *new_context(void) { -+ static int next_id=1; - CONTEXT *context; - - /* allocate and fill the CONTEXT structure */ -- context=str_alloc(sizeof(CONTEXT)); -+ context=calloc(1, sizeof(CONTEXT)); - if(!context) { - s_log(LOG_ERR, "Unable to allocate CONTEXT structure"); - return NULL; - } -- context->stack=str_alloc(stack_size); -- if(!context->stack) { -- s_log(LOG_ERR, "Unable to allocate CONTEXT stack"); -- return NULL; -- } - context->id=next_id++; - context->fds=NULL; - context->ready=0; -- /* some manuals claim that initialization of context structure is required */ -- if(getcontext(&context->context)<0) { -- str_free(context->stack); -- str_free(context); -- ioerror("getcontext"); -- return NULL; -- } -- context->context.uc_link=NULL; /* it should never happen */ --#if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */ -- context->context.uc_stack.ss_sp=context->stack+stack_size-8; --#else -- context->context.uc_stack.ss_sp=context->stack; --#endif -- context->context.uc_stack.ss_size=stack_size; -- context->context.uc_stack.ss_flags=0; - -- /* attach to the tail of the ready queue */ -+ /* append to the tail of the ready queue */ - context->next=NULL; - if(ready_tail) - ready_tail->next=context; - ready_tail=context; - if(!ready_head) - ready_head=context; -+ - return context; - } - - void sthreads_init(void) { - /* create the first (listening) context and put it in the running queue */ -- if(!new_context(DEFAULT_STACK_SIZE)) { -+ if(!new_context()) { - s_log(LOG_ERR, "Unable create the listening context"); - die(1); - } -+ /* no need to initialize ucontext_t structure here -+ it will be initialied with swapcontext() call */ - } - - int create_client(int ls, int s, CLI *arg, void *(*cli)(void *)) { - CONTEXT *context; - - (void)ls; /* this parameter is only used with USE_FORK */ -+ - s_log(LOG_DEBUG, "Creating a new context"); -- context=new_context(arg->opt->stack_size); -+ context=new_context(); - if(!context) { - if(arg) - free(arg); -@@ -150,6 +136,38 @@ - closesocket(s); - return -1; - } -+ -+ /* initialize context_t structure */ -+ if(getcontext(&context->context)<0) { -+ free(context); -+ if(arg) -+ free(arg); -+ if(s>=0) -+ closesocket(s); -+ ioerror("getcontext"); -+ return -1; -+ } -+ context->context.uc_link=NULL; /* stunnel does not use uc_link */ -+ -+ /* create stack */ -+ context->stack=calloc(1, arg->opt->stack_size); -+ if(!context->stack) { -+ free(context); -+ if(arg) -+ free(arg); -+ if(s>=0) -+ closesocket(s); -+ s_log(LOG_ERR, "Unable to allocate stack"); -+ return -1; -+ } -+#if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */ -+ context->context.uc_stack.ss_sp=context->stack+arg->opt->stack_size-8; -+#else -+ context->context.uc_stack.ss_sp=context->stack; -+#endif -+ context->context.uc_stack.ss_size=arg->opt->stack_size; -+ context->context.uc_stack.ss_flags=0; -+ - s_log(LOG_DEBUG, "Context %ld created", context->id); - makecontext(&context->context, (void(*)(void))cli, ARGC, arg); - return 0; -@@ -298,7 +316,7 @@ - /* Disabled on OS X due to strange problems on Mac OS X 10.5 - it seems to restore signal mask somewhere (I couldn't find where) - effectively blocking signals after first accepted connection */ -- sigset_t sigset; -+ sigset_t new_set, old_set; - #endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/ - - (void)ls; /* this parameter is only used with USE_FORK */ -@@ -306,9 +324,8 @@ - #if defined(HAVE_PTHREAD_SIGMASK) && !defined(__APPLE__) - /* the idea is that only the main thread handles all the signals with - * posix threads; signals are blocked for any other thread */ -- sigfillset(&sigset); -- pthread_sigmask(SIG_SETMASK, &sigset, NULL); /* block signals */ -- sigemptyset(&sigset); /* prepare for unblocking */ -+ sigfillset(&new_set); -+ pthread_sigmask(SIG_SETMASK, &new_set, &old_set); /* block signals */ - #endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/ - pthread_attr_init(&pth_attr); - pthread_attr_setdetachstate(&pth_attr, PTHREAD_CREATE_DETACHED); -@@ -316,7 +333,7 @@ - error=pthread_create(&thread, &pth_attr, cli, arg); - pthread_attr_destroy(&pth_attr); - #if defined(HAVE_PTHREAD_SIGMASK) && !defined(__APPLE__) -- pthread_sigmask(SIG_SETMASK, &sigset, NULL); /* unblock signals */ -+ pthread_sigmask(SIG_SETMASK, &old_set, NULL); /* unblock signals */ - #endif /* HAVE_PTHREAD_SIGMASK && !__APPLE__*/ - - if(error) { ---- src/client.c 2011-05-02 18:12:53.000000000 +0200 -+++ src/client.c 2011-06-17 15:19:44.000000000 +0200 -@@ -106,10 +106,8 @@ - if(!c->opt->option.retry) - break; - sleep(1); /* FIXME: not a good idea in ucontext threading */ --#ifndef USE_UCONTEXT - str_stats(); - str_cleanup(); --#endif - } - } else - run_client(c); -@@ -119,18 +117,17 @@ - #ifdef DEBUG_STACK_SIZE - stack_info(0); /* display computed value */ - #endif -+#ifdef USE_UCONTEXT -+ s_log(LOG_DEBUG, "Context %ld closed", ready_head->id); -+#endif - str_stats(); --#if defined(USE_WIN32) && !defined(_WIN32_WCE) - str_cleanup(); -+ /* s_log() is not allowed after str_cleanup() */ -+#if defined(USE_WIN32) && !defined(_WIN32_WCE) - _endthread(); - #endif - #ifdef USE_UCONTEXT -- s_log(LOG_DEBUG, "Context %ld closed", ready_head->id); -- /* no str_cleanup() here, as all contexts share the same CPU thread */ - s_poll_wait(NULL, 0, 0); /* wait on poll() */ -- s_log(LOG_ERR, "INTERNAL ERROR: failed to drop context"); --#else -- str_cleanup(); - #endif - return NULL; - } -@@ -283,6 +280,15 @@ - SSL_set_session_id_context(c->ssl, (unsigned char *)sid_ctx, - strlen(sid_ctx)); - if(c->opt->option.client) { -+#ifndef OPENSSL_NO_TLSEXT -+ if(c->opt->host_name) { -+ s_log(LOG_DEBUG, "SNI host name: %s", c->opt->host_name); -+ if(!SSL_set_tlsext_host_name(c->ssl, c->opt->host_name)) { -+ sslerror("SSL_set_tlsext_host_name"); -+ longjmp(c->err, 1); -+ } -+ } -+#endif - if(c->opt->session) { - enter_critical_section(CRIT_SESSION); - SSL_set_session(c->ssl, c->opt->session); -@@ -314,9 +320,9 @@ - - while(1) { - #if OPENSSL_VERSION_NUMBER<0x1000002f -- /* this critical section is a crude workaround for CVE-2010-3864 */ -- /* see http://www.securityfocus.com/bid/44884 for details */ -- /* NOTE: this critical section also covers callbacks (e.g. OCSP) */ -+ /* this critical section is a crude workaround for CVE-2010-3864 * -+ * see http://www.securityfocus.com/bid/44884 for details * -+ * NOTE: this critical section also covers callbacks (e.g. OCSP) */ - enter_critical_section(CRIT_SSL); - #endif /* OpenSSL version < 1.0.0b */ - if(c->opt->option.client) -@@ -821,22 +827,26 @@ - type=strchr(line, ':'); - if(!type) { - s_log(LOG_ERR, "Malformed IDENT response"); -+ str_free(line); - longjmp(c->err, 1); - } - *type++='\0'; - system=strchr(type, ':'); - if(!system) { - s_log(LOG_ERR, "Malformed IDENT response"); -+ str_free(line); - longjmp(c->err, 1); - } - *system++='\0'; - if(strcmp(type, " USERID ")) { - s_log(LOG_ERR, "Incorrect INETD response type"); -+ str_free(line); - longjmp(c->err, 1); - } - user=strchr(system, ':'); - if(!user) { - s_log(LOG_ERR, "Malformed IDENT response"); -+ str_free(line); - longjmp(c->err, 1); - } - *user++='\0'; -@@ -846,9 +856,11 @@ - safestring(user); - s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user %s)", - c->accepted_address, user); -+ str_free(line); - longjmp(c->err, 1); - } - s_log(LOG_INFO, "IDENT authentication passed"); -+ str_free(line); - } - - #if defined(_WIN32_WCE) || defined(__vms) -@@ -878,8 +890,8 @@ - execname_l=str2tstr(c->opt->execname); - execargs_l=str2tstr(c->opt->execargs); - CreateProcess(execname_l, execargs_l, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); -- free(execname_l); -- free(execargs_l); -+ str_free(execname_l); -+ str_free(execargs_l); - - closesocket(fd[1]); - CloseHandle(pi.hProcess); -@@ -916,6 +928,7 @@ - longjmp(c->err, 1); - case 0: /* child */ - closesocket(fd[0]); -+ set_nonblock(fd[1], 0); /* switch back to blocking mode */ - /* dup2() does not copy FD_CLOEXEC flag */ - dup2(fd[1], 0); - dup2(fd[1], 1); -@@ -969,9 +982,10 @@ - s=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#1"); - if(s<0) - longjmp(c->err, 1); -- fd[1]=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2"); -- if(fd[1]<0) -+ c->fd=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2"); -+ if(c->fd<0) - longjmp(c->err, 1); -+ - addrlen=sizeof addr; - memset(&addr, 0, addrlen); - addr.in.sin_family=AF_INET; -@@ -979,22 +993,30 @@ - addr.in.sin_port=htons(0); /* dynamic port allocation */ - if(bind(s, &addr.sa, addrlen)) - log_error(LOG_DEBUG, get_last_socket_error(), "bind#1"); -- if(bind(fd[1], &addr.sa, addrlen)) -+ if(bind(c->fd, &addr.sa, addrlen)) - log_error(LOG_DEBUG, get_last_socket_error(), "bind#2"); -+ - if(listen(s, 1)) { -+ closesocket(s); - sockerror("listen"); - longjmp(c->err, 1); - } - if(getsockname(s, &addr.sa, &addrlen)) { -+ closesocket(s); - sockerror("getsockname"); - longjmp(c->err, 1); - } -- if(connect(fd[1], &addr.sa, addrlen)) { -- sockerror("connect"); -+ if(connect_blocking(c, &addr, addr_len(addr))) { -+ closesocket(s); - longjmp(c->err, 1); - } -- if((fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept"))<0) -+ fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept"); -+ if(fd[0]<0) { -+ closesocket(s); - longjmp(c->err, 1); -+ } -+ fd[1]=c->fd; -+ c->fd=-1; - closesocket(s); /* don't care about the result */ - #else - if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "socketpair")) ---- src/str.c 2011-05-02 19:14:53.000000000 +0200 -+++ src/str.c 2011-05-08 08:37:57.000000000 +0200 -@@ -38,17 +38,128 @@ - #include "common.h" - #include "prototypes.h" - --typedef struct str_struct { -- struct str_struct *prev, *next; -+#ifndef va_copy -+#ifdef __va_copy -+#define va_copy(dst, src) __va_copy((dst), (src)) -+#else /* __va_copy */ -+#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) -+#endif /* __va_copy */ -+#endif /* va_copy */ -+ -+typedef struct alloc_list { -+ struct alloc_list *prev, *next; - size_t size; - unsigned int magic; --} STR; --static void str_set(STR *); --static STR *str_get(); -+} ALLOC_LIST; -+ -+static void set_alloc_head(ALLOC_LIST *); -+static ALLOC_LIST *get_alloc_head(); -+ -+char *str_dup(const char *str) { -+ char *retval; -+ -+ retval=str_alloc(strlen(str)+1); -+ if(retval) -+ strcpy(retval, str); -+ return retval; -+} -+ -+char *str_printf(const char *format, ...) { -+ char *txt; -+ va_list arglist; -+ -+ va_start(arglist, format); -+ txt=str_vprintf(format, arglist); -+ va_end(arglist); -+ return txt; -+} -+ -+char *str_vprintf(const char *format, va_list start_ap) { -+ int n, size=64; -+ char *p, *np; -+ va_list ap; -+ -+ p=str_alloc(size); -+ if(!p) -+ return NULL; -+ for(;;) { -+ va_copy(ap, start_ap); -+ n=vsnprintf(p, size, format, ap); -+ if(n>-1 && n-1) /* glibc 2.1 */ -+ size=n+1; /* precisely what is needed */ -+ else /* glibc 2.0, WIN32, etc. */ -+ size*=2; /* twice the old size */ -+ np=str_realloc(p, size); -+ if(!np) { -+ str_free(p); -+ return NULL; -+ } -+ p=np; /* LOL */ -+ } -+} -+ -+#ifdef USE_UCONTEXT -+ -+static ALLOC_LIST *alloc_tls=NULL; -+ -+void str_init() { -+} -+ -+static void set_alloc_head(ALLOC_LIST *alloc_head) { -+ if(ready_head) -+ ready_head->tls=alloc_head; -+ else /* ucontext threads not initialized */ -+ alloc_tls=alloc_head; -+} -+ -+static ALLOC_LIST *get_alloc_head() { -+ if(ready_head) -+ return ready_head->tls; -+ else /* ucontext threads not initialized */ -+ return alloc_tls; -+} -+ -+#endif /* USE_UCONTEXT */ -+ -+#ifdef USE_FORK -+ -+static ALLOC_LIST *alloc_tls=NULL; -+ -+void str_init() { -+} -+ -+static void set_alloc_head(ALLOC_LIST *alloc_head) { -+ alloc_tls=alloc_head; -+} -+ -+static ALLOC_LIST *get_alloc_head() { -+ return alloc_tls; -+} -+ -+#endif /* USE_FORK */ -+ -+#ifdef USE_PTHREAD -+ -+static pthread_key_t pthread_key; -+ -+void str_init() { -+ pthread_key_create(&pthread_key, NULL); -+} -+ -+static void set_alloc_head(ALLOC_LIST *alloc_head) { -+ pthread_setspecific(pthread_key, alloc_head); -+} -+ -+static ALLOC_LIST *get_alloc_head() { -+ return pthread_getspecific(pthread_key); -+} -+ -+#endif /* USE_PTHREAD */ - - #ifdef USE_WIN32 - --/* __thread does not work in mingw32 due to a bug in GCC */ - static DWORD tls_index; - - void str_init() { -@@ -59,97 +170,81 @@ - } - } - --static void str_set(STR *str) { -- if(!TlsSetValue(tls_index, str)) { -+static void set_alloc_head(ALLOC_LIST *alloc_head) { -+ if(!TlsSetValue(tls_index, alloc_head)) { - s_log(LOG_ERR, "TlsSetValue failed"); - die(1); - } - } - --static STR *str_get() { -- STR *str; -+static ALLOC_LIST *get_alloc_head() { -+ ALLOC_LIST *alloc_head; - -- str=TlsGetValue(tls_index); -- if(!str && GetLastError()!=ERROR_SUCCESS) { -+ alloc_head=TlsGetValue(tls_index); -+ if(!alloc_head && GetLastError()!=ERROR_SUCCESS) { - s_log(LOG_ERR, "TlsGetValue failed"); - die(1); - } -- return str; --} -- --#else -- --/* gcc Thread-Local Storage */ --static __thread STR *root_str=NULL; -- --void str_init() { -- if(root_str) -- s_log(LOG_WARNING, "str_init: Non-empty allocation list"); -+ return alloc_head; - } - --static void str_set(STR *str) { -- root_str=str; --} -- --static STR *str_get() { -- return root_str; --} -- --#endif -+#endif /* USE_WIN32 */ - - void str_cleanup() { -- STR *str, *tmp; -+ ALLOC_LIST *alloc_head, *tmp; - -- str=str_get(); -- while(str) { -- tmp=str; -- str=tmp->next; -+ alloc_head=get_alloc_head(); -+ while(alloc_head) { -+ tmp=alloc_head; -+ alloc_head=tmp->next; - free(tmp); - } -- str_set(NULL); -+ set_alloc_head(NULL); - } - - void str_stats() { -- STR *tmp; -+ ALLOC_LIST *tmp; - int blocks=0, bytes=0; - -- for(tmp=str_get(); tmp; tmp=tmp->next) { -+ for(tmp=get_alloc_head(); tmp; tmp=tmp->next) { - ++blocks; - bytes+=tmp->size; - } -- s_log(LOG_DEBUG, "str_stats: %d blocks, %d bytes", blocks, bytes); -+ s_log(LOG_DEBUG, "str_stats: %d block(s), %d byte(s)", blocks, bytes); - } - - void *str_alloc(size_t size) { -- STR *str, *tmp; -+ ALLOC_LIST *alloc_head, *tmp; - - if(size>=1024*1024) /* huge allocations are not allowed */ - return NULL; -- tmp=calloc(1, sizeof(STR)+size); -+ tmp=calloc(1, sizeof(ALLOC_LIST)+size); - if(!tmp) - return NULL; -- str=str_get(); -+ alloc_head=get_alloc_head(); - tmp->prev=NULL; -- tmp->next=str; -+ tmp->next=alloc_head; - tmp->size=size; - tmp->magic=0xdeadbeef; -- if(str) -- str->prev=tmp; -- str_set(tmp); -+ if(alloc_head) -+ alloc_head->prev=tmp; -+ set_alloc_head(tmp); - return tmp+1; - } - - void *str_realloc(void *ptr, size_t size) { -- STR *oldtmp, *tmp; -+ ALLOC_LIST *old_tmp, *tmp; - - if(!ptr) - return str_alloc(size); -- oldtmp=(STR *)ptr-1; -- if(oldtmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ -+ old_tmp=(ALLOC_LIST *)ptr-1; -+ if(old_tmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ - s_log(LOG_CRIT, "INTERNAL ERROR: str_realloc: Bad magic"); - die(1); - } -- tmp=realloc(oldtmp, sizeof(STR)+size); -+ if(size>=1024*1024) /* huge allocations are not allowed */ -+ return NULL; -+ tmp=realloc(old_tmp, sizeof(ALLOC_LIST)+size); - if(!tmp) - return NULL; - /* refresh all possibly invalidated pointers */ -@@ -158,17 +253,17 @@ - if(tmp->prev) - tmp->prev->next=tmp; - tmp->size=size; -- if(str_get()==oldtmp) -- str_set(tmp); -+ if(get_alloc_head()==old_tmp) -+ set_alloc_head(tmp); - return tmp+1; - } - - void str_free(void *ptr) { -- STR *tmp; -+ ALLOC_LIST *tmp; - - if(!ptr) /* do not attempt to free null pointers */ - return; -- tmp=(STR *)ptr-1; -+ tmp=(ALLOC_LIST *)ptr-1; - if(tmp->magic!=0xdeadbeef) { /* not allocated by str_alloc() */ - s_log(LOG_CRIT, "INTERNAL ERROR: str_free: Bad magic"); - die(1); -@@ -178,54 +273,9 @@ - tmp->next->prev=tmp->prev; - if(tmp->prev) - tmp->prev->next=tmp->next; -- if(str_get()==tmp) -- str_set(tmp->next); -+ if(get_alloc_head()==tmp) -+ set_alloc_head(tmp->next); - free(tmp); - } - --char *str_dup(const char *str) { -- char *retval; -- -- retval=str_alloc(strlen(str)+1); -- if(retval) -- strcpy(retval, str); -- return retval; --} -- --char *str_vprintf(const char *format, va_list start_ap) { -- int n, size=64; -- char *p, *np; -- va_list ap; -- -- p=str_alloc(size); -- if(!p) -- return NULL; -- for(;;) { -- va_copy(ap, start_ap); -- n=vsnprintf(p, size, format, ap); -- if(n>-1 && n-1) /* glibc 2.1 */ -- size=n+1; /* precisely what is needed */ -- else /* glibc 2.0 */ -- size*=2; /* twice the old size */ -- np=str_realloc(p, size); -- if(!np) { -- str_free(p); -- return NULL; -- } -- p=np; /* LOL */ -- } --} -- --char *str_printf(const char *format, ...) { -- char *txt; -- va_list arglist; -- -- va_start(arglist, format); -- txt=str_vprintf(format, arglist); -- va_end(arglist); -- return txt; --} -- - /* end of str.c */ diff --git a/non-blocking-socket-handling.patch b/non-blocking-socket-handling.patch deleted file mode 100644 index d3abec6..0000000 --- a/non-blocking-socket-handling.patch +++ /dev/null @@ -1,110 +0,0 @@ ---- src/stunnel.c 2011/06/18 04:05:08 1.1 -+++ src/stunnel.c 2011/06/18 04:09:42 -@@ -496,11 +496,9 @@ - #endif - - static int setup_fd(int fd, int nonblock, char *msg) { --#ifdef USE_WIN32 -- unsigned long l; --#else /* USE_WIN32 */ -- int err, flags; --#endif /* USE_WIN32 */ -+#ifdef FD_CLOEXEC -+ int err; -+#endif /* FD_CLOEXEC */ - - if(fd<0) { - sockerror(msg); -@@ -512,11 +510,33 @@ - closesocket(fd); - return -1; - } -+ - #ifndef USE_NEW_LINUX_API --#if defined F_GETFL && defined F_SETFL && defined O_NONBLOCK && !defined __INNOTEK_LIBC__ -+ set_nonblock(fd, nonblock); -+#ifdef FD_CLOEXEC -+ do { -+ err=fcntl(fd, F_SETFD, FD_CLOEXEC); -+ } while(err<0 && get_last_socket_error()==EINTR); -+ if(err<0) -+ sockerror("fcntl SETFD"); /* non-critical */ -+#endif /* FD_CLOEXEC */ -+#endif /* USE_NEW_LINUX_API */ -+ s_log(LOG_DEBUG, "%s: FD=%d allocated (%sblocking mode)", -+ msg, fd, nonblock?"non-":""); -+ return fd; -+} -+ -+void set_nonblock(int fd, unsigned long nonblock) { -+#if defined F_GETFL && defined F_SETFL && defined O_NONBLOCK && !defined __INNOTEK_LIBC__ -+ int err, flags; -+ - do { - flags=fcntl(fd, F_GETFL, 0); - } while(flags<0 && get_last_socket_error()==EINTR); -+ if(flags<0) { -+ sockerror("fcntl GETFL"); /* non-critical */ -+ return; -+ } - if(nonblock) - flags|=O_NONBLOCK; - else ---- src/prototypes.h 2011-06-18 12:14:22.883741503 +0200 -+++ src/prototypes.h 2011-06-17 15:14:24.000000000 +0200 -@@ -154,6 +154,7 @@ - SOCKADDR_LIST local_addr, remote_addr, source_addr; - char *username; - char *remote_address; -+ char *host_name; - int timeout_busy; /* maximum waiting for data time */ - int timeout_close; /* maximum close_notify time */ - int timeout_connect; /* maximum connect() time */ -@@ -322,7 +323,6 @@ - void child_status(void); /* dead libwrap or 'exec' process detected */ - #endif - int set_socket_options(int, int); --void set_nonblock(int, unsigned long); - int get_socket_error(const int); - - /**************************************** prototypes for client.c */ -@@ -333,24 +333,26 @@ - } FD; - - typedef struct { -+ SSL *ssl; /* SSL connnection */ - SERVICE_OPTIONS *opt; -- char accepted_address[IPLEN]; /* text */ -+ jmp_buf err; /* exception handler */ -+ -+ char accepted_address[IPLEN]; /* IP address as text for logging */ - SOCKADDR_LIST peer_addr; /* peer address */ - FD local_rfd, local_wfd; /* read and write local descriptors */ - FD remote_fd; /* remote file descriptor */ -- SSL *ssl; /* SSL Connection */ - SOCKADDR_LIST bind_addr; - /* IP for explicit local bind or transparent proxy */ -- unsigned long pid; /* PID of local process */ -+ unsigned long pid; /* PID of the local process */ - int fd; /* temporary file descriptor */ -- jmp_buf err; - -+ /* data for transfer() function */ - char sock_buff[BUFFSIZE]; /* socket read buffer */ - char ssl_buff[BUFFSIZE]; /* SSL read buffer */ - int sock_ptr, ssl_ptr; /* index of first unused byte in buffer */ - FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */ - FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */ -- int sock_bytes, ssl_bytes; /* bytes written to socket and ssl */ -+ int sock_bytes, ssl_bytes; /* bytes written to socket and SSL */ - s_poll_set fds; /* file descriptors */ - } CLI; - -@@ -408,6 +410,7 @@ - int ready; /* number of ready file descriptors */ - time_t finish; /* when to finish poll() for this context */ - struct CONTEXT_STRUCTURE *next; /* next context on a list */ -+ void *tls; /* thread local storage for str.c */ - } CONTEXT; - extern CONTEXT *ready_head, *ready_tail; - extern CONTEXT *waiting_head, *waiting_tail; diff --git a/stunnel-4.36.tar.bz2 b/stunnel-4.36.tar.bz2 deleted file mode 100644 index eb13d93..0000000 --- a/stunnel-4.36.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91c5fb28603c20e7c6ec09726229157bd26b7b6924d419b5a96f3c41bd4b1403 -size 445523 diff --git a/stunnel-4.38.tar.gz b/stunnel-4.38.tar.gz new file mode 100644 index 0000000..fdd1247 --- /dev/null +++ b/stunnel-4.38.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa49012195fde4dc3e4bed2bb25283cb40a6e0ad8295a47e730652f611e2268c +size 550150 diff --git a/stunnel.changes b/stunnel.changes index cecd52e..ae2679d 100644 --- a/stunnel.changes +++ b/stunnel.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Wed Jun 29 06:08:34 UTC 2011 - daniel.rahn@novell.com + +- update package to 4.38 +* New features: + - Server-side SNI implemented (RFC 3546 section 3.1) with a new + service-level option "nsi". + - "socket" option also accepts "yes" and "no" for flags. + - Nagle's algorithm is now disabled by default for improved + interactivity. +* Bugfixes: + - A compilation fix was added for OpenSSL version < 1.0.0. + - Signal pipe set to non-blocking mode. This bug caused hangs + of stunnel features based on signals, e.g. local mode, FORK + threading, or configuration file reload on Unix. + ------------------------------------------------------------------- Mon Jun 20 07:49:41 UTC 2011 - daniel.rahn@novell.com diff --git a/stunnel.spec b/stunnel.spec index ea204cc..cbf3f80 100644 --- a/stunnel.spec +++ b/stunnel.spec @@ -19,7 +19,7 @@ BuildRequires: gcc-c++ tcp_wrappers %endif Summary: Universal SSL Tunnel License: GNU Library General Public License v. 2.0 and 2.1 (LGPL) -Version: 4.36 +Version: 4.38 Release: 0. Group: Productivity/Networking/Security URL: http://www.stunnel.org/ @@ -27,14 +27,12 @@ Autoreqprov: on %if %{?suse_version:%suse_version}%{?!suse_version:0} > 800 PreReq: /usr/sbin/useradd fileutils textutils %insserv_prereq %fillup_prereq %endif -Source: ftp://ftp.stunnel.org/stunnel/%{name}-%{version}.tar.bz2 +Source: ftp://ftp.stunnel.org/stunnel/%{name}-%{version}.tar.gz Source1: stunnel.conf Source2: stunnel.README Source3: sysconfig.syslog-stunnel Source4: stunnel.rc Patch0: stunnel-listenqueue-option.patch -Patch1: non-blocking-socket-handling.patch -Patch2: fix-ucontext-handling.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %define VENDOR SUSE %debug_package @@ -53,9 +51,7 @@ without any changes to the program code. %prep %setup -q -# %patch1 -p0 %patch0 -p0 -# %patch2 -p0 %build #autoreconf -fi