[stunnel-users] Patch for XMPP in client mode

Philipp Hartwig philipp.hartwig at uni-due.de
Thu May 5 01:27:10 CEST 2011


Hi,

I've attached a small patch which adds support for the XMPP protocol in 
client mode. It does pretty much what Brian Hatch has outlined under 
[1]. I've tested it with several Jabber servers and it seems to work 
nicely.

I'd be very happy about any comments.

Regards,
Philipp

[1] http://stunnel.mirt.net/pipermail/stunnel-users/2009-February/002278.html
-------------- next part --------------
diff -u stunnel-4.36/src/network.c stunnel-4.36-new/src/network.c
--- stunnel-4.36/src/network.c	2011-05-01 23:28:59.000000000 +0200
+++ stunnel-4.36-new/src/network.c	2011-05-05 01:04:21.865907686 +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;i<length-1; i++){
+		str[i]=str[i+1];
+	}
+	str[length-1]=chr;
+}
+
+void read_until(CLI *c, int fd, char *goalstring) {
+	s_poll_set fds;
+	char line[2];
+	char string[256];
+	int length;
+	int i;
+	length=strlen(goalstring);
+	for(i=0; i<length; i++){
+		string[i]='0';
+	}
+	string[length]='\0';
+	do {
+        s_poll_init(&fds);
+        s_poll_add(&fds, fd, 1, 0); /* read */
+        switch(s_poll_wait(&fds, c->opt->timeout_busy, 0)) {
+        case -1:
+            sockerror("read_until: s_poll_wait");
+            str_free(line);
+            longjmp(c->err, 1); /* error */
+        case 0:
+            s_log(LOG_INFO, "read_until: s_poll_wait:"
+                " TIMEOUTbusy exceeded: sending reset");
+            str_free(line);
+            longjmp(c->err, 1); /* timeout */
+        case 1:
+            break; /* OK */
+        default:
+            s_log(LOG_ERR, "read_until: s_poll_wait: unknown result");
+            str_free(line);
+            longjmp(c->err, 1); /* error */
+        }
+        switch(readsocket(fd, line, 1)) {
+        case -1: /* error */
+            sockerror("readsocket (read_until)");
+            str_free(line);
+            longjmp(c->err, 1);
+        case 0: /* EOF */
+            s_log(LOG_ERR, "Unexpected socket close (read_until)");
+            str_free(line);
+            longjmp(c->err, 1);
+        }
+		if(isspace(line[0])) 
+			line[0]=' ';
+		shiftstring(string,line[0]);
+	} while(strcmp(string, goalstring));
+}
+
 int fdprintf(CLI *c, int fd, const char *format, ...) {
     va_list ap;
     char *line;
diff -u stunnel-4.36/src/protocol.c stunnel-4.36-new/src/protocol.c
--- stunnel-4.36/src/protocol.c	2011-05-01 23:36:56.000000000 +0200
+++ stunnel-4.36-new/src/protocol.c	2011-05-05 01:25:48.792289221 +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,19 @@
     write_blocking(c, c->local_wfd.fd, ssl_ok, sizeof ssl_ok);
 }
 
+static void xmpp_client(CLI *c) {
+	char hello_end[]="</stream:features>";
+	char tls_success_start[]="<proceed ";
+	char tls_success_end[]="/>";
+	char *hostname;
+	hostname=strtok(c->opt->remote_address,":");
+	fdprintf(c, c->remote_fd.fd, "<?xml version='1.0'?><stream:stream to='%s' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>", hostname);
+	read_until(c, c->remote_fd.fd, hello_end);
+	fdputline(c, c->remote_fd.fd, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+	read_until(c, c->remote_fd.fd, tls_success_start);
+	read_until(c, c->remote_fd.fd, tls_success_end);
+}
+
 static void smtp_client(CLI *c) {
     char *line;
 
diff -u stunnel-4.36/src/prototypes.h stunnel-4.36-new/src/prototypes.h
--- stunnel-4.36/src/prototypes.h	2011-05-01 20:18:01.000000000 +0200
+++ stunnel-4.36-new/src/prototypes.h	2011-05-04 23:47:57.000000000 +0200
@@ -363,6 +363,7 @@
 void read_blocking(CLI *, int fd, void *, int);
 void fdputline(CLI *, int, const char *);
 char *fdgetline(CLI *, int);
+void read_until(CLI *, int, char *);
 /* descriptor versions of fprintf/fscanf */
 int fdprintf(CLI *, int, const char *, ...)
 #ifdef __GNUC__
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://www.stunnel.org/pipermail/stunnel-users/attachments/20110505/915dc9d8/attachment.sig>


More information about the stunnel-users mailing list