diff options
-rw-r--r-- | radmsg.c | 10 | ||||
-rw-r--r-- | radsecproxy.c | 75 | ||||
-rw-r--r-- | radsecproxy.h | 7 | ||||
-rw-r--r-- | udp.c | 36 |
4 files changed, 62 insertions, 66 deletions
@@ -225,9 +225,13 @@ uint8_t *radmsg2buf(struct radmsg *msg, uint8_t *secret) { free(buf); return NULL; } - if (secret && (msg->code == RAD_Access_Accept || msg->code == RAD_Access_Reject || msg->code == RAD_Access_Challenge || msg->code == RAD_Accounting_Response || msg->code == RAD_Accounting_Request) && !_radsign(buf, secret)) { - free(buf); - return NULL; + if (secret) { + if ((msg->code == RAD_Access_Accept || msg->code == RAD_Access_Reject || msg->code == RAD_Access_Challenge || msg->code == RAD_Accounting_Response || msg->code == RAD_Accounting_Request) && !_radsign(buf, secret)) { + free(buf); + return NULL; + } + if (msg->code == RAD_Accounting_Request) + memcpy(msg->auth, buf + 4, 16); } return buf; } diff --git a/radsecproxy.c b/radsecproxy.c index fdb2838..6ac3825 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -577,7 +577,6 @@ struct client *addclient(struct clsrvconf *conf, uint8_t lock) { } memset(new, 0, sizeof(struct client)); - pthread_mutex_init(&new->lock, NULL); new->conf = conf; if (conf->pdef->addclient) conf->pdef->addclient(new); @@ -597,11 +596,8 @@ void removeclient(struct client *client) { conf = client->conf; pthread_mutex_lock(conf->lock); if (conf->clients) { - pthread_mutex_lock(&client->lock); removequeue(client->replyq); list_removedata(conf->clients, client); - pthread_mutex_unlock(&client->lock); - pthread_mutex_destroy(&client->lock); free(client->addr); free(client); } @@ -1352,14 +1348,14 @@ int pwdrecrypt(uint8_t *pwd, uint8_t len, char *oldsecret, char *newsecret, uint return 1; } -int msmpprecrypt(uint8_t *msmpp, uint8_t len, char *oldsecret, char *newsecret, unsigned char *oldauth, char *newauth) { +int msmpprecrypt(uint8_t *msmpp, uint8_t len, char *oldsecret, char *newsecret, uint8_t *oldauth, uint8_t *newauth) { if (len < 18) return 0; - if (!msmppdecrypt(msmpp + 2, len - 2, (unsigned char *)oldsecret, strlen(oldsecret), oldauth, msmpp)) { + if (!msmppdecrypt(msmpp + 2, len - 2, (uint8_t *)oldsecret, strlen(oldsecret), oldauth, msmpp)) { debug(DBG_WARN, "msmpprecrypt: failed to decrypt msppe key"); return 0; } - if (!msmppencrypt(msmpp + 2, len - 2, (unsigned char *)newsecret, strlen(newsecret), (unsigned char *)newauth, msmpp)) { + if (!msmppencrypt(msmpp + 2, len - 2, (uint8_t *)newsecret, strlen(newsecret), newauth, msmpp)) { debug(DBG_WARN, "msmpprecrypt: failed to encrypt msppe key"); return 0; } @@ -1372,7 +1368,7 @@ int msmppe(unsigned char *attrs, int length, uint8_t type, char *attrtxt, struct for (attr = attrs; (attr = attrget(attr, length - (attr - attrs), type)); attr += ATTRLEN(attr)) { debug(DBG_DBG, "msmppe: Got %s", attrtxt); - if (!msmpprecrypt(ATTRVAL(attr), ATTRVALLEN(attr), oldsecret, newsecret, rq->buf + 4, rq->origauth)) + if (!msmpprecrypt(ATTRVAL(attr), ATTRVALLEN(attr), oldsecret, newsecret, rq->buf + 4, rq->rqauth)) return 0; } return 1; @@ -1722,45 +1718,42 @@ struct request *newrequest() { return rq; } -int addclientrq(struct request *rq, uint8_t id) { +int addclientrq(struct request *rq) { struct request *r; struct timeval now; - - pthread_mutex_lock(&rq->from->lock); - gettimeofday(&now, NULL); - r = rq->from->rqs[id]; + + r = rq->from->rqs[rq->rqid]; if (r) { - if (now.tv_sec - r->created.tv_sec < r->from->conf->dupinterval) { + if (rq->udpport == r->udpport && !memcmp(rq->rqauth, r->rqauth, 16)) { + gettimeofday(&now, NULL); + if (now.tv_sec - r->created.tv_sec < r->from->conf->dupinterval) { #if 0 - later - if (r->replybuf) { - debug(DBG_INFO, "radsrv: already sent reply to request with id %d from %s, resending", id, r->from->conf->host); - r->refcount++; - sendreply(r); - } else + later + if (r->replybuf) { + debug(DBG_INFO, "radsrv: already sent reply to request with id %d from %s, resending", rq->rqid, addr2string(r->from->addr)); + r->refcount++; + sendreply(r); + } else #endif - debug(DBG_INFO, "radsrv: already got request with id %d from %s, ignoring", id, r->from->conf->host); - pthread_mutex_unlock(&rq->from->lock); - return 0; + debug(DBG_INFO, "radsrv: already got request with id %d from %s, ignoring", rq->rqid, addr2string(r->from->addr)); + return 0; + } } freerq(r); } rq->refcount++; - rq->from->rqs[id] = rq; - pthread_mutex_unlock(&rq->from->lock); + rq->from->rqs[rq->rqid] = rq; return 1; } void rmclientrq(struct request *rq, uint8_t id) { struct request *r; - pthread_mutex_lock(&rq->from->lock); r = rq->from->rqs[id]; if (r) { freerq(r); rq->from->rqs[id] = NULL; } - pthread_mutex_unlock(&rq->from->lock); } /* returns 0 if validation/authentication fails, else 1 */ @@ -1768,7 +1761,6 @@ int radsrv(struct request *rq) { struct radmsg *msg = NULL; struct tlv *attr; uint8_t *userascii = NULL; - unsigned char newauth[16]; struct realm *realm = NULL; struct server *to = NULL; struct client *from = rq->from; @@ -1784,13 +1776,16 @@ int radsrv(struct request *rq) { } rq->msg = msg; + rq->rqid = msg->id; + memcpy(rq->rqauth, msg->auth, 16); + debug(DBG_DBG, "radsrv: code %d, id %d", msg->code, msg->id); if (msg->code != RAD_Access_Request && msg->code != RAD_Status_Server && msg->code != RAD_Accounting_Request) { debug(DBG_INFO, "radsrv: server currently accepts only access-requests, accounting-requests and status-server, ignoring"); goto exit; } - if (!addclientrq(rq, msg->id)) + if (!addclientrq(rq)) goto exit; if (msg->code == RAD_Status_Server) { @@ -1846,11 +1841,11 @@ int radsrv(struct request *rq) { goto exit; } - if (msg->code != RAD_Accounting_Request) { - if (!RAND_bytes(newauth, 16)) { - debug(DBG_WARN, "radsrv: failed to generate random auth"); - goto rmclrqexit; - } + if (msg->code == RAD_Accounting_Request) + memset(msg->auth, 0, 16); + else if (!RAND_bytes(msg->auth, 16)) { + debug(DBG_WARN, "radsrv: failed to generate random auth"); + goto rmclrqexit; } #ifdef DEBUG @@ -1860,21 +1855,17 @@ int radsrv(struct request *rq) { attr = radmsg_gettype(msg, RAD_Attr_User_Password); if (attr) { debug(DBG_DBG, "radsrv: found userpwdattr with value length %d", attr->l); - if (!pwdrecrypt(attr->v, attr->l, from->conf->secret, to->conf->secret, msg->auth, newauth)) + if (!pwdrecrypt(attr->v, attr->l, from->conf->secret, to->conf->secret, rq->rqauth, msg->auth)) goto rmclrqexit; } attr = radmsg_gettype(msg, RAD_Attr_Tunnel_Password); if (attr) { debug(DBG_DBG, "radsrv: found tunnelpwdattr with value length %d", attr->l); - if (!pwdrecrypt(attr->v, attr->l, from->conf->secret, to->conf->secret, msg->auth, newauth)) + if (!pwdrecrypt(attr->v, attr->l, from->conf->secret, to->conf->secret, rq->rqauth, msg->auth)) goto rmclrqexit; } - rq->origid = msg->id; - memcpy(rq->origauth, msg->auth, 16); - memcpy(msg->auth, newauth, 16); - if (to->conf->rewriteout && !dorewrite(msg, to->conf->rewriteout)) goto rmclrqexit; @@ -1993,8 +1984,8 @@ void replyh(struct server *server, unsigned char *buf) { } } - msg->id = (char)rqout->rq->origid; - memcpy(msg->auth, rqout->rq->origauth, 16); + msg->id = (char)rqout->rq->rqid; + memcpy(msg->auth, rqout->rq->rqauth, 16); #ifdef DEBUG printfchars(NULL, "origauth/buf+4", "%02x ", buf + 4, 16); diff --git a/radsecproxy.h b/radsecproxy.h index 6caf2d9..8c17c96 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -49,8 +49,8 @@ struct request { struct radmsg *msg; struct client *from; char *origusername; - char origauth[16]; - uint8_t origid; + uint8_t rqid; + uint8_t rqauth[16]; int udpsock; /* only for UDP */ uint16_t udpport; /* only for UDP */ }; @@ -102,9 +102,8 @@ struct clsrvconf { struct client { struct clsrvconf *conf; - int sock; /* for tcp/dtls */ + int sock; SSL *ssl; - pthread_mutex_t lock; /* used for updating rqs */ struct request *rqs[MAX_REQUESTS]; struct queue *replyq; struct queue *rbios; /* for dtls */ @@ -47,6 +47,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, struct clsrvconf *p; struct list_node *node; fd_set readfds; + struct client *c = NULL; for (;;) { if (rad) { @@ -103,26 +104,27 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, if (client) { pthread_mutex_lock(p->lock); - for (node = list_first(p->clients); node; node = list_next(node)) - if (addr_equal((struct sockaddr *)&from, ((struct client *)node->data)->addr)) + for (node = list_first(p->clients); node; node = list_next(node)) { + c = (struct client *)node->data; + if (s == c->sock && addr_equal((struct sockaddr *)&from, c->addr)) break; - if (node) { - *client = (struct client *)node->data; - pthread_mutex_unlock(p->lock); - break; } - fromcopy = addr_copy((struct sockaddr *)&from); - if (!fromcopy) { - pthread_mutex_unlock(p->lock); - continue; + if (!node) { + fromcopy = addr_copy((struct sockaddr *)&from); + if (!fromcopy) { + pthread_mutex_unlock(p->lock); + continue; + } + c = addclient(p, 0); + if (!c) { + free(fromcopy); + pthread_mutex_unlock(p->lock); + continue; + } + c->sock = s; + c->addr = fromcopy; } - *client = addclient(p, 0); - if (!*client) { - free(fromcopy); - pthread_mutex_unlock(p->lock); - continue; - } - (*client)->addr = fromcopy; + *client = c; pthread_mutex_unlock(p->lock); } else if (server) *server = p->servers; |