diff -u Desktop/stunnel-4.36/src/network.c Desktop/stunnel-4.36-new/src/network.c --- Desktop/stunnel-4.36/src/network.c 2011-05-01 23:28:59.000000000 +0200 +++ Desktop/stunnel-4.36-new/src/network.c 2011-05-05 23:51:33.453643619 +0200 @@ -727,6 +727,64 @@ return line; } +/* shifts "str" to the left by 1, discarding the first character and appends "chr" as the last character */ +static void shiftstring(char *str, char chr) { + int i; + int length; + length=strlen(str); + for(i=0;iopt->timeout_busy, 0)) { + case -1: + sockerror("read_until: s_poll_wait"); + longjmp(c->err, 1); /* error */ + case 0: + s_log(LOG_INFO, "read_until: s_poll_wait:" + " TIMEOUTbusy exceeded: sending reset"); + longjmp(c->err, 1); /* timeout */ + case 1: + break; /* OK */ + default: + s_log(LOG_ERR, "read_until: s_poll_wait: unknown result"); + longjmp(c->err, 1); /* error */ + } + switch(readsocket(fd, line, 1)) { + case -1: /* error */ + sockerror("readsocket (read_until)"); + longjmp(c->err, 1); + case 0: /* EOF */ + s_log(LOG_ERR, "Unexpected socket close (read_until)"); + longjmp(c->err, 1); + } + if(line[0] == '"') + line[0]='\''; + if(!isspace(line[0])) + shiftstring(string,line[0]); + } while(strcmp(string, goalstring1)!=0 && !strstr(string, goalstring2)); + if(strcmp(string, goalstring1)==0) + return 0; + else + return 1; +} + int fdprintf(CLI *c, int fd, const char *format, ...) { va_list ap; char *line; diff -u Desktop/stunnel-4.36/src/protocol.c Desktop/stunnel-4.36-new/src/protocol.c --- Desktop/stunnel-4.36/src/protocol.c 2011-05-01 23:36:56.000000000 +0200 +++ Desktop/stunnel-4.36-new/src/protocol.c 2011-05-05 23:35:13.080782201 +0200 @@ -56,6 +56,7 @@ static void nntp_client(CLI *); static void connect_client(CLI *); static void ntlm(CLI *); +static void xmpp_client(CLI *); #ifndef OPENSSL_NO_MD4 static char *ntlm1(); static char *ntlm3(char *, char *, char *); @@ -79,6 +80,8 @@ pop3_client(c); else if(!strcmp(c->opt->protocol, "imap")) imap_client(c); + else if(!strcmp(c->opt->protocol, "xmpp")) + xmpp_client(c); else if(!strcmp(c->opt->protocol, "nntp")) nntp_client(c); else if(!strcmp(c->opt->protocol, "connect")) @@ -180,6 +183,28 @@ write_blocking(c, c->local_wfd.fd, ssl_ok, sizeof ssl_ok); } +static void xmpp_client(CLI *c) { + char hello_end1[]=""; + char hello_end2[]=""; + char tls_success[]="remote_fd.fd, "",strtok(c->opt->remote_address,":")); + if(read_until_alternatives(c, c->remote_fd.fd, hello_end1, hello_end2)) { + s_log(LOG_ERR, "XMPP server didn't advertise any features"); + longjmp(c->err, 1); + } + write_blocking(c, c->remote_fd.fd, starttls_command, strlen(starttls_command)); + s_log(LOG_DEBUG, " -> %s", starttls_command); + if(read_until_alternatives(c, c->remote_fd.fd, tls_success,tls_failure)) { + s_log(LOG_ERR, "XMPP server rejected starttls"); + longjmp(c->err, 1); + } + read_until_alternatives(c, c->remote_fd.fd, tls_success_end1,tls_success_end2); +} + static void smtp_client(CLI *c) { char *line; diff -u Desktop/stunnel-4.36/src/prototypes.h Desktop/stunnel-4.36-new/src/prototypes.h --- Desktop/stunnel-4.36/src/prototypes.h 2011-05-01 20:18:01.000000000 +0200 +++ Desktop/stunnel-4.36-new/src/prototypes.h 2011-05-05 23:54:14.770443545 +0200 @@ -363,6 +363,7 @@ void read_blocking(CLI *, int fd, void *, int); void fdputline(CLI *, int, const char *); char *fdgetline(CLI *, int); +int read_until_alternatives(CLI *, int, char *, char *); /* descriptor versions of fprintf/fscanf */ int fdprintf(CLI *, int, const char *, ...) #ifdef __GNUC__