diff options
-rw-r--r-- | configs/http.conf.sample | 19 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | main/Makefile | 2 | ||||
-rw-r--r-- | main/http.c | 63 |
4 files changed, 66 insertions, 25 deletions
diff --git a/configs/http.conf.sample b/configs/http.conf.sample index 7135463d6..7ee1de9a5 100644 --- a/configs/http.conf.sample +++ b/configs/http.conf.sample @@ -4,7 +4,8 @@ ; [general] ; -; Whether HTTP interface is enabled or not. Default is no. +; Whether HTTP/HTTPS interface is enabled or not. Default is no. +; This also affects manager/rawman/mxml access (see manager.conf) ; ;enabled=yes ; @@ -13,16 +14,26 @@ ; ;enablestatic=yes ; -; Address to bind to. Default is 0.0.0.0 +; Address to bind to, both for HTTP and HTTPS. Default is 0.0.0.0 ; bindaddr=127.0.0.1 ; -; Port to bind to (default is 8088) +; Port to bind to for HTTP sessions (default is 8088) ; -bindport=8088 +;bindport=8088 ; ; Prefix allows you to specify a prefix for all requests ; to the server. The default is "asterisk" so that all ; requests must begin with /asterisk ; ;prefix=asterisk + +; HTTPS support: you need to enable it, define the port to use, +; and have a certificate somewhere. +; sslenable=yes ; enable ssl - default no. +; sslbindport=4433 ; port to use - default is 8089 +; sslcert=/tmp/foo.pem ; path to the certificate +; +; To produce a certificate you can e.g. use openssl +; openssl req -new -x509 -days 365 -nodes -out /tmp/foo.pem -keyout /tmp/foo.pem +; diff --git a/configure.ac b/configure.ac index 80ac4e90b..0cc4ac562 100644 --- a/configure.ac +++ b/configure.ac @@ -251,6 +251,13 @@ AC_FUNC_UTIME_NULL AC_FUNC_VPRINTF AC_CHECK_FUNCS([asprintf atexit bzero dup2 endpwent floor ftruncate getcwd gethostbyname gethostname getloadavg gettimeofday inet_ntoa isascii localtime_r memchr memmove memset mkdir munmap pow putenv re_comp regcomp rint select setenv socket sqrt strcasecmp strcasestr strchr strcspn strdup strerror strncasecmp strndup strnlen strrchr strsep strspn strstr strtol strtoq unsetenv utime vasprintf]) +# https support (in main/http.c) uses funopen on BSD systems, +# fopencookie on linux +AC_CHECK_FUNCS([funopen fopencookie]) + +# some systems already have gethostbyname_r so we don't need to build ours in main/utils.c +AC_CHECK_FUNCS([gethostbyname_r]) + AC_MSG_CHECKING(for compiler atomic operations) AC_LINK_IFELSE( AC_LANG_PROGRAM([], [int foo1; int foo2 = __sync_fetch_and_add(&foo1, 1);]), diff --git a/main/Makefile b/main/Makefile index 4a47104f2..3e631d769 100644 --- a/main/Makefile +++ b/main/Makefile @@ -37,6 +37,8 @@ OBJS+=stdtime/localtime.o # by a module. OBJS+=say.o +AST_LIBS += $(SSL_LIB) + ifeq ($(wildcard /usr/include/sys/poll.h),) OBJS+=poll.o ASTCFLAGS+=-DPOLLCOMPAT diff --git a/main/http.c b/main/http.c index 10b855700..8465323ff 100644 --- a/main/http.c +++ b/main/http.c @@ -64,8 +64,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * We declare most of ssl support variables unconditionally, * because their number is small and this simplifies the code. */ -#ifdef HAVE_OPENSSL -// #define DO_SSL /* comment in/out if you want to support ssl */ +#if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE)) +#define DO_SSL /* comment in/out if you want to support ssl */ #endif #ifdef DO_SSL @@ -428,30 +428,36 @@ static char *handle_uri(struct sockaddr_in *sin, char *uri, int *status, char ** } #ifdef DO_SSL +#if defined(HAVE_FUNOPEN) +#define HOOK_T int +#define LEN_T int +#else +#define HOOK_T ssize_t +#define LEN_T size_t +#endif /*! * replacement read/write functions for SSL support. * We use wrappers rather than SSL_read/SSL_write directly so * we can put in some debugging. */ -static int ssl_read(void *cookie, char *buf, int len) +static HOOK_T ssl_read(void *cookie, char *buf, LEN_T len) { - int i; - i = SSL_read(cookie, buf, len-1); + int i = SSL_read(cookie, buf, len-1); #if 0 if (i >= 0) buf[i] = '\0'; - ast_verbose("ssl read size %d returns %d <%s>\n", len, i, buf); + ast_verbose("ssl read size %d returns %d <%s>\n", (int)len, i, buf); #endif return i; } -static int ssl_write(void *cookie, const char *buf, int len) +static HOOK_T ssl_write(void *cookie, const char *buf, LEN_T len) { #if 0 char *s = alloca(len+1); strncpy(s, buf, len); s[len] = '\0'; - ast_verbose("ssl write size %d <%s>\n", len, s); + ast_verbose("ssl write size %d <%s>\n", (int)len, s); #endif return SSL_write(cookie, buf, len); } @@ -463,7 +469,7 @@ static int ssl_close(void *cookie) SSL_free(cookie); return 0; } -#endif +#endif /* DO_SSL */ static void *ast_httpd_helper_thread(void *data) { @@ -474,24 +480,38 @@ static void *ast_httpd_helper_thread(void *data) char *uri, *c, *title=NULL; int status = 200, contentlength = 0; + /* + * open a FILE * as appropriate. + */ + if (!ser->is_ssl) + ser->f = fdopen(ser->fd, "w+"); #ifdef DO_SSL - if (ser->is_ssl) { - ser->ssl = SSL_new(ssl_ctx); + else if ( (ser->ssl = SSL_new(ssl_ctx)) ) { SSL_set_fd(ser->ssl, ser->fd); - if (SSL_accept(ser->ssl) == 0) { + if (SSL_accept(ser->ssl) == 0) ast_verbose(" error setting up ssl connection"); - goto done; - } - ser->f = funopen(ser->ssl, ssl_read, ssl_write, NULL, ssl_close); - } else + else { +#if defined(HAVE_FUNOPEN) /* the BSD interface */ + ser->f = funopen(ser->ssl, ssl_read, ssl_write, NULL, ssl_close); + +#elif defined(HAVE_FOPENCOOKIE) /* the glibc/linux interface */ + static const cookie_io_functions_t cookie_funcs = { + ssl_read, ssl_write, NULL, ssl_close + }; + ser->f = fopencookie(ser->ssl, "w+", cookie_funcs); +#else + /* could add other methods here */ #endif - ser->f = fdopen(ser->fd, "w+"); + } + if (!ser->f) /* no success opening descriptor stacking */ + SSL_free(ser->ssl); + } +#endif /* DO_SSL */ if (!ser->f) { - ast_log(LOG_WARNING, "fdopen/funopen failed!\n"); close(ser->fd); - free(ser); - return NULL; + ast_log(LOG_WARNING, "FILE * open failed!\n"); + goto done; } if (!fgets(buf, sizeof(buf), ser->f)) @@ -605,7 +625,8 @@ static void *ast_httpd_helper_thread(void *data) free(title); done: - fclose(ser->f); + if (ser->f) + fclose(ser->f); free(ser); return NULL; } |