From 91ec580beceb3d6c723d2ade85436374992526f7 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Tue, 3 Jun 2014 23:23:30 +0200 Subject: Import new openvpn -master version --- main/openvpn/src/openvpn/crypto_openssl.c | 38 +--- main/openvpn/src/openvpn/forward.c | 1 + main/openvpn/src/openvpn/init.c | 7 +- main/openvpn/src/openvpn/multi.c | 1 + main/openvpn/src/openvpn/options.c | 18 +- main/openvpn/src/openvpn/options.h | 2 + main/openvpn/src/openvpn/pf.c | 2 +- main/openvpn/src/openvpn/proto.c | 2 +- main/openvpn/src/openvpn/push.c | 1 + main/openvpn/src/openvpn/route.c | 248 +++---------------------- main/openvpn/src/openvpn/socket.c | 8 +- main/openvpn/src/openvpn/ssl.c | 25 ++- main/openvpn/src/openvpn/ssl.h | 1 - main/openvpn/src/openvpn/ssl_backend.h | 2 +- main/openvpn/src/openvpn/ssl_openssl.c | 17 +- main/openvpn/src/openvpn/ssl_polarssl.c | 19 +- main/openvpn/src/openvpn/ssl_verify.c | 5 + main/openvpn/src/openvpn/ssl_verify.h | 25 +-- main/openvpn/src/openvpn/ssl_verify_backend.h | 19 +- main/openvpn/src/openvpn/ssl_verify_openssl.c | 16 +- main/openvpn/src/openvpn/ssl_verify_polarssl.c | 42 ++++- main/openvpn/src/openvpn/ssl_verify_polarssl.h | 2 - main/openvpn/src/plugins/auth-pam/Makefile.am | 5 +- main/openvpn/src/plugins/down-root/Makefile.am | 3 +- 24 files changed, 192 insertions(+), 317 deletions(-) (limited to 'main/openvpn/src') diff --git a/main/openvpn/src/openvpn/crypto_openssl.c b/main/openvpn/src/openvpn/crypto_openssl.c index 6199e618..c3480e02 100644 --- a/main/openvpn/src/openvpn/crypto_openssl.c +++ b/main/openvpn/src/openvpn/crypto_openssl.c @@ -57,32 +57,6 @@ #warning Some OpenSSL HMAC message digests now support key lengths greater than MAX_HMAC_KEY_LENGTH -- consider increasing MAX_HMAC_KEY_LENGTH #endif -static inline int -EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) -{ - return EVP_CipherInit (ctx, type, key, iv, enc); -} - -static inline int -EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) -{ - return EVP_CipherUpdate (ctx, out, outl, in, inl); -} - -static inline bool -cipher_ok (const char* name) -{ - return true; -} - -#ifndef EVP_CIPHER_name -#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) -#endif - -#ifndef EVP_MD_name -#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e)) -#endif - #if HAVE_OPENSSL_ENGINE #include @@ -285,7 +259,7 @@ show_available_ciphers () for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ { const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); - if (cipher && cipher_ok (OBJ_nid2sn (nid))) + if (cipher) { const unsigned int mode = EVP_CIPHER_mode (cipher); if (mode == EVP_CIPH_CBC_MODE @@ -464,7 +438,7 @@ cipher_kt_get (const char *ciphername) cipher = EVP_get_cipherbyname (ciphername); - if ((NULL == cipher) || !cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher)))) + if (NULL == cipher) msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH) @@ -525,13 +499,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, CLEAR (*ctx); EVP_CIPHER_CTX_init (ctx); - if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc)) + if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc)) msg (M_SSLERR, "EVP cipher init #1"); #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) msg (M_SSLERR, "EVP set key size"); #endif - if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc)) + if (!EVP_CipherInit (ctx, NULL, key, NULL, enc)) msg (M_SSLERR, "EVP cipher init #2"); /* make sure we used a big enough key */ @@ -565,14 +539,14 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx) int cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) { - return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1); + return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1); } int cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { - return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len); + return EVP_CipherUpdate (ctx, dst, dst_len, src, src_len); } int diff --git a/main/openvpn/src/openvpn/forward.c b/main/openvpn/src/openvpn/forward.c index f78f5f0a..a43361b4 100644 --- a/main/openvpn/src/openvpn/forward.c +++ b/main/openvpn/src/openvpn/forward.c @@ -39,6 +39,7 @@ #include "ps.h" #include "dhcp.h" #include "common.h" +#include "ssl_verify.h" #include "memdbg.h" diff --git a/main/openvpn/src/openvpn/init.c b/main/openvpn/src/openvpn/init.c index 425c077b..ede955a1 100644 --- a/main/openvpn/src/openvpn/init.c +++ b/main/openvpn/src/openvpn/init.c @@ -43,6 +43,7 @@ #include "lladdr.h" #include "ping.h" #include "mstats.h" +#include "ssl_verify.h" #include "memdbg.h" @@ -1823,14 +1824,8 @@ do_hold (struct context *c) static void socket_restart_pause (struct context *c) { - bool proxy = false; int sec = 2; - if (c->options.ce.http_proxy_options) - proxy = true; - if (c->options.ce.socks_proxy_server) - proxy = true; - switch (c->options.ce.proto) { case PROTO_TCP_SERVER: diff --git a/main/openvpn/src/openvpn/multi.c b/main/openvpn/src/openvpn/multi.c index b0119181..16250dc2 100644 --- a/main/openvpn/src/openvpn/multi.c +++ b/main/openvpn/src/openvpn/multi.c @@ -38,6 +38,7 @@ #include "otime.h" #include "gremlin.h" #include "mstats.h" +#include "ssl_verify.h" #include "memdbg.h" diff --git a/main/openvpn/src/openvpn/options.c b/main/openvpn/src/openvpn/options.c index f0e94770..fc764616 100644 --- a/main/openvpn/src/openvpn/options.c +++ b/main/openvpn/src/openvpn/options.c @@ -56,6 +56,7 @@ #include "helper.h" #include "manage.h" #include "forward.h" +#include "ssl_verify.h" #include #include "memdbg.h" @@ -3403,18 +3404,21 @@ usage_small (void) void show_library_versions(const unsigned int flags) { - msg (flags, "library versions: %s%s%s", #ifdef ENABLE_SSL - get_ssl_library_version(), +#define SSL_LIB_VER_STR get_ssl_library_version() #else - "", +#define SSL_LIB_VER_STR "" #endif #ifdef ENABLE_LZO - ", LZO ", lzo_version_string() +#define LZO_LIB_VER_STR ", LZO ", lzo_version_string() #else - "", "" +#define LZO_LIB_VER_STR "", "" #endif - ); + + msg (flags, "library versions: %s%s%s", SSL_LIB_VER_STR, LZO_LIB_VER_STR); + +#undef SSL_LIB_VER_STR +#undef LZO_LIB_VER_STR } static void @@ -4108,7 +4112,7 @@ add_option (struct options *options, read_config_file (options, p[1], level, file, line, msglevel, permission_mask, option_types_found, es); } -#ifdef ENABLE_DEBUG +#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL) else if (streq (p[0], "show-gateway")) { struct route_gateway_info rgi; diff --git a/main/openvpn/src/openvpn/options.h b/main/openvpn/src/openvpn/options.h index 06874ccd..21c210ee 100644 --- a/main/openvpn/src/openvpn/options.h +++ b/main/openvpn/src/openvpn/options.h @@ -680,6 +680,8 @@ void notnull (const char *arg, const char *description); void usage_small (void); +void show_library_versions(const unsigned int flags); + void init_options (struct options *o, const bool init_gc); void uninit_options (struct options *o); diff --git a/main/openvpn/src/openvpn/pf.c b/main/openvpn/src/openvpn/pf.c index 461beed7..a3208db1 100644 --- a/main/openvpn/src/openvpn/pf.c +++ b/main/openvpn/src/openvpn/pf.c @@ -35,8 +35,8 @@ #if defined(ENABLE_PF) #include "init.h" - #include "memdbg.h" +#include "ssl_verify.h" #include "pf-inline.h" diff --git a/main/openvpn/src/openvpn/proto.c b/main/openvpn/src/openvpn/proto.c index b437f1ad..7b58e6ab 100644 --- a/main/openvpn/src/openvpn/proto.c +++ b/main/openvpn/src/openvpn/proto.c @@ -60,7 +60,7 @@ is_ipv_X ( int tunnel_type, struct buffer *buf, int ip_ver ) + sizeof (struct openvpn_iphdr))) return false; eh = (const struct openvpn_ethhdr *) BPTR (buf); - if (ntohs (eh->proto) != OPENVPN_ETH_P_IPV4) + if (ntohs (eh->proto) != (ip_ver == 6 ? OPENVPN_ETH_P_IPV6 : OPENVPN_ETH_P_IPV4)) return false; offset = sizeof (struct openvpn_ethhdr); } diff --git a/main/openvpn/src/openvpn/push.c b/main/openvpn/src/openvpn/push.c index 92e3abbb..24d12c7b 100644 --- a/main/openvpn/src/openvpn/push.c +++ b/main/openvpn/src/openvpn/push.c @@ -33,6 +33,7 @@ #include "push.h" #include "options.h" #include "ssl.h" +#include "ssl_verify.h" #include "manage.h" #include "memdbg.h" diff --git a/main/openvpn/src/openvpn/route.c b/main/openvpn/src/openvpn/route.c index 7ea791b8..bcc6fcee 100644 --- a/main/openvpn/src/openvpn/route.c +++ b/main/openvpn/src/openvpn/route.c @@ -628,7 +628,7 @@ init_route_list (struct route_list *rl, if (rl->rgi.flags & RGI_ADDR_DEFINED) { setenv_route_addr (es, "net_gateway", rl->rgi.gateway.addr, -1); -#ifdef ENABLE_DEBUG +#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL) print_default_gateway (D_ROUTE, &rl->rgi); #endif } @@ -2636,118 +2636,9 @@ get_default_gateway (struct route_gateway_info *rgi) gc_free (&gc); } -#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY) - -#include -#include -#include -#include - -struct { - struct rt_msghdr m_rtm; - char m_space[512]; -} m_rtmsg; - -#define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - -/* - * FIXME -- add support for netmask, hwaddr, and iface - */ -void -get_default_gateway (struct route_gateway_info *rgi) -{ - struct gc_arena gc = gc_new (); - int s, seq, l, pid, rtm_addrs, i; - struct sockaddr so_dst, so_mask; - char *cp = m_rtmsg.m_space; - struct sockaddr *gate = NULL, *sa; - struct rt_msghdr *rtm_aux; - -#define NEXTADDR(w, u) \ - if (rtm_addrs & (w)) {\ - l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ - } - -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) - -#define rtm m_rtmsg.m_rtm - - CLEAR(*rgi); - - pid = getpid(); - seq = 0; - rtm_addrs = RTA_DST | RTA_NETMASK; - - bzero(&so_dst, sizeof(so_dst)); - bzero(&so_mask, sizeof(so_mask)); - bzero(&rtm, sizeof(struct rt_msghdr)); - - rtm.rtm_type = RTM_GET; - rtm.rtm_flags = RTF_UP | RTF_GATEWAY; - rtm.rtm_version = RTM_VERSION; - rtm.rtm_seq = ++seq; - rtm.rtm_addrs = rtm_addrs; - - so_dst.sa_family = AF_INET; - so_dst.sa_len = sizeof(struct sockaddr_in); - so_mask.sa_family = AF_INET; - so_mask.sa_len = sizeof(struct sockaddr_in); - - NEXTADDR(RTA_DST, so_dst); - NEXTADDR(RTA_NETMASK, so_mask); - - rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - - s = socket(PF_ROUTE, SOCK_RAW, 0); - - if (write(s, (char *)&m_rtmsg, l) < 0) - { - msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:"); - gc_free (&gc); - close(s); - return; - } - - do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); - } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - - close(s); - - rtm_aux = &rtm; - - cp = ((char *)(rtm_aux + 1)); - if (rtm_aux->rtm_addrs) { - for (i = 1; i; i <<= 1) - if (i & rtm_aux->rtm_addrs) { - sa = (struct sockaddr *)cp; - if (i == RTA_GATEWAY ) - gate = sa; - ADVANCE(cp, sa); - } - } - else - { - gc_free (&gc); - return; - } - - - if (gate != NULL ) - { - rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); - rgi->flags |= RGI_ADDR_DEFINED; - - gc_free (&gc); - } - else - { - gc_free (&gc); - } -} - -#elif defined(TARGET_DARWIN) +#elif defined(TARGET_DARWIN) || \ + defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) || \ + defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) #include #include @@ -2760,8 +2651,25 @@ struct rtmsg { char m_space[512]; }; -#define ROUNDUP(a) \ +/* the route socket code is identical for all 4 supported BSDs and for + * MacOS X (Darwin), with one crucial difference: when going from + * 32 bit to 64 bit, the BSDs increased the structure size but kept + * source code compatibility by keeping the use of "long", while + * MacOS X decided to keep binary compatibility by *changing* the API + * to use "uint32_t", thus 32 bit on all OS X variants + * + * We used to have a large amount of duplicate code here which really + * differed only in this (long) vs. (uint32_t) - IMHO, worse than + * having a combined block for all BSDs with this single #ifdef inside + */ + +#if defined(TARGET_DARWIN) +# define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t)) +#else +# define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#endif #define NEXTADDR(w, u) \ if (rtm_addrs & (w)) {\ @@ -2955,118 +2863,6 @@ get_default_gateway (struct route_gateway_info *rgi) #undef max -#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) - -#include -#include -#include -#include - -struct { - struct rt_msghdr m_rtm; - char m_space[512]; -} m_rtmsg; - -#define ROUNDUP(a) \ - ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) - -/* - * FIXME -- add support for netmask, hwaddr, and iface - */ -void -get_default_gateway (struct route_gateway_info *rgi) -{ - struct gc_arena gc = gc_new (); - int s, seq, l, rtm_addrs, i; - pid_t pid; - struct sockaddr so_dst, so_mask; - char *cp = m_rtmsg.m_space; - struct sockaddr *gate = NULL, *sa; - struct rt_msghdr *rtm_aux; - -#define NEXTADDR(w, u) \ - if (rtm_addrs & (w)) {\ - l = ROUNDUP(u.sa_len); memmove(cp, &(u), l); cp += l;\ - } - -#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) - -#define rtm m_rtmsg.m_rtm - - CLEAR(*rgi); - - pid = getpid(); - seq = 0; - rtm_addrs = RTA_DST | RTA_NETMASK; - - bzero(&so_dst, sizeof(so_dst)); - bzero(&so_mask, sizeof(so_mask)); - bzero(&rtm, sizeof(struct rt_msghdr)); - - rtm.rtm_type = RTM_GET; - rtm.rtm_flags = RTF_UP | RTF_GATEWAY; - rtm.rtm_version = RTM_VERSION; - rtm.rtm_seq = ++seq; - rtm.rtm_addrs = rtm_addrs; - - so_dst.sa_family = AF_INET; - so_dst.sa_len = sizeof(struct sockaddr_in); - so_mask.sa_family = AF_INET; - so_mask.sa_len = sizeof(struct sockaddr_in); - - NEXTADDR(RTA_DST, so_dst); - NEXTADDR(RTA_NETMASK, so_mask); - - rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - - s = socket(PF_ROUTE, SOCK_RAW, 0); - - if (write(s, (char *)&m_rtmsg, l) < 0) - { - msg(M_WARN|M_ERRNO, "Could not retrieve default gateway from route socket:"); - gc_free (&gc); - close(s); - return; - } - - do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); - } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid)); - - close(s); - - rtm_aux = &rtm; - - cp = ((char *)(rtm_aux + 1)); - if (rtm_aux->rtm_addrs) { - for (i = 1; i; i <<= 1) - if (i & rtm_aux->rtm_addrs) { - sa = (struct sockaddr *)cp; - if (i == RTA_GATEWAY ) - gate = sa; - ADVANCE(cp, sa); - } - } - else - { - gc_free (&gc); - return; - } - - - if (gate != NULL ) - { - rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr); - rgi->flags |= RGI_ADDR_DEFINED; - - gc_free (&gc); - } - else - { - gc_free (&gc); - } -} - #else /* diff --git a/main/openvpn/src/openvpn/socket.c b/main/openvpn/src/openvpn/socket.c index 6f822e7d..9e6bd10c 100644 --- a/main/openvpn/src/openvpn/socket.c +++ b/main/openvpn/src/openvpn/socket.c @@ -2967,11 +2967,11 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, mesg.msg_name = &to->dest.addr.sa; mesg.msg_namelen = sizeof (struct sockaddr_in); mesg.msg_control = &opi; - mesg.msg_controllen = sizeof (struct openvpn_in4_pktinfo); mesg.msg_flags = 0; +#ifdef HAVE_IN_PKTINFO + mesg.msg_controllen = sizeof (struct openvpn_in4_pktinfo); cmsg = CMSG_FIRSTHDR (&mesg); cmsg->cmsg_len = sizeof (struct openvpn_in4_pktinfo); -#ifdef HAVE_IN_PKTINFO cmsg->cmsg_level = SOL_IP; cmsg->cmsg_type = IP_PKTINFO; { @@ -2982,6 +2982,10 @@ link_socket_write_udp_posix_sendmsg (struct link_socket *sock, pkti->ipi_addr.s_addr = 0; } #elif defined(IP_RECVDSTADDR) + ASSERT( CMSG_SPACE(sizeof (struct in_addr)) <= sizeof(opi) ); + mesg.msg_controllen = CMSG_SPACE(sizeof (struct in_addr)); + cmsg = CMSG_FIRSTHDR (&mesg); + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_RECVDSTADDR; *(struct in_addr *) CMSG_DATA (cmsg) = to->pi.in4; diff --git a/main/openvpn/src/openvpn/ssl.c b/main/openvpn/src/openvpn/ssl.c index 9bcb2acb..95bbb277 100644 --- a/main/openvpn/src/openvpn/ssl.c +++ b/main/openvpn/src/openvpn/ssl.c @@ -35,7 +35,6 @@ * Both the TLS session and the data channel are multiplexed * over the same TCP/UDP port. */ - #ifdef HAVE_CONFIG_H #include "config.h" #elif defined(_MSC_VER) @@ -48,7 +47,6 @@ #include "error.h" #include "common.h" -#include "integer.h" #include "socket.h" #include "misc.h" #include "fdmisc.h" @@ -57,8 +55,6 @@ #include "status.h" #include "gremlin.h" #include "pkcs11.h" -#include "list.h" -#include "base64.h" #include "route.h" #include "ssl.h" @@ -841,6 +837,25 @@ static inline void tls_session_set_self_referential_pointers (struct tls_session session->tls_auth.packet_id = &session->tls_auth_pid; } +/** + * Returns whether or not the server should check for username/password + * + * @param session The current TLS session + * + * @return true if username and password verification is enabled, + * false if not. + */ +static inline bool +tls_session_user_pass_enabled(struct tls_session *session) +{ + return (session->opt->auth_user_pass_verify_script + || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) +#ifdef MANAGEMENT_DEF_AUTH + || management_enable_def_auth (management) +#endif + ); +} + /** @addtogroup control_processor * @{ */ @@ -2073,7 +2088,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi output_peer_info_env (session->opt->es, multi->peer_info); #endif - if (verify_user_pass_enabled(session)) + if (tls_session_user_pass_enabled(session)) { /* Perform username/password authentication */ if (!username_status || !password_status) diff --git a/main/openvpn/src/openvpn/ssl.h b/main/openvpn/src/openvpn/ssl.h index cd7cae2e..aaecff43 100644 --- a/main/openvpn/src/openvpn/ssl.h +++ b/main/openvpn/src/openvpn/ssl.h @@ -44,7 +44,6 @@ #include "plugin.h" #include "ssl_common.h" -#include "ssl_verify.h" #include "ssl_backend.h" /* Used in the TLS PRF function */ diff --git a/main/openvpn/src/openvpn/ssl_backend.h b/main/openvpn/src/openvpn/ssl_backend.h index 37a458cc..bfd15496 100644 --- a/main/openvpn/src/openvpn/ssl_backend.h +++ b/main/openvpn/src/openvpn/ssl_backend.h @@ -485,6 +485,6 @@ void get_highest_preference_tls_cipher (char *buf, int size); * return a pointer to a static memory area containing the * name and version number of the SSL library in use */ -char * get_ssl_library_version(void); +const char * get_ssl_library_version(void); #endif /* SSL_BACKEND_H_ */ diff --git a/main/openvpn/src/openvpn/ssl_openssl.c b/main/openvpn/src/openvpn/ssl_openssl.c index 5ab34151..c9d2d26d 100644 --- a/main/openvpn/src/openvpn/ssl_openssl.c +++ b/main/openvpn/src/openvpn/ssl_openssl.c @@ -56,7 +56,9 @@ #include #include #include +#ifndef OPENSSL_NO_EC #include +#endif /* * Allocate space in SSL objects in which to store a struct tls_session @@ -196,6 +198,9 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags) SSL_CTX_set_options (ctx->ctx, sslopt); } +#ifdef SSL_MODE_RELEASE_BUFFERS + SSL_CTX_set_mode (ctx->ctx, SSL_MODE_RELEASE_BUFFERS); +#endif SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback); @@ -334,6 +339,7 @@ void tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name ) { +#ifndef OPENSSL_NO_EC int nid = NID_undef; EC_KEY *ecdh = NULL; const char *sname = NULL; @@ -395,6 +401,10 @@ tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname); EC_KEY_free(ecdh); +#else + msg (M_DEBUG, "Your OpenSSL library was built without elliptic curve support." + " Skipping ECDH parameter loading."); +#endif /* OPENSSL_NO_EC */ } int @@ -1374,6 +1384,7 @@ show_available_tls_ciphers (const char *cipher_list) void show_available_curves() { +#ifndef OPENSSL_NO_EC EC_builtin_curve *curves = NULL; size_t crv_len = 0; size_t n = 0; @@ -1404,6 +1415,10 @@ show_available_curves() } OPENSSL_free(curves); } +#else + msg (M_WARN, "Your OpenSSL library was built without elliptic curve support. " + "No curves available."); +#endif } void @@ -1427,7 +1442,7 @@ get_highest_preference_tls_cipher (char *buf, int size) SSL_CTX_free (ctx); } -char * +const char * get_ssl_library_version(void) { return SSLeay_version(SSLEAY_VERSION); diff --git a/main/openvpn/src/openvpn/ssl_polarssl.c b/main/openvpn/src/openvpn/ssl_polarssl.c index 79c5087b..ddccf1d9 100644 --- a/main/openvpn/src/openvpn/ssl_polarssl.c +++ b/main/openvpn/src/openvpn/ssl_polarssl.c @@ -232,7 +232,9 @@ void tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name ) { - msg(M_WARN, "Elliptic Curves not yet supported by PolarSSL"); + if (NULL != curve_name) + msg(M_WARN, "WARNING: PolarSSL builds do not support specifying an ECDH " + "curve, using default curves."); } int @@ -1093,7 +1095,18 @@ show_available_tls_ciphers (const char *cipher_list) void show_available_curves (void) { - printf("The PolarSSL build of OpenVPN does not support elliptic curves yet"); + const ecp_curve_info *pcurve = ecp_curve_list(); + + if (NULL == pcurve) + msg (M_FATAL, "Cannot retrieve curve list from PolarSSL"); + + /* Print curve list */ + printf ("Available Elliptic curves, listed in order of preference:\n\n"); + while (POLARSSL_ECP_DP_NONE != pcurve->grp_id) + { + printf("%s\n", pcurve->name); + pcurve++; + } } void @@ -1108,7 +1121,7 @@ get_highest_preference_tls_cipher (char *buf, int size) strncpynt (buf, cipher_name, size); } -char * +const char * get_ssl_library_version(void) { static char polar_version[30]; diff --git a/main/openvpn/src/openvpn/ssl_verify.c b/main/openvpn/src/openvpn/ssl_verify.c index 7a9a56ef..2d10d155 100644 --- a/main/openvpn/src/openvpn/ssl_verify.c +++ b/main/openvpn/src/openvpn/ssl_verify.c @@ -435,6 +435,11 @@ verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", cert_depth); setenv_str (es, envname, serial); + /* export serial number in hex as environmental variable */ + serial = backend_x509_get_serial_hex(peer_cert, &gc); + openvpn_snprintf (envname, sizeof(envname), "tls_serial_hex_%d", cert_depth); + setenv_str (es, envname, serial); + gc_free(&gc); } diff --git a/main/openvpn/src/openvpn/ssl_verify.h b/main/openvpn/src/openvpn/ssl_verify.h index e0bcba42..84554f89 100644 --- a/main/openvpn/src/openvpn/ssl_verify.h +++ b/main/openvpn/src/openvpn/ssl_verify.h @@ -30,9 +30,10 @@ #ifndef SSL_VERIFY_H_ #define SSL_VERIFY_H_ +#if defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) + #include "syshead.h" #include "misc.h" -#include "manage.h" #include "ssl_common.h" /* Include OpenSSL-specific code */ @@ -165,25 +166,6 @@ tls_common_name_hash (const struct tls_multi *multi, const char **cn, uint32_t * #endif -/** - * Returns whether or not the server should check for username/password - * - * @param session The current TLS session - * - * @return true if username and password verification is enabled, - * false if not. - * - */ -static inline bool verify_user_pass_enabled(struct tls_session *session) -{ - return (session->opt->auth_user_pass_verify_script - || plugin_defined (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY) -#ifdef MANAGEMENT_DEF_AUTH - || management_enable_def_auth (management) -#endif - ); -} - /** * Verify the given username and password, using either an external script, a * plugin, or the management interface. @@ -254,5 +236,6 @@ tls_client_reason (struct tls_multi *multi) #endif } -#endif /* SSL_VERIFY_H_ */ +#endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_SSL) */ +#endif /* SSL_VERIFY_H_ */ diff --git a/main/openvpn/src/openvpn/ssl_verify_backend.h b/main/openvpn/src/openvpn/ssl_verify_backend.h index fa4369d2..4e9ad60f 100644 --- a/main/openvpn/src/openvpn/ssl_verify_backend.h +++ b/main/openvpn/src/openvpn/ssl_verify_backend.h @@ -113,17 +113,32 @@ result_t backend_x509_get_username (char *common_name, int cn_len, char * x509_username_field, openvpn_x509_cert_t *peer_cert); /* - * Return the certificate's serial number. + * Return the certificate's serial number in decimal string representation. * * The serial number is returned as a string, since it might be a bignum. * * @param cert Certificate to retrieve the serial number from. * @param gc Garbage collection arena to use when allocating string. * - * @return The certificate's serial number. + * @return String representation of the certificate's serial number + * in decimal notation, or NULL on error. */ char *backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc); +/* + * Return the certificate's serial number in hex string representation. + * + * The serial number is returned as a string, since it might be a bignum. + * + * @param cert Certificate to retrieve the serial number from. + * @param gc Garbage collection arena to use when allocating string. + * + * @return String representation of the certificate's serial number + * in hex notation, or NULL on error. + */ +char *backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, + struct gc_arena *gc); + /* * Save X509 fields to environment, using the naming convention: * diff --git a/main/openvpn/src/openvpn/ssl_verify_openssl.c b/main/openvpn/src/openvpn/ssl_verify_openssl.c index a9205f31..2482eaa4 100644 --- a/main/openvpn/src/openvpn/ssl_verify_openssl.c +++ b/main/openvpn/src/openvpn/ssl_verify_openssl.c @@ -37,9 +37,13 @@ #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_OPENSSL) +#include "ssl_verify_openssl.h" + +#include "error.h" +#include "ssl_openssl.h" #include "ssl_verify.h" #include "ssl_verify_backend.h" -#include "ssl_openssl.h" + #include #include @@ -238,10 +242,18 @@ backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) return serial; } +char * +backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc) +{ + const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert); + + return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc); +} + unsigned char * x509_get_sha1_hash (X509 *cert, struct gc_arena *gc) { - char *hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc); + unsigned char *hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc); memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH); return hash; } diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.c b/main/openvpn/src/openvpn/ssl_verify_polarssl.c index 1b2990c7..71d38a9d 100644 --- a/main/openvpn/src/openvpn/ssl_verify_polarssl.c +++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.c @@ -38,6 +38,8 @@ #if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL) #include "ssl_verify.h" +#include +#include #include #include @@ -124,7 +126,45 @@ backend_x509_get_username (char *cn, int cn_len, } char * -backend_x509_get_serial (x509_crt *cert, struct gc_arena *gc) +backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) +{ + char *buf = NULL; + size_t buflen = 0; + mpi serial_mpi = { 0 }; + int retval = 0; + + /* Transform asn1 integer serial into PolarSSL MPI */ + mpi_init(&serial_mpi); + retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len); + if (retval < 0) + { + char errbuf[128]; + polarssl_strerror(retval, errbuf, sizeof(errbuf)); + + msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf); + return NULL; + } + + /* Determine decimal representation length, allocate buffer */ + mpi_write_string(&serial_mpi, 10, buf, &buflen); + buf = gc_malloc(buflen, true, gc); + + /* Write MPI serial as decimal string into buffer */ + retval = mpi_write_string(&serial_mpi, 10, buf, &buflen); + if (retval < 0) + { + char errbuf[128]; + polarssl_strerror(retval, errbuf, sizeof(errbuf)); + + msg(M_WARN, "Failed to write serial to string: %s.", errbuf); + return NULL; + } + + return buf; +} + +char * +backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc) { char *buf = NULL; size_t len = cert->serial.len * 3 + 1; diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.h b/main/openvpn/src/openvpn/ssl_verify_polarssl.h index b5157ed1..2076f2ef 100644 --- a/main/openvpn/src/openvpn/ssl_verify_polarssl.h +++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.h @@ -31,8 +31,6 @@ #define SSL_VERIFY_POLARSSL_H_ #include "syshead.h" -#include "misc.h" -#include "manage.h" #include #ifndef __OPENVPN_X509_CERT_T_DECLARED diff --git a/main/openvpn/src/plugins/auth-pam/Makefile.am b/main/openvpn/src/plugins/auth-pam/Makefile.am index 701a7497..2aef311a 100644 --- a/main/openvpn/src/plugins/auth-pam/Makefile.am +++ b/main/openvpn/src/plugins/auth-pam/Makefile.am @@ -8,8 +8,9 @@ MAINTAINERCLEANFILES = \ $(srcdir)/Makefile.in AM_CFLAGS = \ - -I$(top_srcdir)/include - $(PLUGIN_AUTH_PAM_CFLAGS) + -I$(top_srcdir)/include \ + $(PLUGIN_AUTH_PAM_CFLAGS) \ + $(OPTIONAL_CRYPTO_CFLAGS) if ENABLE_PLUGIN_AUTH_PAM plugin_LTLIBRARIES = openvpn-plugin-auth-pam.la diff --git a/main/openvpn/src/plugins/down-root/Makefile.am b/main/openvpn/src/plugins/down-root/Makefile.am index 064aa30c..7ca5a4e1 100644 --- a/main/openvpn/src/plugins/down-root/Makefile.am +++ b/main/openvpn/src/plugins/down-root/Makefile.am @@ -8,7 +8,8 @@ MAINTAINERCLEANFILES = \ $(srcdir)/Makefile.in AM_CFLAGS = \ - -I$(top_srcdir)/include + -I$(top_srcdir)/include \ + $(OPTIONAL_CRYPTO_CFLAGS) if ENABLE_PLUGIN_DOWN_ROOT plugin_LTLIBRARIES = openvpn-plugin-down-root.la -- cgit v1.2.3