Commit a1ea5fc1 authored by venaas's avatar venaas Committed by venaas

various code improvements

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@375 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent faf8717d
......@@ -585,8 +585,7 @@ void *dtlsclientrd(void *arg) {
dtlsconnect(server, &lastconnecttry, 0, "dtlsclientrd");
continue;
}
if (!replyh(server, buf))
free(buf);
replyh(server, buf);
}
ERR_remove_state(0);
server->clientrdgone = 1;
......
......@@ -13,6 +13,7 @@
#include <limits.h>
#include <glob.h>
#include <sys/types.h>
#include <ctype.h>
#include <libgen.h>
#include <errno.h>
#include "debug.h"
......@@ -350,6 +351,28 @@ int getconfigline(struct gconffile **cf, char *block, char **opt, char **val, in
return 0;
}
uint8_t hexdigit2int(char d) {
if (d >= '0' && d <= '9')
return d - '0';
if (d >= 'a' && d <= 'f')
return 10 + d - 'a';
if (d >= 'A' && d <= 'F')
return 10 + d - 'A';
return 0;
}
void unhex(char *s) {
char *t;
for (t = s; *t; s++) {
if (*t == '%' && isxdigit(t[1]) && isxdigit(t[2])) {
*s = 16 * hexdigit2int(t[1]) + hexdigit2int(t[2]);
t += 3;
} else
*s = *t++;
}
*s = '\0';
}
/* returns 1 if ok, 0 on error */
/* caller must free returned values also on error */
int getgenericconfig(struct gconffile **cf, char *block, ...) {
......@@ -436,6 +459,7 @@ int getgenericconfig(struct gconffile **cf, char *block, ...) {
debug(DBG_ERR, "configuration error, option %s already set to %s", opt, *str);
goto errexit;
}
unhex(val);
*str = val;
break;
case CONF_MSTR:
......@@ -448,6 +472,7 @@ int getgenericconfig(struct gconffile **cf, char *block, ...) {
debug(DBG_ERR, "malloc failed");
goto errexit;
}
unhex(val);
newmstr[n] = val;
newmstr[n + 1] = NULL;
*mstr = newmstr;
......
......@@ -16,6 +16,7 @@
#include "debug.h"
#include <pthread.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#define RADLEN(x) ntohs(((uint16_t *)(x))[1])
......@@ -32,6 +33,7 @@ struct radmsg *radmsg_init(uint8_t code, uint8_t id, uint8_t *auth) {
msg = malloc(sizeof(struct radmsg));
if (!msg)
return NULL;
memset(msg, 0, sizeof(struct radmsg));
msg->attrs = list_create();
if (!msg->attrs) {
free(msg);
......@@ -39,7 +41,12 @@ struct radmsg *radmsg_init(uint8_t code, uint8_t id, uint8_t *auth) {
}
msg->code = code;
msg->id = id;
memcpy(msg->auth, auth, 16);
if (auth)
memcpy(msg->auth, auth, 16);
else if (!RAND_bytes(msg->auth, 16)) {
free(msg);
return NULL;
}
return msg;
}
......@@ -66,40 +73,6 @@ struct tlv *radmsg_gettype(struct radmsg *msg, uint8_t type) {
return NULL;
}
uint8_t *radmsg2buf(struct radmsg *msg) {
struct list_node *node;
struct tlv *tlv;
int size;
uint8_t *buf, *p;
if (!msg || !msg->attrs)
return NULL;
size = 20;
for (node = list_first(msg->attrs); node; node = list_next(node))
size += 2 + ((struct tlv *)node->data)->l;
if (size > 65535)
return NULL;
buf = malloc(size);
if (!buf)
return NULL;
p = buf;
*p++ = msg->code;
*p++ = msg->id;
*(uint16_t *)p = htons(size);
p += 2;
memcpy(p, msg->auth, 16);
p += 16;
for (node = list_first(msg->attrs); node; node = list_next(node)) {
tlv = (struct tlv *)node->data;
p = tlv2buf(p, tlv);
p[-1] += 2;
p += tlv->l;
}
return buf;
}
int _checkmsgauth(unsigned char *rad, uint8_t *authattr, uint8_t *secret) {
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static unsigned char first = 1;
......@@ -163,7 +136,76 @@ int _validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
pthread_mutex_unlock(&lock);
return result;
}
int _createmessageauth(unsigned char *rad, unsigned char *authattrval, uint8_t *secret) {
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static unsigned char first = 1;
static HMAC_CTX hmacctx;
unsigned int md_len;
if (!authattrval)
return 1;
pthread_mutex_lock(&lock);
if (first) {
HMAC_CTX_init(&hmacctx);
first = 0;
}
memset(authattrval, 0, 16);
md_len = 0;
HMAC_Init_ex(&hmacctx, secret, strlen((char *)secret), EVP_md5(), NULL);
HMAC_Update(&hmacctx, rad, RADLEN(rad));
HMAC_Final(&hmacctx, authattrval, &md_len);
if (md_len != 16) {
debug(DBG_WARN, "message auth computation failed");
pthread_mutex_unlock(&lock);
return 0;
}
pthread_mutex_unlock(&lock);
return 1;
}
uint8_t *radmsg2buf(struct radmsg *msg, uint8_t *secret) {
struct list_node *node;
struct tlv *tlv;
int size;
uint8_t *buf, *p, *msgauth = NULL;
if (!msg || !msg->attrs)
return NULL;
size = 20;
for (node = list_first(msg->attrs); node; node = list_next(node))
size += 2 + ((struct tlv *)node->data)->l;
if (size > 65535)
return NULL;
buf = malloc(size);
if (!buf)
return NULL;
p = buf;
*p++ = msg->code;
*p++ = msg->id;
*(uint16_t *)p = htons(size);
p += 2;
memcpy(p, msg->auth, 16);
p += 16;
for (node = list_first(msg->attrs); node; node = list_next(node)) {
tlv = (struct tlv *)node->data;
p = tlv2buf(p, tlv);
p[-1] += 2;
if (tlv->t == RAD_Attr_Message_Authenticator && secret)
msgauth = p;
p += tlv->l;
}
if (msgauth && !_createmessageauth(buf, msgauth, secret)) {
free(buf);
return NULL;
}
return buf;
}
/* if secret set we also validate message authenticator if present */
struct radmsg *buf2radmsg(uint8_t *buf, uint8_t *secret, uint8_t *rqauth) {
struct radmsg *msg;
......
......@@ -37,5 +37,5 @@ void radmsg_free(struct radmsg *);
struct radmsg *radmsg_init(uint8_t, uint8_t, uint8_t *);
int radmsg_add(struct radmsg *, struct tlv *);
struct tlv *radmsg_gettype(struct radmsg *, uint8_t);
uint8_t *radmsg2buf(struct radmsg *msg);
uint8_t *radmsg2buf(struct radmsg *msg, uint8_t *);
struct radmsg *buf2radmsg(uint8_t *, uint8_t *, uint8_t *);
This diff is collapsed.
......@@ -6,6 +6,9 @@
* copyright notice and this permission notice appear in all copies.
*/
#include "tlv11.h"
#include "radmsg.h"
#define DEBUG_LEVEL 3
#define CONFIG_MAIN "/etc/radsecproxy.conf"
......@@ -41,6 +44,7 @@ struct options {
/* requests that our client will send */
struct request {
unsigned char *buf;
struct radmsg *msg;
uint8_t tries;
uint8_t received;
struct timeval expiry;
......@@ -203,6 +207,6 @@ void freebios(struct queue *q);
int radsrv(struct request *rq);
X509 *verifytlscert(SSL *ssl);
int verifyconfcert(X509 *cert, struct clsrvconf *conf);
int replyh(struct server *server, unsigned char *buf);
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);
......@@ -180,8 +180,7 @@ void *tcpclientrd(void *arg) {
continue;
}
if (!replyh(server, buf))
free(buf);
replyh(server, buf);
}
server->clientrdgone = 1;
return NULL;
......
......@@ -221,8 +221,8 @@ void *tlsclientrd(void *arg) {
continue;
}
if (!replyh(server, buf))
free(buf);
replyh(server, buf);
if (server->dynamiclookuparg) {
gettimeofday(&now, NULL);
if (now.tv_sec - server->lastreply.tv_sec > IDLE_TIMEOUT) {
......
......@@ -27,8 +27,6 @@
#include <openssl/ssl.h>
#include "debug.h"
#include "list.h"
#include "tlv11.h"
#include "radmsg.h"
#include "util.h"
#include "radsecproxy.h"
#include "tls.h"
......@@ -162,8 +160,7 @@ void *udpclientrd(void *arg) {
for (;;) {
server = NULL;
buf = radudpget(*s, NULL, &server, NULL);
if (!replyh(server, buf))
free(buf);
replyh(server, buf);
}
}
......
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