summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-12-22 13:14:41 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-12-22 13:14:41 +0000
commite0c9e33cc484025e2b80bec19f7130554e9e3781 (patch)
tree8e59eef2efd7c569707224edbc67ade716d8673f
parenta99d921cf322a09d779500c2cdeb55e3df260fb8 (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.h2
-rw-r--r--radsecproxy.c251
-rw-r--r--radsecproxy.h6
-rw-r--r--tcp.c7
-rw-r--r--tlscommon.c240
-rw-r--r--tlscommon.h22
-rw-r--r--udp.c34
-rw-r--r--util.c28
-rw-r--r--util.h3
9 files changed, 299 insertions, 294 deletions
diff --git a/gconfig.h b/gconfig.h
index 06dbf30..4861d5f 100644
--- a/gconfig.h
+++ b/gconfig.h
@@ -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);
diff --git a/tcp.c b/tcp.c
index cddd554..c0a266c 100644
--- a/tcp.c
+++ b/tcp.c
@@ -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
diff --git a/udp.c b/udp.c
index ad2789b..54cc97b 100644
--- a/udp.c
+++ b/udp.c
@@ -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) {
diff --git a/util.c b/util.c
index d9e2709..ae02570 100644
--- a/util.c
+++ b/util.c
@@ -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;
diff --git a/util.h b/util.h
index 9565584..d87befd 100644
--- a/util.h
+++ b/util.h
@@ -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);