[asterisk-commits] anthonyl: branch anthonyl/testing-branch r43828 - /team/anthonyl/testing-bran...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Sep 27 14:39:40 MST 2006


Author: anthonyl
Date: Wed Sep 27 16:39:40 2006
New Revision: 43828

URL: http://svn.digium.com/view/asterisk?rev=43828&view=rev
Log:
http ssl integration limited needs some fixing but works

Modified:
    team/anthonyl/testing-branch/main/Makefile
    team/anthonyl/testing-branch/main/http.c
    team/anthonyl/testing-branch/main/manager.c

Modified: team/anthonyl/testing-branch/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/anthonyl/testing-branch/main/Makefile?rev=43828&r1=43827&r2=43828&view=diff
==============================================================================
--- team/anthonyl/testing-branch/main/Makefile (original)
+++ team/anthonyl/testing-branch/main/Makefile Wed Sep 27 16:39:40 2006
@@ -25,7 +25,7 @@
 	astmm.o enum.o srv.o dns.o aescrypt.o aestab.o aeskey.o \
 	utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
 	netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
-	cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
+	cryptostub.o sha1.o http.o  openssl.o fixedjitterbuf.o abstract_jb.o \
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static
 # objects use it.

Modified: team/anthonyl/testing-branch/main/http.c
URL: http://svn.digium.com/view/asterisk/team/anthonyl/testing-branch/main/http.c?rev=43828&r1=43827&r2=43828&view=diff
==============================================================================
--- team/anthonyl/testing-branch/main/http.c (original)
+++ team/anthonyl/testing-branch/main/http.c Wed Sep 27 16:39:40 2006
@@ -53,6 +53,7 @@
 #include "asterisk/strings.h"
 #include "asterisk/options.h"
 #include "asterisk/config.h"
+#include "asterisk/openssl.h"
 
 #define MAX_PREFIX 80
 #define DEFAULT_PREFIX "/asterisk"
@@ -61,6 +62,8 @@
 	FILE *f;
 	int fd;
 	struct sockaddr_in requestor;
+	int ast_http_ssl;
+	struct ast_openssl_context *openssl_context;
 	ast_http_callback callback;
 };
 
@@ -72,6 +75,10 @@
 static int prefix_len = 0;
 static struct sockaddr_in oldsin;
 static int enablestatic=0;
+static pthread_t t;
+static pthread_t ssl_main_thread;
+static int session_count;
+static int ssl_session_count;
 
 /*! \brief Limit the kinds of files we're willing to serve up */
 static struct {
@@ -84,6 +91,7 @@
 	{ "wav", "audio/x-wav" },
 	{ "mp3", "audio/mpeg" },
 };
+
 
 static char *ftype2mtype(const char *ftype, char *wkspace, int wkspacelen)
 {
@@ -283,6 +291,7 @@
 	int len;
 	struct ast_variable *vars=NULL, *v, *prev = NULL;
 	
+	ast_verbose("trying to access uri %s\n",uri);
 	
 	params = strchr(uri, '?');
 	if (params) {
@@ -335,6 +344,7 @@
 			}
 		}
 	}
+	
 	if (urih) {
 		c = urih->callback(sin, uri, vars, status, title, contentlength);
 		ast_variables_destroy(vars);
@@ -351,98 +361,190 @@
 	return c;
 }
 
+
+/* the main ssl_httpd server instanse */
+static void *ast_httpd_ssl_main(void *data)
+{
+  	int ret;
+	pthread_attr_t attr;
+	struct eventqent *eqe;
+	struct mansession *s;
+	struct protoent *p;
+	struct ast_openssl_context *openssl_context;
+	int arg = 1;
+	int flags;
+	time_t now;
+       	int fd_ssl;
+	int accept_sock;
+	
+	/* the struct for dealing with all the http bits */
+
+	struct ast_http_server_instance *ser;
+	
+	pthread_attr_init(&attr);
+  	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+	openssl_context = ast_socket_openssl(4444,AST_SOCKET_SSL3);
+
+	if (openssl_context == NULL || openssl_context == -1) {
+		ast_log(LOG_WARNING,"we could not bind the openssl socket!\n");
+		return;
+	}
+	
+	/* we need to poll for new connections here and also do the per session thingie */
+
+	for (;;) {
+		accept_sock = ast_openssl_accept(openssl_context);
+		openssl_context->accept_sock = accept_sock;
+		ast_openssl_accept_connection(openssl_context);
+
+		ser = ast_calloc(1, sizeof(*ser));
+		
+		if (ser) {
+			
+			memcpy(&ser->requestor, &openssl_context->sin, sizeof(ser->requestor));
+			ser->ast_http_ssl = 1;
+			ser->openssl_context = openssl_context;
+			/* should this be pthread'ed ? .. maybe later */
+			ast_httpd_helper_thread(ser);
+		}
+		
+	}
+
+	
+	return;
+}
+
 static void *ast_httpd_helper_thread(void *data)
 {
 	char buf[4096];
 	char cookie[4096];
 	char timebuf[256];
+	char outbuf[4096];
 	struct ast_http_server_instance *ser = data;
 	struct ast_variable *var, *prev=NULL, *vars=NULL;
 	char *uri, *c, *title=NULL;
 	char *vname, *vval;
 	int status = 200, contentlength = 0;
 	time_t t;
-
-	if (fgets(buf, sizeof(buf), ser->f)) {
-		/* Skip method */
+	int ret;
+
+
+	/* make sure that we null up buf before we do anything */
+	memset(&buf,0x00,sizeof(buf));
+	
+	if (ser->ast_http_ssl) {
+	       
+		ret = ast_ssl_read(ser->openssl_context,&buf,sizeof(buf)-1);
 		uri = buf;
-		while(*uri && (*uri > 32))
+
+		while (*uri && (*uri > 32))
 			uri++;
+		
 		if (*uri) {
 			*uri = '\0';
 			uri++;
 		}
-
-		/* Skip white space */
-		while (*uri && (*uri < 33))
-			uri++;
-
-		if (*uri) {
-			c = uri;
-			while (*c && (*c > 32))
-				 c++;
-			if (*c) {
-				*c = '\0';
+				
+	} else {
+
+		ast_verbose("calling the non-ssl fgets \n");
+		if (fgets(buf, sizeof(buf), ser->f)) {
+			/* Skip method */
+			uri = buf;
+			while(*uri && (*uri > 32))
+				uri++;
+			if (*uri) {
+				*uri = '\0';
+				uri++;
 			}
-		}
-
-		while (fgets(cookie, sizeof(cookie), ser->f)) {
-			/* Trim trailing characters */
-			while(!ast_strlen_zero(cookie) && (cookie[strlen(cookie) - 1] < 33)) {
-				cookie[strlen(cookie) - 1] = '\0';
-			}
-			if (ast_strlen_zero(cookie))
-				break;
-			if (!strncasecmp(cookie, "Cookie: ", 8)) {
-
-				/* TODO - The cookie parsing code below seems to work   
-				   in IE6 and FireFox 1.5.  However, it is not entirely 
-				   correct, and therefore may not work in all           
-				   circumstances.		                        
-				      For more details see RFC 2109 and RFC 2965        */
 			
-				/* FireFox cookie strings look like:                    
-				     Cookie: mansession_id="********"                   
-				   InternetExplorer's look like:                        
-				     Cookie: $Version="1"; mansession_id="********"     */
-				
-				/* If we got a FireFox cookie string, the name's right  
-				    after "Cookie: "                                    */
-                                vname = cookie + 8;
-				
-				/* If we got an IE cookie string, we need to skip to    
-				    past the version to get to the name                 */
-				if (*vname == '$') {
-					vname = strchr(vname, ';');
-					if (vname) { 
-						vname++;
-						if (*vname == ' ')
+		} 
+		
+	}
+	
+	/* Skip white space */
+	while (*uri && (*uri < 33))
+		uri++;
+	
+	if (*uri) {
+		c = uri;
+		while (*c && (*c > 32))
+			c++;
+		if (*c) {
+			*c = '\0';
+		}
+		
+		/* are we using ssl ? */
+		if (ser->ast_http_ssl) {
+			
+			/* grab the cookie from the http header ..etc */
+			ast_verbose("we are in the cookie routine\n");
+
+		} else {
+									
+			while (fgets(cookie, sizeof(cookie), ser->f)) {
+				/* Trim trailing characters */
+				while(!ast_strlen_zero(cookie) && (cookie[strlen(cookie) - 1] < 33)) {
+					cookie[strlen(cookie) - 1] = '\0';
+				}
+				if (ast_strlen_zero(cookie))
+					break;
+				if (!strncasecmp(cookie, "Cookie: ", 8)) {
+
+					/* TODO - The cookie parsing code below seems to work   
+					   in IE6 and FireFox 1.5.  However, it is not entirely 
+					   correct, and therefore may not work in all           
+					   circumstances.		                        
+					   For more details see RFC 2109 and RFC 2965        */
+					
+					/* FireFox cookie strings look like:                    
+					   Cookie: mansession_id="********"                   
+					   InternetExplorer's look like:                        
+					   Cookie: $Version="1"; mansession_id="********"     */
+					
+					/* If we got a FireFox cookie string, the name's right  
+					   after "Cookie: "                                    */
+					vname = cookie + 8;
+					
+					/* If we got an IE cookie string, we need to skip to    
+					   past the version to get to the name                 */
+					if (*vname == '$') {
+						vname = strchr(vname, ';');
+						if (vname) { 
 							vname++;
+							if (*vname == ' ')
+								vname++;
+						}
 					}
-				}
-				
-				if (vname) {
-					vval = strchr(vname, '=');
-					if (vval) {
-						/* Ditch the = and the quotes */
-						*vval++ = '\0';
-						if (*vval)
-							vval++;
-						if (strlen(vval))
-							vval[strlen(vval) - 1] = '\0';
-						var = ast_variable_new(vname, vval);
-						if (var) {
-							if (prev)
-								prev->next = var;
-							else
-								vars = var;
-							prev = var;
+					
+					if (vname) {
+						vval = strchr(vname, '=');
+						if (vval) {
+							/* Ditch the = and the quotes */
+							*vval++ = '\0';
+							if (*vval)
+								vval++;
+							if (strlen(vval))
+								vval[strlen(vval) - 1] = '\0';
+							var = ast_variable_new(vname, vval);
+							if (var) {
+								if (prev)
+									prev->next = var;
+								else
+									vars = var;
+								prev = var;
+							}
 						}
 					}
 				}
 			}
-		}
-
+			
+		} /* end the non-ssl cookie processing */
+
+
+		/* c is the result of handle_uri */
+		/* it is just a standard char * */
 		if (*uri) {
 			if (!strcasecmp(buf, "get")) 
 				c = handle_uri(&ser->requestor, uri, &status, &title, &contentlength, &vars);
@@ -454,32 +556,118 @@
 		/* If they aren't mopped up already, clean up the cookies */
 		if (vars)
 			ast_variables_destroy(vars);
-
+		
 		if (!c)
 			c = ast_http_error(500, "Internal Error", NULL, "Internal Server Error");
 		if (c) {
 			time(&t);
+
+			
 			strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t));
-			ast_cli(ser->fd, "HTTP/1.1 %d %s\r\n", status, title ? title : "OK");
-			ast_cli(ser->fd, "Server: Asterisk\r\n");
-			ast_cli(ser->fd, "Date: %s\r\n", timebuf);
-			ast_cli(ser->fd, "Connection: close\r\n");
+
+			ast_verbose("we have reached the time formating\n");
+			if (ser->ast_http_ssl) {
+				int i = 0;
+				memset( (char *)&outbuf,0x00,sizeof(outbuf));
+
+				i =  snprintf( (char *)&outbuf + i,(sizeof(outbuf) - i ), "HTTP/1.1 %d %s\r\n",status,title ? title : "OK" );
+				i += snprintf( (char *)&outbuf + i,(sizeof(outbuf) - i),  "Server: Asterisk\r\n");
+				i += snprintf( (char *)&outbuf + i,(sizeof(outbuf) - i),  "Date: %s\r\n",timebuf);
+				i += snprintf( (char *)&outbuf + i,(sizeof(outbuf) - i),  "Connection: close\r\n");
+
+				/* this is where we will need to store the cookies that we want to send out */
+				
+				ast_verbose("%s\n",outbuf);
+				ast_verbose("-------------------------------------\n");
+				
+			} else {
+				ast_cli(ser->fd, "HTTP/1.1 %d %s\r\n", status, title ? title : "OK");
+				ast_cli(ser->fd, "Server: Asterisk\r\n");
+				ast_cli(ser->fd, "Date: %s\r\n", timebuf);
+				ast_cli(ser->fd, "Connection: close\r\n");
+			}
+
+			
 			if (contentlength) {
 				char *tmp;
+				char *p;
+
 				tmp = strstr(c, "\r\n\r\n");
 				if (tmp) {
-					ast_cli(ser->fd, "Content-length: %d\r\n", contentlength);
-					write(ser->fd, c, (tmp + 4 - c));
-					write(ser->fd, tmp + 4, contentlength);
+
+					if (ser->ast_http_ssl) {
+						p = (char *)&outbuf;
+						p += strlen(outbuf);
+
+						sprintf(p,"Content-length: %d\r\n",contentlength);
+
+						ast_verbose("with contentlength----\n%s",outbuf);
+						
+					} else {
+						ast_cli(ser->fd, "Content-length: %d\r\n", contentlength);
+					}
+
+
+					/* add the ability to write ssl out here */
+					/* it would be great if we could write into a buffer write.. sprintf maybe */
+
+					if (ser->ast_http_ssl) {
+						char *out;
+
+						out = malloc((strlen(outbuf)+strlen(c)+4));
+						
+						if (!out) {
+							ast_log(LOG_ERROR,"We failed to allocate some memory!\n");
+							return;
+						}
+
+						sprintf(out,"%s%s\r\n\r\n",outbuf,c);
+						
+						/* send the output via https */
+						ast_verbose("--- ssl output -------------------------------------\n");
+						ast_verbose("%s\n",out);
+						ast_verbose("----------------------------------------------------\n");
+						 ast_ssl_write(ser->openssl_context ,tmp,strlen(tmp));
+					} else {
+						write(ser->fd, c, (tmp + 4 - c));
+						write(ser->fd, tmp + 4, contentlength);
+					}
+					
 				}
-			} else
-				ast_cli(ser->fd, "%s", c);
+				
+			} else {
+				if (ser->ast_http_ssl) {
+					char *out;
+
+					out = malloc( strlen(c) + strlen(outbuf) + 2);
+
+					if (!out) {
+						ast_verbose("failed to make a memory allocation!!\n");
+						return;
+					}
+					
+					sprintf(out,"%s%s\0",outbuf,c);
+					ast_ssl_write(ser->openssl_context,out,strlen(out));
+									
+					free(out);
+					
+				} else {
+					ast_cli(ser->fd, "%s", c);
+				}
+			}
+			
 			free(c);
 		}
 		if (title)
 			free(title);
 	}
-	fclose(ser->f);
+
+	if (!ser->ast_http_ssl) {
+		fclose(ser->f);
+	} else {
+		close(ser->openssl_context->accept_sock);
+	}
+
 	free(ser);
 	return NULL;
 }
@@ -502,7 +690,9 @@
 				ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
 			continue;
 		}
+		
 		ser = ast_calloc(1, sizeof(*ser));
+		
 		if (ser) {
 			ser->fd = fd;
 			memcpy(&ser->requestor, &sin, sizeof(ser->requestor));
@@ -603,6 +793,7 @@
 	struct ast_variable *v;
 	int enabled=0;
 	int newenablestatic=0;
+	int enablessl=0;
 	struct sockaddr_in sin;
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -619,6 +810,8 @@
 				enabled = ast_true(v->value);
 			else if (!strcasecmp(v->name, "enablestatic"))
 				newenablestatic = ast_true(v->value);
+			else if (!strcasecmp(v->name, "enablessl"))
+				 enablessl = ast_true(v->value);
 			else if (!strcasecmp(v->name, "bindport"))
 				sin.sin_port = ntohs(atoi(v->value));
 			else if (!strcasecmp(v->name, "bindaddr")) {
@@ -646,6 +839,14 @@
 		ast_copy_string(prefix, newprefix, sizeof(prefix));
 		prefix_len = strlen(prefix);
 	}
+        
+        /* we are going to need to spawn the SSL based interface here */
+        /* and pass the data along to the handling routines */
+
+	if (enablessl) {
+		ast_pthread_create(&ssl_main_thread,NULL,ast_httpd_ssl_main ,NULL);
+	}
+	
 	enablestatic = newenablestatic;
 	http_server_start(&sin);
 	return 0;

Modified: team/anthonyl/testing-branch/main/manager.c
URL: http://svn.digium.com/view/asterisk/team/anthonyl/testing-branch/main/manager.c?rev=43828&r1=43827&r2=43828&view=diff
==============================================================================
--- team/anthonyl/testing-branch/main/manager.c (original)
+++ team/anthonyl/testing-branch/main/manager.c Wed Sep 27 16:39:40 2006
@@ -69,7 +69,7 @@
 #include "asterisk/threadstorage.h"
 #include "asterisk/linkedlists.h"
 /* include for the openssl info */
-/* #include "asterisk/openssl.h" */
+#include "asterisk/openssl.h"
 
 
 struct fast_originate_helper {
@@ -189,7 +189,7 @@
 static void *session_do(void *data);
 
 /* this is the main thread for manaing ssl manager connections */
-/*
+
 static int *astman_ssl_thread(void)
 {
   	int ret;
@@ -203,19 +203,31 @@
 	time_t now;
 	struct pollfd pfds[1];
        	int fd_ssl;
-	
+	char buf[1024];
+	int content_len;
+
+	/* a lame https test remove me, it was just for a short example */
+	/* ignore the poor style on this ..etc */
+	char html[] = "HTTP/1.0 200 OK\r\n"
+		"Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"
+		"Content-Type: text/html\r\n"
+		"Content-Length: 9001\r\n\r\n"
+		"<HTML> <HEAD>Asterisk SSL</head> <BODY> HELLO!!! </BODY> </HTML>";
+
         pthread_attr_init(&attr);
   	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 	
-	for(;;) {
-  	 	openssl_context = ast_socket_openssl(5039,AST_SOCKET_TLS1);
-		
-  		if (openssl_context == NULL) {
-        		ast_log(LOG_WARNING, "Error binding SSL socket\n");
-  		}
-
-		return 0;
-	}
+
+	openssl_context = ast_socket_openssl(5040,AST_SOCKET_SSL3);
+	
+	if (openssl_context == NULL) {
+		ast_log(LOG_WARNING, "Error binding SSL socket\n");
+	}
+	
+	ret = ast_ssl_read(openssl_context, &buf, sizeof(buf));
+	//printf("we have read %i bytes ssl style\n",ret);    
+	
+	ast_ssl_write(openssl_context,&html,sizeof(html));
 	
 	
 	if (!(s = ast_calloc(1, sizeof(*s)))) {
@@ -232,12 +244,16 @@
 	
 	s->flag_ssl = 1;
 
+        /* test reading and writing using the openssl api here first */
+        /* before we go on with using this api for anything that cirtical */
+        
+       
 	if (ast_pthread_create(&s->t, &attr, session_do ,s)) {
 	}
 	
   return 0;
 }
-*/
+
 
 /*! \brief Convert authority code to string with serveral options */
 static char *authority_to_str(int authority, char *res, int reslen)
@@ -1920,6 +1936,13 @@
 }
 
 
+/* the ssl enabled version of get_input() */
+static int get_input_ssl(struct mansession *s, char *output)
+{
+
+	return 0;
+}
+
 static int get_input(struct mansession *s, char *output)
 {
 	/* output must have at least sizeof(s->inbuf) space */
@@ -1975,6 +1998,7 @@
 	s->inbuf[s->inlen] = '\0';
 	return 0;
 }
+
 
 static void *session_do(void *data)
 {
@@ -2660,13 +2684,13 @@
 			ast_verbose("Asterisk Management interface listening on port %d\n", portno);
 		
 		ast_pthread_create(&t, NULL, accept_thread, NULL);
-	/*	
+		
 		if(ssl_on) {
 		  ast_pthread_create(&ssl_main_thread,NULL,astman_ssl_thread ,NULL);
 		  if (option_verbose)
 		    ast_verbose("Asterisk Managment interface SSL starting\n");
 		}
-	*/
+	
 
 	}
 	return 0;



More information about the asterisk-commits mailing list