- Added HTTPS support for SSL/TLS-enabled HTTP proxies
authormichael <michael@82007160-df01-0410-b94d-b575c5fd34c7>
Wed, 1 Jul 2015 18:09:27 +0000 (18:09 +0000)
committermichael <michael@82007160-df01-0410-b94d-b575c5fd34c7>
Wed, 1 Jul 2015 18:09:27 +0000 (18:09 +0000)
git-svn-id: svn://svn.ircd-hybrid.org/svnroot/hopm/trunk@6222 82007160-df01-0410-b94d-b575c5fd34c7

configure.ac
doc/reference.conf
m4/ax_arg_openssl.m4 [new file with mode: 0644]
src/config-lexer.l
src/libopm/src/libopm.c
src/libopm/src/libopm.h
src/libopm/src/opm_types.h
src/libopm/src/proxy.c
src/libopm/src/proxy.h
src/scan.c
src/stats.c

index bb2fe7a85562750c7616bd5fcc4881d737365edc..4c1931fbeee7be9426f1f9959588ee8e1874f627 100644 (file)
@@ -28,6 +28,7 @@ GCC_STACK_PROTECT_CC
 GCC_STACK_PROTECT_LIB
 
 AX_LIBRARY_NET
+AX_ARG_OPENSSL
 AX_ARG_ENABLE_ASSERT
 AX_ARG_ENABLE_WARNINGS
 
index fb830757e42da153b234f2b9bc42e7c01724b58e..4cc24c5a9a26f35c75b955a88d9529094f879dfa 100644 (file)
@@ -467,6 +467,9 @@ scanner {
        protocol = HTTP:3128;
        protocol = HTTP:6588;
 
+       protocol = HTTPS:443;
+       protocol = HTTPS:8443;
+
        /*
         * SOCKS4/5 - well known proxy protocols, probably the second most
         * common for insecure proxies, also offers transparent two way TCP
@@ -511,6 +514,9 @@ scanner {
         */
        protocol = HTTPPOST:80;
 
+       protocol = HTTPSPOST:443;
+       protocol = HTTPSPOST:8443;
+
        /*
         * IP address this scanner will bind to. Use this if you need your scans to
         * come FROM a particular interface on the machine you run HOPM from.
diff --git a/m4/ax_arg_openssl.m4 b/m4/ax_arg_openssl.m4
new file mode 100644 (file)
index 0000000..324555b
--- /dev/null
@@ -0,0 +1,84 @@
+AC_DEFUN([AX_ARG_OPENSSL], [
+AC_ARG_ENABLE(openssl,
+[  --enable-openssl[=DIR]       Enable LibreSSL/OpenSSL support (DIR optional).
+  --disable-openssl            Disable LibreSSL/OpenSSL support. ],
+[ cf_enable_openssl=$enableval ],
+[ cf_enable_openssl="auto" ])
+AC_MSG_CHECKING([for LibreSSL/OpenSSL])
+if test "$cf_enable_openssl" != "no"; then
+  cf_openssl_basedir=""
+  if test "$cf_enable_openssl" != "auto" &&
+     test "$cf_enable_openssl" != "yes"; then
+     dnl Support for --enable-openssl=/some/place
+     cf_openssl_basedir="${cf_enable_openssl}"
+  else
+    dnl Do the auto-probe here.  Check some common directory paths.
+    for dirs in /usr/local/ssl /usr/pkg /usr/local /usr/lib /usr/lib/ssl\
+                /opt /opt/openssl /usr/local/openssl; do
+      if test -f "${dirs}/include/openssl/opensslv.h"; then
+        cf_openssl_basedir="${dirs}"
+        break
+      fi
+    done
+    unset dirs
+  fi
+
+  dnl Now check cf_openssl_found to see if we found anything.
+  if test ! -z "$cf_openssl_basedir"; then
+    if test -f "${cf_openssl_basedir}/include/openssl/opensslv.h"; then
+      CPPFLAGS="-I${cf_openssl_basedir}/include $CPPFLAGS"
+      LDFLAGS="-L${cf_openssl_basedir}/lib $LDFLAGS"
+    else
+      dnl OpenSSL wasn't found in the directory specified.  Naughty
+      dnl administrator...
+      cf_openssl_basedir=""
+    fi
+  else
+    dnl Check for stock FreeBSD 4.x and 5.x systems, since their files
+    dnl are in /usr/include and /usr/lib.  In this case, we don't want to
+    dnl change INCLUDES or LIBS, but still want to enable OpenSSL.
+    dnl We can't do this check above, because some people want two versions
+    dnl of OpenSSL installed (stock FreeBSD 4.x/5.x and /usr/local/ssl)
+    dnl and they want /usr/local/ssl to have preference.
+    if test -f "/usr/include/openssl/opensslv.h"; then
+      cf_openssl_basedir="/usr"
+    fi
+  fi
+
+  dnl If we have a basedir defined, then everything is okay.  Otherwise,
+  dnl we have a problem.
+  if test ! -z "$cf_openssl_basedir"; then
+    AC_MSG_RESULT([$cf_openssl_basedir])
+    cf_enable_openssl="yes"
+  else
+    AC_MSG_RESULT([not found. Please check your path.])
+    cf_enable_openssl="no"
+  fi
+  unset cf_openssl_basedir
+else
+  dnl If --disable-openssl was specified
+  AC_MSG_RESULT([disabled])
+fi
+
+AS_IF([test "$cf_enable_openssl" != "no"],
+ [AC_MSG_CHECKING(for LibreSSL or OpenSSL 0.9.8o and above)
+  AC_RUN_IFELSE([
+    AC_LANG_PROGRAM([
+    #include <openssl/opensslv.h>
+    #include <stdlib.h>],
+    [[ exit(!(OPENSSL_VERSION_NUMBER >= 0x009080ffL)); ]])],
+  [cf_openssl_version_ok=yes],
+  [cf_openssl_version_ok=no],
+  [cf_openssl_version_ok=no])
+
+  AS_IF([test "$cf_openssl_version_ok" = "yes"],
+    [AC_MSG_RESULT(found)
+
+    AC_CHECK_LIB(crypto, RSA_free)
+    AS_IF([test "$ac_cv_lib_crypto_RSA_free" = "yes"],
+      [AC_CHECK_LIB(ssl, SSL_connect)])
+    ],[AC_MSG_RESULT(no - LibreSSL/OpenSSL support disabled)
+    cf_enable_openssl="no"])])
+
+AM_CONDITIONAL(ENABLE_SSL, [test "$ac_cv_lib_ssl_SSL_connect" = yes])
+])
index 82c173a285de8f55c4db00434a6c15c1891a48b6..40bf5a162f29b3e73e846e1214dd8f5e66c7f388 100644 (file)
@@ -174,6 +174,16 @@ HTTPPOST                {
                           return PROTOCOLTYPE;
                         }
 
+HTTPS                   {
+                          yylval.number = OPM_TYPE_HTTPS;
+                          return PROTOCOLTYPE;
+                        }
+
+HTTPSPOST               {
+                          yylval.number = OPM_TYPE_HTTPSPOST;
+                          return PROTOCOLTYPE;
+                        }
+
 SOCKS4                  {
                           yylval.number = OPM_TYPE_SOCKS4;
                           return PROTOCOLTYPE;
index d78458e2d88ab6f3c41a04ed45df5b8b8072b276..6c84d0ad2650ddd22204a97394a1548d1547b5bc 100644 (file)
@@ -39,6 +39,9 @@
 #include <unistd.h>
 #include <string.h>
 #include <poll.h>
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/ssl.h>
+#endif
 
 
 static OPM_PROTOCOL_CONFIG_T *libopm_protocol_config_create(void);
@@ -66,6 +69,7 @@ static void libopm_check_queue(OPM_T *);
 
 static void libopm_do_connect(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 static void libopm_do_readready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
+static int libopm_do_readready_tls(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 static void libopm_do_writeready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 static void libopm_do_hup(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 static void libopm_do_read(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
@@ -84,13 +88,15 @@ static OPM_REMOTE_T *libopm_setup_remote(OPM_REMOTE_T *, OPM_CONNECTION_T *);
  */
 static OPM_PROTOCOL_T OPM_PROTOCOLS[] =
 {
-  { OPM_TYPE_HTTP,     libopm_proxy_http_write,     NULL },
-  { OPM_TYPE_SOCKS4,   libopm_proxy_socks4_write,   NULL },
-  { OPM_TYPE_SOCKS5,   libopm_proxy_socks5_write,   NULL },
-  { OPM_TYPE_ROUTER,   libopm_proxy_router_write,   NULL },
-  { OPM_TYPE_WINGATE,  libopm_proxy_wingate_write,  NULL },
-  { OPM_TYPE_HTTPPOST, libopm_proxy_httppost_write, NULL },
-  { OPM_TYPE_DREAMBOX, libopm_proxy_dreambox_write, NULL }
+  { OPM_TYPE_HTTP,      libopm_proxy_http_write,      NULL, 0 },
+  { OPM_TYPE_SOCKS4,    libopm_proxy_socks4_write,    NULL, 0 },
+  { OPM_TYPE_SOCKS5,    libopm_proxy_socks5_write,    NULL, 0 },
+  { OPM_TYPE_ROUTER,    libopm_proxy_router_write,    NULL, 0 },
+  { OPM_TYPE_WINGATE,   libopm_proxy_wingate_write,   NULL, 0 },
+  { OPM_TYPE_HTTPPOST,  libopm_proxy_httppost_write,  NULL, 0 },
+  { OPM_TYPE_DREAMBOX,  libopm_proxy_dreambox_write,  NULL, 0 },
+  { OPM_TYPE_HTTPS,     libopm_proxy_https_write,     libopm_do_readready_tls, 1 },
+  { OPM_TYPE_HTTPSPOST, libopm_proxy_httpspost_write, libopm_do_readready_tls, 1 }
 };
 
 /* opm_create
@@ -294,6 +300,10 @@ opm_addtype(OPM_T *scanner, int type, unsigned short int port)
   {
     if (type == OPM_PROTOCOLS[i].type)
     {
+#ifndef HAVE_LIBCRYPTO
+      if (OPM_PROTOCOLS[i].use_tls)
+        return OPM_ERR_BADPROTOCOL;
+#endif
       protocol_config = libopm_protocol_config_create();
       protocol_config->type = &OPM_PROTOCOLS[i];
       protocol_config->port = port;
@@ -330,6 +340,10 @@ OPM_ERR_T opm_remote_addtype(OPM_REMOTE_T *remote, int type, unsigned short int
   {
     if (type == OPM_PROTOCOLS[i].type)
     {
+#ifndef HAVE_LIBCRYPTO
+      if (OPM_PROTOCOLS[i].use_tls)
+        return OPM_ERR_BADPROTOCOL;
+#endif
       protocol_config = libopm_protocol_config_create();
       protocol_config->type = &OPM_PROTOCOLS[i];
       protocol_config->port = port;
@@ -595,6 +609,20 @@ libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
   OPM_SCAN_T *ret;
   OPM_CONNECTION_T *conn;
   OPM_NODE_T *node, *p;
+#ifdef HAVE_LIBCRYPTO
+  static int tls_init = 0;
+  static SSL_CTX *ctx_client;
+
+  if (!tls_init)
+  {
+    tls_init = 1;
+    SSLeay_add_ssl_algorithms();
+
+    ctx_client = SSL_CTX_new(SSLv23_client_method());
+    if (!ctx_client)
+      exit(EXIT_FAILURE);
+  }
+#endif
 
   ret = xcalloc(sizeof(*ret));
   ret->remote = remote;
@@ -608,6 +636,12 @@ libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
     conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
     conn->port     = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
 
+#ifdef HAVE_LIBCRYPTO
+    if (conn->protocol->use_tls)
+      /* SSL_new does only fail if OOM in which case HOPM exits anyway */
+      conn->tls_handle = SSL_new(ctx_client);
+#endif
+
     node = libopm_node_create(conn);
     libopm_list_add(ret->connections, node);
   }
@@ -622,6 +656,12 @@ libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
     conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
     conn->port     = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
 
+#ifdef HAVE_LIBCRYPTO
+    if (conn->protocol->use_tls)
+      /* SSL_new does only fail if OOM in which case HOPM exits anyway */
+      conn->tls_handle = SSL_new(ctx_client);
+#endif
+
     node = libopm_node_create(conn);
     libopm_list_add(ret->connections, node);
   }
@@ -846,6 +886,15 @@ libopm_check_closed(OPM_T *scanner)
 
       if (conn->state == OPM_STATE_CLOSED)
       {
+#ifdef HAVE_LIBCRYPTO
+        if (conn->protocol->use_tls)
+        {
+          SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
+          if (!SSL_shutdown(conn->tls_handle))
+            SSL_shutdown(conn->tls_handle);
+          SSL_free(conn->tls_handle);
+        }
+#endif
         if (conn->fd > 0)
           close(conn->fd);
 
@@ -859,6 +908,15 @@ libopm_check_closed(OPM_T *scanner)
 
       if (((present - conn->creation) >= timeout) && conn->state != OPM_STATE_UNESTABLISHED)
       {
+#ifdef HAVE_LIBCRYPTO
+        if (conn->protocol->use_tls)
+        {
+          SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
+          if (!SSL_shutdown(conn->tls_handle))
+            SSL_shutdown(conn->tls_handle);
+          SSL_free(conn->tls_handle);
+        }
+#endif
         close(conn->fd);
         scanner->fd_use--;
 
@@ -938,6 +996,11 @@ libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
 
   connect(conn->fd, (struct sockaddr *)addr, sizeof(*addr));
 
+#ifdef HAVE_LIBCRYPTO
+  if (conn->protocol->use_tls)
+    SSL_set_fd(conn->tls_handle, conn->fd);
+#endif
+
   conn->state = OPM_STATE_ESTABLISHED;
   time(&conn->creation);  /* Stamp creation time, for timeout */
 }
@@ -1047,6 +1110,63 @@ libopm_check_poll(OPM_T *scanner)
   }
 }
 
+static int
+libopm_do_readready_tls(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
+{
+#ifdef HAVE_LIBCRYPTO
+  int max_read, length;
+  char readbuf[LIBOPM_TLS_RECORD_SIZE];
+
+  if (!SSL_is_init_finished(conn->tls_handle))
+    return 0;
+
+  if ((length = SSL_read(conn->tls_handle, readbuf, sizeof(readbuf))) <= 0)
+  {
+    switch (SSL_get_error(conn->tls_handle, length))
+    {
+      /* TBD: possibly could recover here from some errors */ 
+      default:
+        libopm_do_hup(scanner, scan, conn);
+        return 0;
+    }
+  }
+
+  max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
+
+  for (const char *p = readbuf, *end = readbuf + length; p < end; ++p)
+  {
+    conn->bytes_read++;
+
+    if (conn->bytes_read >= max_read)
+    {
+      libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
+      conn->state = OPM_STATE_CLOSED;
+      return 0;
+    }
+
+    if (*p == '\0' || *p == '\r')
+      continue;
+
+    if (*p == '\n')
+    {
+      conn->readbuf[conn->readlen] = '\0';
+      conn->readlen = 0;
+
+      libopm_do_read(scanner, scan, conn);
+
+      if (conn->state == OPM_STATE_CLOSED)
+        return 0;
+
+      continue;
+    }
+
+    if (conn->readlen < READBUFLEN)
+      conn->readbuf[++(conn->readlen) - 1] = *p;  /* -1 to pad for null term */
+  }
+#endif
+  return 0;
+}
+
 /* do_readready
  *
  *    Remote connection is read ready, read the data into a buffer and check it against
@@ -1200,6 +1320,17 @@ libopm_do_writeready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
 {
   OPM_PROTOCOL_T *protocol;
 
+#ifdef HAVE_LIBCRYPTO
+  if (conn->protocol->use_tls)
+  {
+    if (!SSL_is_init_finished(conn->tls_handle))
+    {
+      SSL_connect(conn->tls_handle);
+      return;
+    }
+  }
+#endif
+
   protocol = conn->protocol;
 
   /* Call write function for specific protocol */
index cffd5459587e1603518750ef12b9933feda3a076..72b19aecacbee92efa314784290ed36c4d4e5289 100644 (file)
@@ -9,6 +9,7 @@
 #define CBLEN 5         /* Number of callback functions  */
 #define READBUFLEN 128  /* Size of conn->readbuf         */
 #define SENDBUFLEN 512  /* Size of sendbuffer in proxy.c */
+#define LIBOPM_TLS_RECORD_SIZE 16384
 
 typedef struct  _OPM_SCAN             OPM_SCAN_T;
 typedef struct  _OPM_CONNECTION       OPM_CONNECTION_T;
@@ -39,6 +40,7 @@ struct _OPM_CONNECTION
   unsigned short int readlen;          /* Length of readbuf */
   unsigned short int state;            /* State of connection */
   time_t             creation;         /* When this connection was established */
+  void *tls_handle;                    /* SSL structure created by SSL_new() */
 };
 
 struct _OPM_PROTOCOL_CONFIG
@@ -52,5 +54,6 @@ struct _OPM_PROTOCOL
   int type;                            /* Protocol type */
   OPM_PROXYWRITE_T *write_function;    /* Write function handler for this protocol */
   OPM_PROXYREAD_T  *read_function;     /* Read function handler for this protocol */
+  int use_tls;                         /* TLS/SSL-enabled protocol such as HTTPS */
 };
 #endif /* LIBOPM_H */
index d01ccaaa785d0d540d1b727bb140f1a191583a83..5fb50f8031f9a84d00ec49c9ffb9b0e8438c590f 100644 (file)
@@ -25,6 +25,9 @@
 #define OPM_TYPE_ROUTER          5
 #define OPM_TYPE_HTTPPOST        6
 #define OPM_TYPE_DREAMBOX        7
+#define OPM_TYPE_HTTPS           8
+#define OPM_TYPE_HTTPSPOST       9
+
 
 /* States */
 #define OPM_STATE_UNESTABLISHED  1
index e69a62229b8f1b33c9826337a578dc1dc3eee5b1..1f2e70f1e40b34264f75f81e50c6347390115a64 100644 (file)
@@ -25,6 +25,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/ssl.h>
+#endif
 
 #include "inet.h"
 #include "config.h"
@@ -270,3 +273,45 @@ libopm_proxy_dreambox_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *
 
   return OPM_SUCCESS;
 }
+
+int
+libopm_proxy_https_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
+{
+#ifdef HAVE_LIBCRYPTO
+  size_t len = snprintf(SENDBUF, SENDBUFLEN, "CONNECT %s:%d HTTP/1.0\r\n\r\n",
+                        (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP),
+                        *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT));
+
+  SSL_write(conn->tls_handle, SENDBUF, len);
+
+  /* extra linefeed required for MikroTik HttpProxy, must be separate send() */
+  SSL_write(conn->tls_handle, "\r\n", 2);
+#endif
+  return OPM_SUCCESS;
+}
+
+/*
+ * HTTPS POST Scanning
+ *
+ */
+int
+libopm_proxy_httpspost_write(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
+{
+#ifdef HAVE_LIBCRYPTO
+  size_t len;
+  int scan_port;
+  char *scan_ip;
+
+  scan_ip = (char *)libopm_config(scanner->config, OPM_CONFIG_SCAN_IP);
+  scan_port = *(int *)libopm_config(scanner->config, OPM_CONFIG_SCAN_PORT);
+
+  len = snprintf(SENDBUF, SENDBUFLEN,
+                 "POST http://%s:%d/ HTTP/1.0\r\n"
+                 "Content-type: text/plain\r\n"
+                 "Content-length: 5\r\n\r\n"
+                 "quit\r\n\r\n", scan_ip, scan_port);
+
+  SSL_write(conn->tls_handle, SENDBUF, len);
+#endif
+  return OPM_SUCCESS;
+}
index 248518474f2eaf3a282b253e1168ee82ec38c4a0..c00620323adbfac03301e0204adc9bbbd4514ea4 100644 (file)
@@ -10,4 +10,6 @@ extern int libopm_proxy_wingate_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *)
 extern int libopm_proxy_router_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 extern int libopm_proxy_httppost_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 extern int libopm_proxy_dreambox_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
+extern int libopm_proxy_https_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
+extern int libopm_proxy_httpspost_write(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
 #endif /* PROXY_H */
index 76a0347a4aaf5f98e52751732a6e1cd8618e39dd..845793fd403ca03f6e53de001784592f37e24121 100644 (file)
@@ -145,13 +145,15 @@ scan_gettype(int protocol)
   static const char *undef = "undefined";
   static const struct protocol_assoc protocols[] =
   {
-    { OPM_TYPE_HTTP,     "HTTP"     },
-    { OPM_TYPE_HTTPPOST, "HTTPPOST" },
-    { OPM_TYPE_SOCKS4,   "SOCKS4"   },
-    { OPM_TYPE_SOCKS5,   "SOCKS5"   },
-    { OPM_TYPE_WINGATE,  "WINGATE"  },
-    { OPM_TYPE_ROUTER,   "ROUTER"   },
-    { OPM_TYPE_DREAMBOX, "DREAMBOX" }
+    { OPM_TYPE_HTTP,      "HTTP"      },
+    { OPM_TYPE_HTTPPOST,  "HTTPPOST"  },
+    { OPM_TYPE_SOCKS4,    "SOCKS4"    },
+    { OPM_TYPE_SOCKS5,    "SOCKS5"    },
+    { OPM_TYPE_WINGATE,   "WINGATE"   },
+    { OPM_TYPE_ROUTER,    "ROUTER"    },
+    { OPM_TYPE_HTTPS,     "HTTPS"     },
+    { OPM_TYPE_HTTPSPOST, "HTTPSPOST" },
+    { OPM_TYPE_DREAMBOX,  "DREAMBOX"  }
   };
 
   for (unsigned int i = 0; i < (sizeof(protocols) / sizeof(struct protocol_assoc)); ++i)
index 00d4c1625c998c8a1370bbad1e0e55506aa3bdb5..c5ca132939f7fae173a578e6a759f6d7ca7bf7af 100644 (file)
@@ -43,13 +43,17 @@ static unsigned int STATS_DNSBLSENT;
 
 static struct StatsHash STATS_PROXIES[] =
 {
-  { OPM_TYPE_HTTP,     0, "HTTP"     },
-  { OPM_TYPE_HTTPPOST, 0, "HTTPPOST" },
-  { OPM_TYPE_SOCKS4,   0, "SOCKS4"   },
-  { OPM_TYPE_SOCKS5,   0, "SOCKS5"   },
-  { OPM_TYPE_ROUTER,   0, "ROUTER"   },
-  { OPM_TYPE_WINGATE,  0, "WINGATE"  },
-  { OPM_TYPE_DREAMBOX, 0, "DREAMBOX" },
+  { OPM_TYPE_HTTP,      0, "HTTP"      },
+  { OPM_TYPE_HTTPPOST,  0, "HTTPPOST"  },
+#ifdef HAVE_LIBCRYPTO
+  { OPM_TYPE_HTTPS,     0, "HTTPS"     },
+  { OPM_TYPE_HTTPSPOST, 0, "HTTPSPOST" },
+#endif
+  { OPM_TYPE_SOCKS4,    0, "SOCKS4"    },
+  { OPM_TYPE_SOCKS5,    0, "SOCKS5"    },
+  { OPM_TYPE_ROUTER,    0, "ROUTER"    },
+  { OPM_TYPE_WINGATE,   0, "WINGATE"   },
+  { OPM_TYPE_DREAMBOX,  0, "DREAMBOX"  },
   { 0, 0, NULL }
 };