Commit 0aa4b1fb authored by venaas's avatar venaas Committed by venaas

make clientwr not try to connect (left to reader), changed some timing stuff,...

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
parent 68d4aae0
......@@ -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;
......
......@@ -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) {
......
......@@ -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);
......@@ -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;
}
......
......@@ -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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment