summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/http.conf.sample19
-rw-r--r--configure.ac7
-rw-r--r--main/Makefile2
-rw-r--r--main/http.c63
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;
}