diff options
| author | venaas <venaas> | 2008-12-22 13:14:41 +0000 | 
|---|---|---|
| committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2008-12-22 13:14:41 +0000 | 
| commit | e0c9e33cc484025e2b80bec19f7130554e9e3781 (patch) | |
| tree | 8e59eef2efd7c569707224edbc67ade716d8673f | |
| parent | a99d921cf322a09d779500c2cdeb55e3df260fb8 (diff) | |
moved more code to tlscommon, fixed a couple of minor lint warnings
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@447 e88ac4ed-0b26-0410-9574-a7f39faa03bf
| -rw-r--r-- | gconfig.h | 2 | ||||
| -rw-r--r-- | radsecproxy.c | 251 | ||||
| -rw-r--r-- | radsecproxy.h | 6 | ||||
| -rw-r--r-- | tcp.c | 7 | ||||
| -rw-r--r-- | tlscommon.c | 240 | ||||
| -rw-r--r-- | tlscommon.h | 22 | ||||
| -rw-r--r-- | udp.c | 34 | ||||
| -rw-r--r-- | util.c | 28 | ||||
| -rw-r--r-- | util.h | 3 | 
9 files changed, 299 insertions, 294 deletions
| @@ -4,6 +4,8 @@  #define CONF_BLN 4  #define CONF_LINT 5 +#include <stdio.h> +  struct gconffile {      char *path;      FILE *file; diff --git a/radsecproxy.c b/radsecproxy.c index 375d54d..7aaf9f3 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -70,13 +70,11 @@  #include "list.h"  #include "hash.h"  #include "util.h" -#include "gconfig.h"  #include "radsecproxy.h"  #include "udp.h"  #include "tcp.h"  #include "tls.h"  #include "dtls.h" -#include "tlscommon.h"  static struct options options;  static struct list *clconfs, *srvconfs; @@ -515,7 +513,6 @@ void freeserver(struct server *server, uint8_t destroymutex) {  }  int addserver(struct clsrvconf *conf) { -    uint8_t type;      int i;      if (conf->servers) { @@ -530,10 +527,8 @@ int addserver(struct clsrvconf *conf) {      memset(conf->servers, 0, sizeof(struct server));      conf->servers->conf = conf; -    type = conf->type; -     -#ifdef DRADPROT_TLS     -    if (type == RAD_DTLS) +#ifdef RADPROT_DTLS     +    if (conf->type == RAD_DTLS)  	conf->servers->rbios = newqueue();  #endif      conf->pdef->setsrcres(); @@ -585,194 +580,6 @@ int addserver(struct clsrvconf *conf) {      return 0;  } -int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) { -    int loc, i, l, n, r = 0; -    char *v; -    X509_EXTENSION *ex; -    STACK_OF(GENERAL_NAME) *alt; -    GENERAL_NAME *gn; -     -    debug(DBG_DBG, "subjectaltnameaddr"); -     -    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); -    if (loc < 0) -	return r; -     -    ex = X509_get_ext(cert, loc); -    alt = X509V3_EXT_d2i(ex); -    if (!alt) -	return r; -     -    n = sk_GENERAL_NAME_num(alt); -    for (i = 0; i < n; i++) { -	gn = sk_GENERAL_NAME_value(alt, i); -	if (gn->type != GEN_IPADD) -	    continue; -	r = -1; -	v = (char *)ASN1_STRING_data(gn->d.ia5); -	l = ASN1_STRING_length(gn->d.ia5); -	if (((family == AF_INET && l == sizeof(struct in_addr)) || (family == AF_INET6 && l == sizeof(struct in6_addr))) -	    && !memcmp(v, &addr, l)) { -	    r = 1; -	    break; -	} -    } -    GENERAL_NAMES_free(alt); -    return r; -} - -int cnregexp(X509 *cert, char *exact, regex_t *regex) { -    int loc, l; -    char *v, *s; -    X509_NAME *nm; -    X509_NAME_ENTRY *e; -    ASN1_STRING *t; - -    nm = X509_get_subject_name(cert); -    loc = -1; -    for (;;) { -	loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc); -	if (loc == -1) -	    break; -	e = X509_NAME_get_entry(nm, loc); -	t = X509_NAME_ENTRY_get_data(e); -	v = (char *) ASN1_STRING_data(t); -	l = ASN1_STRING_length(t); -	if (l < 0) -	    continue; -	if (exact) { -	    if (l == strlen(exact) && !strncasecmp(exact, v, l)) -		return 1; -	} else { -	    s = stringcopy((char *)v, l); -	    if (!s) { -		debug(DBG_ERR, "malloc failed"); -		continue; -	    } -	    if (regexec(regex, s, 0, NULL, 0)) { -		free(s); -		continue; -	    } -	    free(s); -	    return 1; -	} -    } -    return 0; -} - -int subjectaltnameregexp(X509 *cert, int type, char *exact,  regex_t *regex) { -    int loc, i, l, n, r = 0; -    char *s, *v; -    X509_EXTENSION *ex; -    STACK_OF(GENERAL_NAME) *alt; -    GENERAL_NAME *gn; -     -    debug(DBG_DBG, "subjectaltnameregexp"); -     -    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); -    if (loc < 0) -	return r; -     -    ex = X509_get_ext(cert, loc); -    alt = X509V3_EXT_d2i(ex); -    if (!alt) -	return r; -     -    n = sk_GENERAL_NAME_num(alt); -    for (i = 0; i < n; i++) { -	gn = sk_GENERAL_NAME_value(alt, i); -	if (gn->type != type) -	    continue; -	r = -1; -	v = (char *)ASN1_STRING_data(gn->d.ia5); -	l = ASN1_STRING_length(gn->d.ia5); -	if (l <= 0) -	    continue; -#ifdef DEBUG -	printfchars(NULL, gn->type == GEN_DNS ? "dns" : "uri", NULL, v, l); -#endif	 -	if (exact) { -	    if (memcmp(v, exact, l)) -		continue; -	} else { -	    s = stringcopy((char *)v, l); -	    if (!s) { -		debug(DBG_ERR, "malloc failed"); -		continue; -	    } -	    if (regexec(regex, s, 0, NULL, 0)) { -		free(s); -		continue; -	    } -	    free(s); -	} -	r = 1; -	break; -    } -    GENERAL_NAMES_free(alt); -    return r; -} - -X509 *verifytlscert(SSL *ssl) { -    X509 *cert; -    unsigned long error; -     -    if (SSL_get_verify_result(ssl) != X509_V_OK) { -	debug(DBG_ERR, "verifytlscert: basic validation failed"); -	while ((error = ERR_get_error())) -	    debug(DBG_ERR, "verifytlscert: TLS: %s", ERR_error_string(error, NULL)); -	return NULL; -    } - -    cert = SSL_get_peer_certificate(ssl); -    if (!cert) -	debug(DBG_ERR, "verifytlscert: failed to obtain certificate"); -    return cert; -} -     -int verifyconfcert(X509 *cert, struct clsrvconf *conf) { -    int r; -    uint8_t type = 0; /* 0 for DNS, AF_INET for IPv4, AF_INET6 for IPv6 */ -    struct in6_addr addr; -     -    if (conf->certnamecheck && conf->prefixlen == 255) { -	if (inet_pton(AF_INET, conf->host, &addr)) -	    type = AF_INET; -	else if (inet_pton(AF_INET6, conf->host, &addr)) -	    type = AF_INET6; - -	r = type ? subjectaltnameaddr(cert, type, &addr) : subjectaltnameregexp(cert, GEN_DNS, conf->host, NULL); -	if (r) { -	    if (r < 0) { -		debug(DBG_WARN, "verifyconfcert: No subjectaltname matching %s %s", type ? "address" : "host", conf->host); -		return 0; -	    } -	    debug(DBG_DBG, "verifyconfcert: Found subjectaltname matching %s %s", type ? "address" : "host", conf->host); -	} else { -	    if (!cnregexp(cert, conf->host, NULL)) { -		debug(DBG_WARN, "verifyconfcert: cn not matching host %s", conf->host); -		return 0; -	    }		 -	    debug(DBG_DBG, "verifyconfcert: Found cn matching host %s", conf->host); -	} -    } -    if (conf->certcnregex) { -	if (cnregexp(cert, NULL, conf->certcnregex) < 1) { -	    debug(DBG_WARN, "verifyconfcert: CN not matching regex"); -	    return 0; -	} -	debug(DBG_DBG, "verifyconfcert: CN matching regex"); -    } -    if (conf->certuriregex) { -	if (subjectaltnameregexp(cert, GEN_URI, NULL, conf->certuriregex) < 1) { -	    debug(DBG_WARN, "verifyconfcert: subjectaltname URI not matching regex"); -	    return 0; -	} -	debug(DBG_DBG, "verifyconfcert: subjectaltname URI matching regex"); -    } -    return 1; -} -  unsigned char *attrget(unsigned char *attrs, int length, uint8_t type) {      while (length > 1) {  	if (ATTRTYPE(attrs) == type) @@ -1286,7 +1093,7 @@ int msmppe(unsigned char *attrs, int length, uint8_t type, char *attrtxt, struct      return 1;  } -int findvendorsubattr(uint32_t *attrs, uint32_t vendor, uint8_t subattr) { +int findvendorsubattr(uint32_t *attrs, uint32_t vendor, uint32_t subattr) {      if (!attrs)  	return 0; @@ -1312,7 +1119,7 @@ int dovendorrewriterm(struct tlv *attr, uint32_t *removevendorattrs) {      if (!*removevendorattrs)  	return 0; -    if (findvendorsubattr(removevendorattrs, vendor, -1)) +    if (findvendorsubattr(removevendorattrs, vendor, 256))  	return 1; /* remove entire vendor attribute */      sublen = attr->l - 4; @@ -1504,7 +1311,7 @@ void addttlattr(struct radmsg *msg, uint32_t *attrtype, uint8_t addttl) {      memset(ttl, 0, 4);      ttl[3] = addttl; -    if (attrtype[1] == -1) { /* not vendor */ +    if (attrtype[1] == 256) { /* not vendor */  	attr = maketlv(attrtype[0], 4, ttl);  	if (attr && !radmsg_add(msg, attr))  	    freetlv(attr); @@ -1545,7 +1352,7 @@ int checkttl(struct radmsg *msg, uint32_t *attrtype) {      uint32_t vendor;      int sublen; -    if (attrtype[1] == -1) { /* not vendor */ +    if (attrtype[1] == 256) { /* not vendor */  	attr = radmsg_gettype(msg, attrtype[0]);  	if (attr)  	    return decttl(attr->l, attr->v); @@ -2623,40 +2430,6 @@ int dynamicconfig(struct server *server) {      return 0;  } -int addmatchcertattr(struct clsrvconf *conf) { -    char *v; -    regex_t **r; -     -    if (!strncasecmp(conf->matchcertattr, "CN:/", 4)) { -	r = &conf->certcnregex; -	v = conf->matchcertattr + 4; -    } else if (!strncasecmp(conf->matchcertattr, "SubjectAltName:URI:/", 20)) { -	r = &conf->certuriregex; -	v = conf->matchcertattr + 20; -    } else -	return 0; -    if (!*v) -	return 0; -    /* regexp, remove optional trailing / if present */ -    if (v[strlen(v) - 1] == '/') -	v[strlen(v) - 1] = '\0'; -    if (!*v) -	return 0; - -    *r = malloc(sizeof(regex_t)); -    if (!*r) { -	debug(DBG_ERR, "malloc failed"); -	return 0; -    } -    if (regcomp(*r, v, REG_EXTENDED | REG_ICASE | REG_NOSUB)) { -	free(*r); -	*r = NULL; -	debug(DBG_ERR, "failed to compile regular expression %s", v); -	return 0; -    } -    return 1; -} -  /* should accept both names and numeric values, only numeric right now */  uint8_t attrname2val(char *attrname) {      int val = 0; @@ -2672,11 +2445,11 @@ int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) {      *vendor = atoi(attrname);      s = strchr(attrname, ':');      if (!s) { -	*type = -1; +	*type = 256;  	return 1;      }      *type = atoi(s + 1); -    return *type >= 0 && *type < 256; +    return *type < 256;  }  /* should accept both names and numeric values, only numeric right now */ @@ -2856,7 +2629,7 @@ int setttlattr(struct options *opts, char *defaultattr) {      char *ttlattr = opts->ttlattr ? opts->ttlattr : defaultattr;      if (vattrname2val(ttlattr, opts->ttlattrtype, opts->ttlattrtype + 1) && -	(opts->ttlattrtype[1] != -1 || opts->ttlattrtype[0] < 256)) +	(opts->ttlattrtype[1] != 256 || opts->ttlattrtype[0] < 256))  	return 1;      debug(DBG_ERR, "setttlattr: invalid TTLAttribute value %s", ttlattr);      return 0; @@ -2953,9 +2726,11 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char  			  "type", CONF_STR, &conftype,  			  "host", CONF_STR, &conf->host,  			  "secret", CONF_STR, &conf->secret, +#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)      			  "tls", CONF_STR, &conf->tls,  			  "matchcertificateattribute", CONF_STR, &conf->matchcertattr,  			  "CertificateNameCheck", CONF_BLN, &conf->certnamecheck, +#endif			    			  "DuplicateInterval", CONF_LINT, &dupinterval,  			  "addTTL", CONF_LINT, &addttl,  			  "rewrite", CONF_STR, &rewriteinalias, @@ -3114,8 +2889,11 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char  			  "host", CONF_STR, &conf->host,  			  "port", CONF_STR, &conf->port,  			  "secret", CONF_STR, &conf->secret, +#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)      			  "tls", CONF_STR, &conf->tls,  			  "MatchCertificateAttribute", CONF_STR, &conf->matchcertattr, +			  "CertificateNameCheck", CONF_BLN, &conf->certnamecheck, +#endif			    			  "addTTL", CONF_LINT, &addttl,  			  "rewrite", CONF_STR, &rewriteinalias,  			  "rewriteIn", CONF_STR, &conf->confrewritein, @@ -3123,7 +2901,6 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char  			  "StatusServer", CONF_BLN, &conf->statusserver,  			  "RetryInterval", CONF_LINT, &retryinterval,  			  "RetryCount", CONF_LINT, &retrycount, -			  "CertificateNameCheck", CONF_BLN, &conf->certnamecheck,  			  "DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,  			  NULL  			  )) { diff --git a/radsecproxy.h b/radsecproxy.h index 1c3135f..5bba34a 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -8,6 +8,7 @@  #include "tlv11.h"  #include "radmsg.h" +#include "gconfig.h"  #define DEBUG_LEVEL 3 @@ -106,6 +107,8 @@ struct clsrvconf {      struct server *servers;  }; +#include "tlscommon.h" +  struct client {      struct clsrvconf *conf;      int sock; @@ -204,8 +207,5 @@ void freebios(struct queue *q);  struct request *newrequest();  void freerq(struct request *rq);  int radsrv(struct request *rq); -X509 *verifytlscert(SSL *ssl); -int verifyconfcert(X509 *cert, struct clsrvconf *conf);  void replyh(struct server *server, unsigned char *buf); -SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);  struct addrinfo *resolve_hostport_addrinfo(uint8_t type, char *hostport); @@ -6,7 +6,6 @@   * copyright notice and this permission notice appear in all copies.   */ -#ifdef RADPROT_TCP  #include <signal.h>  #include <sys/socket.h>  #include <netinet/in.h> @@ -25,12 +24,12 @@  #include <arpa/inet.h>  #include <regex.h>  #include <pthread.h> -#include <openssl/ssl.h> -#include "debug.h"  #include "list.h" -#include "util.h"  #include "radsecproxy.h" +#ifdef RADPROT_TCP +#include "debug.h" +#include "util.h"  static void setprotoopts(struct commonprotoopts *opts);  static char **getlistenerargs();  void *tcplistener(void *arg); diff --git a/tlscommon.c b/tlscommon.c index d934269..2c89e3d 100644 --- a/tlscommon.c +++ b/tlscommon.c @@ -36,26 +36,8 @@  #include "list.h"  #include "hash.h"  #include "util.h" -#include "gconfig.h"  #include "radsecproxy.h" -struct tls { -    char *name; -    char *cacertfile; -    char *cacertpath; -    char *certfile; -    char *certkeyfile; -    char *certkeypwd; -    uint8_t crlcheck; -    char **policyoids; -    uint32_t cacheexpiry; -    uint32_t tlsexpiry; -    uint32_t dtlsexpiry; -    X509_VERIFY_PARAM *vpm; -    SSL_CTX *tlsctx; -    SSL_CTX *dtlsctx; -}; -  static struct hash *tlsconfs = NULL;  static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) { @@ -335,6 +317,194 @@ SSL_CTX *tlsgetctx(uint8_t type, struct tls *t) {      return NULL;  } +X509 *verifytlscert(SSL *ssl) { +    X509 *cert; +    unsigned long error; +     +    if (SSL_get_verify_result(ssl) != X509_V_OK) { +	debug(DBG_ERR, "verifytlscert: basic validation failed"); +	while ((error = ERR_get_error())) +	    debug(DBG_ERR, "verifytlscert: TLS: %s", ERR_error_string(error, NULL)); +	return NULL; +    } + +    cert = SSL_get_peer_certificate(ssl); +    if (!cert) +	debug(DBG_ERR, "verifytlscert: failed to obtain certificate"); +    return cert; +} + +static int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) { +    int loc, i, l, n, r = 0; +    char *v; +    X509_EXTENSION *ex; +    STACK_OF(GENERAL_NAME) *alt; +    GENERAL_NAME *gn; +     +    debug(DBG_DBG, "subjectaltnameaddr"); +     +    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); +    if (loc < 0) +	return r; +     +    ex = X509_get_ext(cert, loc); +    alt = X509V3_EXT_d2i(ex); +    if (!alt) +	return r; +     +    n = sk_GENERAL_NAME_num(alt); +    for (i = 0; i < n; i++) { +	gn = sk_GENERAL_NAME_value(alt, i); +	if (gn->type != GEN_IPADD) +	    continue; +	r = -1; +	v = (char *)ASN1_STRING_data(gn->d.ia5); +	l = ASN1_STRING_length(gn->d.ia5); +	if (((family == AF_INET && l == sizeof(struct in_addr)) || (family == AF_INET6 && l == sizeof(struct in6_addr))) +	    && !memcmp(v, &addr, l)) { +	    r = 1; +	    break; +	} +    } +    GENERAL_NAMES_free(alt); +    return r; +} + +static int subjectaltnameregexp(X509 *cert, int type, char *exact,  regex_t *regex) { +    int loc, i, l, n, r = 0; +    char *s, *v; +    X509_EXTENSION *ex; +    STACK_OF(GENERAL_NAME) *alt; +    GENERAL_NAME *gn; +     +    debug(DBG_DBG, "subjectaltnameregexp"); +     +    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); +    if (loc < 0) +	return r; +     +    ex = X509_get_ext(cert, loc); +    alt = X509V3_EXT_d2i(ex); +    if (!alt) +	return r; +     +    n = sk_GENERAL_NAME_num(alt); +    for (i = 0; i < n; i++) { +	gn = sk_GENERAL_NAME_value(alt, i); +	if (gn->type != type) +	    continue; +	r = -1; +	v = (char *)ASN1_STRING_data(gn->d.ia5); +	l = ASN1_STRING_length(gn->d.ia5); +	if (l <= 0) +	    continue; +#ifdef DEBUG +	printfchars(NULL, gn->type == GEN_DNS ? "dns" : "uri", NULL, v, l); +#endif	 +	if (exact) { +	    if (memcmp(v, exact, l)) +		continue; +	} else { +	    s = stringcopy((char *)v, l); +	    if (!s) { +		debug(DBG_ERR, "malloc failed"); +		continue; +	    } +	    if (regexec(regex, s, 0, NULL, 0)) { +		free(s); +		continue; +	    } +	    free(s); +	} +	r = 1; +	break; +    } +    GENERAL_NAMES_free(alt); +    return r; +} + +static int cnregexp(X509 *cert, char *exact, regex_t *regex) { +    int loc, l; +    char *v, *s; +    X509_NAME *nm; +    X509_NAME_ENTRY *e; +    ASN1_STRING *t; + +    nm = X509_get_subject_name(cert); +    loc = -1; +    for (;;) { +	loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc); +	if (loc == -1) +	    break; +	e = X509_NAME_get_entry(nm, loc); +	t = X509_NAME_ENTRY_get_data(e); +	v = (char *) ASN1_STRING_data(t); +	l = ASN1_STRING_length(t); +	if (l < 0) +	    continue; +	if (exact) { +	    if (l == strlen(exact) && !strncasecmp(exact, v, l)) +		return 1; +	} else { +	    s = stringcopy((char *)v, l); +	    if (!s) { +		debug(DBG_ERR, "malloc failed"); +		continue; +	    } +	    if (regexec(regex, s, 0, NULL, 0)) { +		free(s); +		continue; +	    } +	    free(s); +	    return 1; +	} +    } +    return 0; +} + +int verifyconfcert(X509 *cert, struct clsrvconf *conf) { +    int r; +    uint8_t type = 0; /* 0 for DNS, AF_INET for IPv4, AF_INET6 for IPv6 */ +    struct in6_addr addr; +     +    if (conf->certnamecheck && conf->prefixlen == 255) { +	if (inet_pton(AF_INET, conf->host, &addr)) +	    type = AF_INET; +	else if (inet_pton(AF_INET6, conf->host, &addr)) +	    type = AF_INET6; + +	r = type ? subjectaltnameaddr(cert, type, &addr) : subjectaltnameregexp(cert, GEN_DNS, conf->host, NULL); +	if (r) { +	    if (r < 0) { +		debug(DBG_WARN, "verifyconfcert: No subjectaltname matching %s %s", type ? "address" : "host", conf->host); +		return 0; +	    } +	    debug(DBG_DBG, "verifyconfcert: Found subjectaltname matching %s %s", type ? "address" : "host", conf->host); +	} else { +	    if (!cnregexp(cert, conf->host, NULL)) { +		debug(DBG_WARN, "verifyconfcert: cn not matching host %s", conf->host); +		return 0; +	    }		 +	    debug(DBG_DBG, "verifyconfcert: Found cn matching host %s", conf->host); +	} +    } +    if (conf->certcnregex) { +	if (cnregexp(cert, NULL, conf->certcnregex) < 1) { +	    debug(DBG_WARN, "verifyconfcert: CN not matching regex"); +	    return 0; +	} +	debug(DBG_DBG, "verifyconfcert: CN matching regex"); +    } +    if (conf->certuriregex) { +	if (subjectaltnameregexp(cert, GEN_URI, NULL, conf->certuriregex) < 1) { +	    debug(DBG_WARN, "verifyconfcert: subjectaltname URI not matching regex"); +	    return 0; +	} +	debug(DBG_DBG, "verifyconfcert: subjectaltname URI matching regex"); +    } +    return 1; +} +  int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {      struct tls *conf;      long int expiry = LONG_MIN; @@ -405,6 +575,40 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v      free(conf);      return 0;  } + +int addmatchcertattr(struct clsrvconf *conf) { +    char *v; +    regex_t **r; +     +    if (!strncasecmp(conf->matchcertattr, "CN:/", 4)) { +	r = &conf->certcnregex; +	v = conf->matchcertattr + 4; +    } else if (!strncasecmp(conf->matchcertattr, "SubjectAltName:URI:/", 20)) { +	r = &conf->certuriregex; +	v = conf->matchcertattr + 20; +    } else +	return 0; +    if (!*v) +	return 0; +    /* regexp, remove optional trailing / if present */ +    if (v[strlen(v) - 1] == '/') +	v[strlen(v) - 1] = '\0'; +    if (!*v) +	return 0; + +    *r = malloc(sizeof(regex_t)); +    if (!*r) { +	debug(DBG_ERR, "malloc failed"); +	return 0; +    } +    if (regcomp(*r, v, REG_EXTENDED | REG_ICASE | REG_NOSUB)) { +	free(*r); +	*r = NULL; +	debug(DBG_ERR, "failed to compile regular expression %s", v); +	return 0; +    } +    return 1; +}  #else  /* Just to makes file non-empty, should rather avoid compiling this file when not needed */  static void tlsdummy() { diff --git a/tlscommon.h b/tlscommon.h index 2b7a5e4..97388e4 100644 --- a/tlscommon.h +++ b/tlscommon.h @@ -6,8 +6,30 @@   * copyright notice and this permission notice appear in all copies.   */ +#include <openssl/ssl.h> + +struct tls { +    char *name; +    char *cacertfile; +    char *cacertpath; +    char *certfile; +    char *certkeyfile; +    char *certkeypwd; +    uint8_t crlcheck; +    char **policyoids; +    uint32_t cacheexpiry; +    uint32_t tlsexpiry; +    uint32_t dtlsexpiry; +    X509_VERIFY_PARAM *vpm; +    SSL_CTX *tlsctx; +    SSL_CTX *dtlsctx; +}; +  #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)  struct tls *tlsgettls(char *alt1, char *alt2);  SSL_CTX *tlsgetctx(uint8_t type, struct tls *t); +X509 *verifytlscert(SSL *ssl); +int verifyconfcert(X509 *cert, struct clsrvconf *conf);  int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val); +int addmatchcertattr(struct clsrvconf *conf);  #endif @@ -6,7 +6,6 @@   * copyright notice and this permission notice appear in all copies.   */ -#ifdef RADPROT_UDP  #include <signal.h>  #include <sys/socket.h>  #include <netinet/in.h> @@ -25,12 +24,13 @@  #include <arpa/inet.h>  #include <regex.h>  #include <pthread.h> -#include <openssl/ssl.h> -#include "debug.h"  #include "list.h" -#include "util.h"  #include "radsecproxy.h" +#ifdef RADPROT_UDP +#include "debug.h" +#include "util.h" +  static void setprotoopts(struct commonprotoopts *opts);  static char **getlistenerargs();  void *udpserverrd(void *arg); @@ -102,6 +102,31 @@ void removeudpclientfromreplyq(struct client *c) {      pthread_mutex_unlock(&c->replyq->mutex);  }	 +static int addr_equal(struct sockaddr *a, struct sockaddr *b) { +    switch (a->sa_family) { +    case AF_INET: +	return !memcmp(&((struct sockaddr_in*)a)->sin_addr, +		       &((struct sockaddr_in*)b)->sin_addr, +		       sizeof(struct in_addr)); +    case AF_INET6: +	return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr, +				  &((struct sockaddr_in6*)b)->sin6_addr); +    default: +	/* Must not reach */ +	return 0; +    } +} + +uint16_t port_get(struct sockaddr *sa) { +    switch (sa->sa_family) { +    case AF_INET: +	return ntohs(((struct sockaddr_in *)sa)->sin_port); +    case AF_INET6: +	return ntohs(((struct sockaddr_in6 *)sa)->sin6_port); +    } +    return 0; +} +  /* exactly one of client and server must be non-NULL */  /* return who we received from in *client or *server */  /* return from in sa if not NULL */ @@ -261,6 +286,7 @@ void *udpserverrd(void *arg) {  	radsrv(rq);      }      free(sp); +    return NULL;  }  void *udpserverwr(void *arg) { @@ -39,16 +39,6 @@ void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int      printf("\n");  } -uint16_t port_get(struct sockaddr *sa) { -    switch (sa->sa_family) { -    case AF_INET: -	return ntohs(((struct sockaddr_in *)sa)->sin_port); -    case AF_INET6: -	return ntohs(((struct sockaddr_in6 *)sa)->sin6_port); -    } -    return 0; -} -  void port_set(struct sockaddr *sa, uint16_t port) {      switch (sa->sa_family) {      case AF_INET: @@ -60,21 +50,6 @@ void port_set(struct sockaddr *sa, uint16_t port) {      }  } -int addr_equal(struct sockaddr *a, struct sockaddr *b) { -    switch (a->sa_family) { -    case AF_INET: -	return !memcmp(&((struct sockaddr_in*)a)->sin_addr, -		       &((struct sockaddr_in*)b)->sin_addr, -		       sizeof(struct in_addr)); -    case AF_INET6: -	return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr, -				  &((struct sockaddr_in6*)b)->sin6_addr); -    default: -	/* Must not reach */ -	return 0; -    } -} -  struct sockaddr *addr_copy(struct sockaddr *in) {      struct sockaddr *out = NULL; @@ -122,6 +97,8 @@ char *addr2string(struct sockaddr *addr) {      return addr_buf[i];  } +#if 0 +/* not in use */  int connectport(int type, char *host, char *port) {      struct addrinfo hints, *res0, *res;      int s = -1; @@ -150,6 +127,7 @@ int connectport(int type, char *host, char *port) {      freeaddrinfo(res0);      return s;  } +#endif  int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {      int s, on = 1; @@ -11,12 +11,9 @@  char *stringcopy(const char *s, int len);  char *addr2string(struct sockaddr *addr); -int addr_equal(struct sockaddr *a, struct sockaddr *b);  struct sockaddr *addr_copy(struct sockaddr *in); -uint16_t port_get(struct sockaddr *sa);  void port_set(struct sockaddr *sa, uint16_t port);  void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len); -int connectport(int type, char *host, char *port);  int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);  int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src); | 
