- fix ucontext handling (backport from v4.37)
- fix non-blocking socket handling (backport from v4.37) OBS-URL: https://build.opensuse.org/package/show/security:Stunnel/stunnel?expand=0&rev=42
This commit is contained in:
parent
7464662073
commit
dc83cf7bf4
441
fix-ucontext-handling.patch
Normal file
441
fix-ucontext-handling.patch
Normal file
@ -0,0 +1,441 @@
|
||||
--- 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"))
|
@ -1,159 +1,3 @@
|
||||
--- 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;
|
||||
}
|
||||
@@ -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/stunnel.c 2011/06/18 04:05:08 1.1
|
||||
+++ src/stunnel.c 2011/06/18 04:09:42
|
||||
@@ -496,11 +496,9 @@
|
||||
@ -229,13 +73,61 @@
|
||||
}
|
||||
|
||||
/**************************************** log messages to identify build */
|
||||
--- src/prototypes.h 2011/06/18 04:05:02 1.1
|
||||
+++ src/prototypes.h 2011/06/18 04:06:08
|
||||
@@ -256,6 +256,7 @@
|
||||
int s_accept(int, struct sockaddr *, socklen_t *, int, char *);
|
||||
void stunnel_info(int);
|
||||
void die(int);
|
||||
+void set_nonblock(int, unsigned long);
|
||||
--- 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 log.c */
|
||||
/**************************************** 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;
|
||||
|
@ -1,7 +1,12 @@
|
||||
-------------------------------------------------------------------
|
||||
Sat Jun 18 10:04:29 UTC 2011 - daniel.rahn@novell.com
|
||||
|
||||
- fix ucontext handling (backport from v4.37)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Jun 18 03:59:20 UTC 2011 - daniel.rahn@novell.com
|
||||
|
||||
- fix non-blocking socket handling (backport from 4.37)
|
||||
- fix non-blocking socket handling (backport from v4.37)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 16 11:44:32 UTC 2011 - daniel.rahn@novell.com
|
||||
|
@ -34,6 +34,7 @@ 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
|
||||
|
||||
@ -50,8 +51,9 @@ without any changes to the program code.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch0 -p0
|
||||
%patch1 -p0
|
||||
%patch0 -p0
|
||||
%patch2 -p0
|
||||
|
||||
%build
|
||||
#autoreconf -fi
|
||||
|
Loading…
x
Reference in New Issue
Block a user