[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