summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-09-23 15:21:50 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-09-23 15:21:50 +0000
commit0aa4b1fb04dafb9767309afa5d6ad6805391670f (patch)
tree49e25fb218817429cc1ae3e89d04e10e3d8f4829
parent68d4aae0802ff658cf822976820493627f4948e4 (diff)
make clientwr not try to connect (left to reader), changed some timing stuff, issue with statusserver and connection down..., added optional cacheexpiry option for tls blocks
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@398 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r--dtls.c21
-rw-r--r--radsecproxy.c67
-rw-r--r--radsecproxy.h6
-rw-r--r--tcp.c14
-rw-r--r--tls.c33
5 files changed, 102 insertions, 39 deletions
diff --git a/dtls.c b/dtls.c
index 0b26bbf..ed5e44e 100644
--- a/dtls.c
+++ b/dtls.c
@@ -297,12 +297,16 @@ void *dtlsservernew(void *arg) {
struct list_node *cur = NULL;
SSL *ssl = NULL;
X509 *cert = NULL;
+ SSL_CTX *ctx = NULL;
uint8_t delay = 60;
debug(DBG_DBG, "dtlsservernew: starting");
conf = find_clconf(RAD_DTLS, (struct sockaddr *)&params->addr, NULL);
if (conf) {
- ssl = dtlsacccon(1, conf->ssl_ctx, params->sock, (struct sockaddr *)&params->addr, params->sesscache->rbios);
+ ctx = tlsgetctx(RAD_DTLS, conf->tlsconf);
+ if (!ctx)
+ goto exit;
+ ssl = dtlsacccon(1, ctx, params->sock, (struct sockaddr *)&params->addr, params->sesscache->rbios);
if (!ssl)
goto exit;
cert = verifytlscert(ssl);
@@ -472,7 +476,8 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *
struct timeval now;
time_t elapsed;
X509 *cert;
-
+ SSL_CTX *ctx = NULL;
+
debug(DBG_DBG, "dtlsconnect: called from %s", text);
pthread_mutex_lock(&server->lock);
if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
@@ -510,7 +515,11 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *
debug(DBG_WARN, "dtlsconnect: trying to open DTLS connection to %s port %s", server->conf->host, server->conf->port);
SSL_free(server->ssl);
- server->ssl = dtlsacccon(0, server->conf->ssl_ctx, server->sock, server->conf->addrinfo->ai_addr, server->rbios);
+ server->ssl = NULL;
+ ctx = tlsgetctx(RAD_DTLS, server->conf->tlsconf);
+ if (!ctx)
+ continue;
+ server->ssl = dtlsacccon(0, ctx, server->sock, server->conf->addrinfo->ai_addr, server->rbios);
if (!server->ssl)
continue;
debug(DBG_DBG, "dtlsconnect: DTLS: ok");
@@ -525,6 +534,7 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *
}
X509_free(cert);
debug(DBG_WARN, "dtlsconnect: DTLS connection to %s port %s up", server->conf->host, server->conf->port);
+ server->connectionok = 1;
gettimeofday(&server->lastconnecttry, NULL);
pthread_mutex_unlock(&server->lock);
return 1;
@@ -536,12 +546,13 @@ int clientradputdtls(struct server *server, unsigned char *rad) {
unsigned long error;
struct clsrvconf *conf = server->conf;
- if (!server->ssl)
+ if (!server->connectionok)
return 0;
len = RADLEN(rad);
- while ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
+ if ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
while ((error = ERR_get_error()))
debug(DBG_ERR, "clientradputdtls: DTLS: %s", ERR_error_string(error, NULL));
+ return 0;
}
debug(DBG_DBG, "clientradputdtls: Sent %d bytes, Radius packet of length %d to DTLS peer %s", cnt, len, conf->host);
return 1;
diff --git a/radsecproxy.c b/radsecproxy.c
index 71d8856..9c44328 100644
--- a/radsecproxy.c
+++ b/radsecproxy.c
@@ -1019,7 +1019,8 @@ void sendrq(struct server *to, struct request *rq) {
return;
errexit:
- rmclientrq(rq, rq->msg->id);
+ if (rq->from)
+ rmclientrq(rq, rq->msg->id);
freerq(rq);
pthread_mutex_unlock(&to->newrq_mutex);
}
@@ -2061,7 +2062,8 @@ void *clientwr(void *arg) {
struct server *server = (struct server *)arg;
struct rqout *rqout = NULL;
pthread_t clientrdth;
- int i, secs, dynconffail = 0;
+ int i, dynconffail = 0;
+ time_t secs;
uint8_t rnd;
struct timeval now, laststatsrv;
struct timespec timeout;
@@ -2107,6 +2109,8 @@ void *clientwr(void *arg) {
rnd /= 32;
if (conf->statusserver) {
secs = server->lastrcv.tv_sec > laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec;
+ if (now.tv_sec - secs > STATUS_SERVER_PERIOD)
+ secs = now.tv_sec;
if (!timeout.tv_sec || timeout.tv_sec > secs + STATUS_SERVER_PERIOD + rnd)
timeout.tv_sec = secs + STATUS_SERVER_PERIOD + rnd;
} else {
@@ -2182,7 +2186,7 @@ void *clientwr(void *arg) {
conf->pdef->clientradput(server, rqout->rq->buf);
pthread_mutex_unlock(rqout->lock);
}
- if (conf->statusserver) {
+ if (conf->statusserver && server->connectionok) {
secs = server->lastrcv.tv_sec > laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec;
gettimeofday(&now, NULL);
if (now.tv_sec - secs > STATUS_SERVER_PERIOD) {
@@ -2388,24 +2392,50 @@ SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) {
return ctx;
}
-SSL_CTX *tlsgetctx(uint8_t type, char *alt1, char *alt2) {
+struct tls *tlsgettls(char *alt1, char *alt2) {
struct tls *t;
t = hash_read(tlsconfs, alt1, strlen(alt1));
- if (!t) {
+ if (!t)
t = hash_read(tlsconfs, alt2, strlen(alt2));
- if (!t)
- return NULL;
- }
+ return t;
+}
+SSL_CTX *tlsgetctx(uint8_t type, struct tls *t) {
+ struct timeval now;
+
+ if (!t)
+ return NULL;
+ gettimeofday(&now, NULL);
+
switch (type) {
case RAD_TLS:
- if (!t->tlsctx)
+ if (t->tlsexpiry && t->tlsctx) {
+ if (t->tlsexpiry < now.tv_sec) {
+ t->tlsexpiry = now.tv_sec + t->cacheexpiry;
+ SSL_CTX_free(t->tlsctx);
+ return t->tlsctx = tlscreatectx(RAD_TLS, t);
+ }
+ }
+ if (!t->tlsctx) {
t->tlsctx = tlscreatectx(RAD_TLS, t);
+ if (t->cacheexpiry)
+ t->tlsexpiry = now.tv_sec + t->cacheexpiry;
+ }
return t->tlsctx;
case RAD_DTLS:
- if (!t->dtlsctx)
+ if (t->dtlsexpiry && t->dtlsctx) {
+ if (t->dtlsexpiry < now.tv_sec) {
+ t->dtlsexpiry = now.tv_sec + t->cacheexpiry;
+ SSL_CTX_free(t->dtlsctx);
+ return t->dtlsctx = tlscreatectx(RAD_DTLS, t);
+ }
+ }
+ if (!t->dtlsctx) {
t->dtlsctx = tlscreatectx(RAD_DTLS, t);
+ if (t->cacheexpiry)
+ t->dtlsexpiry = now.tv_sec + t->cacheexpiry;
+ }
return t->dtlsctx;
}
return NULL;
@@ -3066,8 +3096,8 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
free(conftype);
if (conf->type == RAD_TLS || conf->type == RAD_DTLS) {
- conf->ssl_ctx = conf->tls ? tlsgetctx(conf->type, conf->tls, NULL) : tlsgetctx(conf->type, "defaultclient", "default");
- if (!conf->ssl_ctx)
+ conf->tlsconf = conf->tls ? tlsgettls(conf->tls, NULL) : tlsgettls("defaultclient", "default");
+ if (!conf->tlsconf)
debugx(1, DBG_ERR, "error in block %s, no tls context defined", block);
if (conf->matchcertattr && !addmatchcertattr(conf))
debugx(1, DBG_ERR, "error in block %s, invalid MatchCertificateAttributeValue", block);
@@ -3117,8 +3147,8 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
int compileserverconfig(struct clsrvconf *conf, const char *block) {
if (conf->type == RAD_TLS || conf->type == RAD_DTLS) {
- conf->ssl_ctx = conf->tls ? tlsgetctx(conf->type, conf->tls, NULL) : tlsgetctx(conf->type, "defaultserver", "default");
- if (!conf->ssl_ctx) {
+ conf->tlsconf = conf->tls ? tlsgettls(conf->tls, NULL) : tlsgettls("defaultserver", "default");
+ if (!conf->tlsconf) {
debug(DBG_ERR, "error in block %s, no tls context defined", block);
return 0;
}
@@ -3306,6 +3336,7 @@ int confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
struct tls *conf;
+ long int expiry = LONG_MIN;
debug(DBG_DBG, "conftls_cb called for %s", block);
@@ -3322,6 +3353,7 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v
"CertificateFile", CONF_STR, &conf->certfile,
"CertificateKeyFile", CONF_STR, &conf->certkeyfile,
"CertificateKeyPassword", CONF_STR, &conf->certkeypwd,
+ "CacheExpiry", CONF_LINT, &expiry,
"CRLCheck", CONF_BLN, &conf->crlcheck,
NULL
)) {
@@ -3336,6 +3368,13 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v
debug(DBG_ERR, "conftls_cb: CA Certificate file or path need to be specified in block %s", val);
goto errexit;
}
+ if (expiry != LONG_MIN) {
+ if (expiry < 0) {
+ debug(DBG_ERR, "error in block %s, value of option CacheExpiry is %ld, may not be negative", val, expiry);
+ goto errexit;
+ }
+ conf->cacheexpiry = expiry;
+ }
conf->name = stringcopy(val, 0);
if (!conf->name) {
diff --git a/radsecproxy.h b/radsecproxy.h
index 8c17c96..4cb102b 100644
--- a/radsecproxy.h
+++ b/radsecproxy.h
@@ -90,12 +90,12 @@ struct clsrvconf {
uint8_t retrycount;
uint8_t dupinterval;
uint8_t certnamecheck;
- SSL_CTX *ssl_ctx;
struct rewrite *rewritein;
struct rewrite *rewriteout;
struct addrinfo *addrinfo;
uint8_t prefixlen;
pthread_mutex_t *lock; /* only used for updating clients so far */
+ struct tls *tlsconf;
struct list *clients;
struct server *servers;
};
@@ -150,6 +150,9 @@ struct tls {
char *certkeyfile;
char *certkeypwd;
uint8_t crlcheck;
+ uint32_t cacheexpiry;
+ uint32_t tlsexpiry;
+ uint32_t dtlsexpiry;
SSL_CTX *tlsctx;
SSL_CTX *dtlsctx;
};
@@ -212,3 +215,4 @@ int verifyconfcert(X509 *cert, struct clsrvconf *conf);
void replyh(struct server *server, unsigned char *buf);
int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src);
int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);
+SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);
diff --git a/tcp.c b/tcp.c
index 0d1da1c..2a4a799 100644
--- a/tcp.c
+++ b/tcp.c
@@ -75,6 +75,7 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t
debug(DBG_ERR, "tcpconnect: connecttcp failed");
}
debug(DBG_WARN, "tcpconnect: TCP connection to %s port %s up", server->conf->host, server->conf->port);
+ server->connectionok = 1;
gettimeofday(&server->lastconnecttry, NULL);
pthread_mutex_unlock(&server->lock);
return 1;
@@ -150,18 +151,15 @@ unsigned char *radtcpget(int s, int timeout) {
int clientradputtcp(struct server *server, unsigned char *rad) {
int cnt;
size_t len;
- struct timeval lastconnecttry;
struct clsrvconf *conf = server->conf;
-
+
+ if (!server->connectionok)
+ return 0;
len = RADLEN(rad);
- lastconnecttry = server->lastconnecttry;
- while ((cnt = write(server->sock, rad, len)) <= 0) {
+ if ((cnt = write(server->sock, rad, len)) <= 0) {
debug(DBG_ERR, "clientradputtcp: write error");
- tcpconnect(server, &lastconnecttry, 0, "clientradputtcp");
- lastconnecttry = server->lastconnecttry;
+ return 0;
}
-
- server->connectionok = 1;
debug(DBG_DBG, "clientradputtcp: Sent %d bytes, Radius packet of length %d to TCP peer %s", cnt, len, conf->host);
return 1;
}
diff --git a/tls.c b/tls.c
index 8ff92f9..836f3aa 100644
--- a/tls.c
+++ b/tls.c
@@ -36,6 +36,7 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t
struct timeval now;
time_t elapsed;
X509 *cert;
+ SSL_CTX *ctx = NULL;
unsigned long error;
debug(DBG_DBG, "tlsconnect: called from %s", text);
@@ -81,7 +82,14 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t
}
SSL_free(server->ssl);
- server->ssl = SSL_new(server->conf->ssl_ctx);
+ server->ssl = NULL;
+ ctx = tlsgetctx(RAD_TLS, server->conf->tlsconf);
+ if (!ctx)
+ continue;
+ server->ssl = SSL_new(ctx);
+ if (!server->ssl)
+ continue;
+
SSL_set_fd(server->ssl, server->sock);
if (SSL_connect(server->ssl) <= 0) {
while ((error = ERR_get_error()))
@@ -98,6 +106,7 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t
X509_free(cert);
}
debug(DBG_WARN, "tlsconnect: TLS connection to %s port %s up", server->conf->host, server->conf->port);
+ server->connectionok = 1;
gettimeofday(&server->lastconnecttry, NULL);
pthread_mutex_unlock(&server->lock);
return 1;
@@ -186,21 +195,17 @@ int clientradputtls(struct server *server, unsigned char *rad) {
int cnt;
size_t len;
unsigned long error;
- struct timeval lastconnecttry;
struct clsrvconf *conf = server->conf;
-
+
+ if (!server->connectionok)
+ return 0;
len = RADLEN(rad);
- lastconnecttry = server->lastconnecttry;
- while ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
+ if ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {
while ((error = ERR_get_error()))
debug(DBG_ERR, "clientradputtls: TLS: %s", ERR_error_string(error, NULL));
- if (server->dynamiclookuparg)
- return 0;
- tlsconnect(server, &lastconnecttry, 0, "clientradputtls");
- lastconnecttry = server->lastconnecttry;
+ return 0;
}
- server->connectionok = 1;
debug(DBG_DBG, "clientradputtls: Sent %d bytes, Radius packet of length %d to TLS peer %s", cnt, len, conf->host);
return 1;
}
@@ -325,6 +330,7 @@ void *tlsservernew(void *arg) {
struct list_node *cur = NULL;
SSL *ssl = NULL;
X509 *cert = NULL;
+ SSL_CTX *ctx = NULL;
unsigned long error;
struct client *client;
@@ -337,7 +343,12 @@ void *tlsservernew(void *arg) {
conf = find_clconf(RAD_TLS, (struct sockaddr *)&from, &cur);
if (conf) {
- ssl = SSL_new(conf->ssl_ctx);
+ ctx = tlsgetctx(RAD_TLS, conf->tlsconf);
+ if (!ctx)
+ goto exit;
+ ssl = SSL_new(ctx);
+ if (!ssl)
+ goto exit;
SSL_set_fd(ssl, s);
if (SSL_accept(ssl) <= 0) {