summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2007-10-02 15:26:22 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2007-10-02 15:26:22 +0000
commit74c17fd2b460a6eb31dcbc48a6f6e3eb195abafe (patch)
tree7e105c2b530befd0f6d3faea44e677817527e41b
parente2795d242623c166bed292cf280cd78469c473a4 (diff)
code for keeping original username in request when rewriting, new freerqdata function and some tidying
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@175 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r--radsecproxy.c111
-rw-r--r--radsecproxy.h1
2 files changed, 71 insertions, 41 deletions
diff --git a/radsecproxy.c b/radsecproxy.c
index 05a3e82..4413927 100644
--- a/radsecproxy.c
+++ b/radsecproxy.c
@@ -873,6 +873,13 @@ unsigned char *attrget(unsigned char *attrs, int length, uint8_t type) {
return NULL;
}
+void freerqdata(struct request *rq) {
+ if (rq->origusername)
+ free(rq->origusername);
+ if (rq->buf)
+ free(rq->buf);
+}
+
void sendrq(struct server *to, struct request *rq) {
int i;
uint8_t *attr;
@@ -888,7 +895,7 @@ void sendrq(struct server *to, struct request *rq) {
break;
if (i == to->nextid) {
debug(DBG_WARN, "No room in queue, dropping request");
- free(rq->buf);
+ freerqdata(rq);
pthread_mutex_unlock(&to->newrq_mutex);
return;
}
@@ -898,7 +905,7 @@ void sendrq(struct server *to, struct request *rq) {
attr = attrget(rq->buf + 20, RADLEN(rq->buf) - 20, RAD_Attr_Message_Authenticator);
if (attr && !createmessageauth(rq->buf, ATTRVAL(attr), to->conf->secret)) {
- free(rq->buf);
+ freerqdata(rq);
pthread_mutex_unlock(&to->newrq_mutex);
return;
}
@@ -1249,18 +1256,22 @@ int msmppe(unsigned char *attrs, int length, uint8_t type, char *attrtxt, struct
return 1;
}
-void rewriteattr(struct clsrvconf *conf, char *in) {
+int rewriteattr(struct request *rq, char *in) {
size_t nmatch = 10, reslen = 0, start = 0;
regmatch_t pmatch[10], *pfield;
int i;
char result[1024];
- char *out = conf->rewriteattrreplacement;
+ char *out = rq->from->conf->rewriteattrreplacement;
- if (regexec(conf->rewriteattrregex, in, nmatch, pmatch, 0)) {
+ if (regexec(rq->from->conf->rewriteattrregex, in, nmatch, pmatch, 0)) {
debug(DBG_DBG, "rewriteattr: username not matching, no rewrite");
- return;
+ return 1;
}
+ rq->origusername = stringcopy(in, 0);
+ if (!rq->origusername)
+ return 0;
+
for (i = start; out[i]; i++) {
if (out[i] == '\\' && out[i + 1] >= '1' && out[i + 1] <= '9') {
pfield = &pmatch[out[i + 1] - '0'];
@@ -1276,7 +1287,8 @@ void rewriteattr(struct clsrvconf *conf, char *in) {
}
memcpy(result + reslen, out + start, i + 1 - start);
- debug(DBG_DBG, "rewriteattr: username matching, would have rewritten to %s", result);
+ debug(DBG_DBG, "rewriteattr: username matching, %s would have rewritten to %s", in, result);
+ return 1;
}
void acclog(unsigned char *attrs, int length, char *host) {
@@ -1386,7 +1398,7 @@ void radsrv(struct request *rq) {
if (code != RAD_Access_Request && code != RAD_Status_Server && code != RAD_Accounting_Request) {
debug(DBG_INFO, "radsrv: server currently accepts only access-requests, accounting-requests and status-server, ignoring");
- free(buf);
+ freerqdata(rq);
return;
}
@@ -1395,7 +1407,7 @@ void radsrv(struct request *rq) {
if (!attrvalidate(attrs, len)) {
debug(DBG_WARN, "radsrv: attribute validation failed, ignoring packet");
- free(buf);
+ freerqdata(rq);
return;
}
@@ -1403,27 +1415,35 @@ void radsrv(struct request *rq) {
attr = attrget(attrs, len, RAD_Attr_User_Name);
if (!attr) {
debug(DBG_WARN, "radsrv: ignoring request, no username attribute");
- free(buf);
+ freerqdata(rq);
return;
}
memcpy(username, ATTRVAL(attr), ATTRVALLEN(attr));
username[ATTRVALLEN(attr)] = '\0';
- debug(DBG_DBG, "Access Request with username: %s", username);
if (rq->from->conf->rewriteattrregex)
- rewriteattr(rq->from->conf, username);
+ if (!rewriteattr(rq, username)) {
+ debug(DBG_WARN, "radsrv: username malloc failed, ignoring request");
+ freerqdata(rq);
+ return;
+ }
+
+ if (rq->origusername)
+ debug(DBG_DBG, "Access Request with username: %s (originally %s)", username, rq->origusername);
+ else
+ debug(DBG_DBG, "Access Request with username: %s", username);
realm = id2realm(username, strlen(username));
if (!realm) {
debug(DBG_INFO, "radsrv: ignoring request, don't know where to send it");
- free(buf);
+ freerqdata(rq);
return;
}
to = realm2server(realm);
if (to && rqinqueue(to, rq->from, id)) {
debug(DBG_INFO, "radsrv: already got request from host %s with id %d, ignoring", rq->from->conf->host, id);
- free(buf);
+ freerqdata(rq);
return;
}
}
@@ -1431,20 +1451,20 @@ void radsrv(struct request *rq) {
attr = attrget(attrs, len, RAD_Attr_Message_Authenticator);
if (attr && (ATTRVALLEN(attr) != 16 || !checkmessageauth(buf, ATTRVAL(attr), rq->from->conf->secret))) {
debug(DBG_WARN, "radsrv: message authentication failed");
- free(buf);
+ freerqdata(rq);
return;
}
if (code == RAD_Accounting_Request) {
acclog(attrs, len, rq->from->conf->host);
respondaccounting(rq);
- free(buf);
+ freerqdata(rq);
return;
}
if (code == RAD_Status_Server) {
respondstatusserver(rq);
- free(buf);
+ freerqdata(rq);
return;
}
@@ -1453,13 +1473,13 @@ void radsrv(struct request *rq) {
debug(DBG_INFO, "radsrv: sending reject to %s for %s", rq->from->conf->host, username);
respondreject(rq, realm->message);
}
- free(buf);
+ freerqdata(rq);
return;
}
if (!RAND_bytes(newauth, 16)) {
debug(DBG_WARN, "radsrv: failed to generate random auth");
- free(buf);
+ freerqdata(rq);
return;
}
@@ -1471,7 +1491,7 @@ void radsrv(struct request *rq) {
if (attr) {
debug(DBG_DBG, "radsrv: found userpwdattr with value length %d", ATTRVALLEN(attr));
if (!pwdrecrypt(ATTRVAL(attr), ATTRVALLEN(attr), rq->from->conf->secret, to->conf->secret, auth, newauth)) {
- free(buf);
+ freerqdata(rq);
return;
}
}
@@ -1480,7 +1500,7 @@ void radsrv(struct request *rq) {
if (attr) {
debug(DBG_DBG, "radsrv: found tunnelpwdattr with value length %d", ATTRVALLEN(attr));
if (!pwdrecrypt(ATTRVAL(attr), ATTRVALLEN(attr), rq->from->conf->secret, to->conf->secret, auth, newauth)) {
- free(buf);
+ freerqdata(rq);
return;
}
}
@@ -1494,6 +1514,7 @@ void radsrv(struct request *rq) {
void *clientrd(void *arg) {
struct server *server = (struct server *)arg;
struct client *from;
+ struct request *rq;
int i, len, sublen;
unsigned char *buf, *messageauth, *subattrs, *attrs, *attr;
struct sockaddr_storage fromsa;
@@ -1528,30 +1549,32 @@ void *clientrd(void *arg) {
debug(DBG_INFO, "clientrd: discarding, only accept access accept, access reject and access challenge messages");
continue;
}
+
+ rq = server->requests + i;
pthread_mutex_lock(&server->newrq_mutex);
- if (!server->requests[i].buf || !server->requests[i].tries) {
+ if (!rq->buf || !rq->tries) {
pthread_mutex_unlock(&server->newrq_mutex);
free(buf);
debug(DBG_INFO, "clientrd: no matching request sent with this id, ignoring");
continue;
}
- if (server->requests[i].received) {
+ if (rq->received) {
pthread_mutex_unlock(&server->newrq_mutex);
free(buf);
debug(DBG_INFO, "clientrd: already received, ignoring");
continue;
}
- if (!validauth(buf, server->requests[i].buf + 4, (unsigned char *)server->conf->secret)) {
+ if (!validauth(buf, rq->buf + 4, (unsigned char *)server->conf->secret)) {
pthread_mutex_unlock(&server->newrq_mutex);
free(buf);
debug(DBG_WARN, "clientrd: invalid auth, ignoring");
continue;
}
- from = server->requests[i].from;
+ from = rq->from;
len = RADLEN(buf) - 20;
attrs = buf + 20;
@@ -1572,7 +1595,7 @@ void *clientrd(void *arg) {
continue;
}
memcpy(tmp, buf + 4, 16);
- memcpy(buf + 4, server->requests[i].buf + 4, 16);
+ memcpy(buf + 4, rq->buf + 4, 16);
if (!checkmessageauth(buf, ATTRVAL(messageauth), server->conf->secret)) {
pthread_mutex_unlock(&server->newrq_mutex);
free(buf);
@@ -1583,8 +1606,8 @@ void *clientrd(void *arg) {
debug(DBG_DBG, "clientrd: message auth ok");
}
- if (*server->requests[i].buf == RAD_Status_Server) {
- server->requests[i].received = 1;
+ if (*rq->buf == RAD_Status_Server) {
+ rq->received = 1;
pthread_mutex_unlock(&server->newrq_mutex);
free(buf);
debug(DBG_INFO, "clientrd: got status server response from %s", server->conf->host);
@@ -1603,9 +1626,9 @@ void *clientrd(void *arg) {
subattrs = ATTRVAL(attr) + 4;
if (!attrvalidate(subattrs, sublen) ||
!msmppe(subattrs, sublen, RAD_VS_ATTR_MS_MPPE_Send_Key, "MS MPPE Send Key",
- server->requests + i, server->conf->secret, from->conf->secret) ||
+ rq, server->conf->secret, from->conf->secret) ||
!msmppe(subattrs, sublen, RAD_VS_ATTR_MS_MPPE_Recv_Key, "MS MPPE Recv Key",
- server->requests + i, server->conf->secret, from->conf->secret))
+ rq, server->conf->secret, from->conf->secret))
break;
}
if (attr) {
@@ -1616,23 +1639,29 @@ void *clientrd(void *arg) {
}
if (*buf == RAD_Access_Accept || *buf == RAD_Access_Reject) {
- attr = attrget(server->requests[i].buf + 20, RADLEN(server->requests[i].buf) - 20, RAD_Attr_User_Name);
+ attr = attrget(rq->buf + 20, RADLEN(rq->buf) - 20, RAD_Attr_User_Name);
/* we know the attribute exists */
memcpy(tmp, ATTRVAL(attr), ATTRVALLEN(attr));
tmp[ATTRVALLEN(attr)] = '\0';
switch (*buf) {
case RAD_Access_Accept:
- debug(DBG_INFO, "Access Accept for %s from %s", tmp, server->conf->host);
+ if (rq->origusername)
+ debug(DBG_INFO, "Access Accept for %s (originally %s) from %s", tmp, rq->origusername, server->conf->host);
+ else
+ debug(DBG_INFO, "Access Accept for %s from %s", tmp, server->conf->host);
break;
case RAD_Access_Reject:
- debug(DBG_INFO, "Access Reject for %s from %s", tmp, server->conf->host);
+ if (rq->origusername)
+ debug(DBG_INFO, "Access Reject for %s (originally %s) from %s", tmp, rq->origusername, server->conf->host);
+ else
+ debug(DBG_INFO, "Access Reject for %s from %s", tmp, server->conf->host);
break;
}
}
- /* once we set received = 1, requests[i] may be reused */
- buf[1] = (char)server->requests[i].origid;
- memcpy(buf + 4, server->requests[i].origauth, 16);
+ /* once we set received = 1, rq may be reused */
+ buf[1] = (char)rq->origid;
+ memcpy(buf + 4, rq->origauth, 16);
#ifdef DEBUG
printfchars(NULL, "origauth/buf+4", "%02x ", buf + 4, 16);
#endif
@@ -1647,8 +1676,8 @@ void *clientrd(void *arg) {
}
if (from->conf->type == 'U')
- fromsa = server->requests[i].fromsa;
- server->requests[i].received = 1;
+ fromsa = rq->fromsa;
+ rq->received = 1;
pthread_mutex_unlock(&server->newrq_mutex);
debug(DBG_DBG, "clientrd: giving packet back to where it came from");
@@ -1731,7 +1760,7 @@ void *clientwr(void *arg) {
debug(DBG_DBG, "clientwr: packet %d in queue is marked as received", i);
if (rq->buf) {
debug(DBG_DBG, "clientwr: freeing received packet %d from queue", i);
- free(rq->buf);
+ freerqdata(rq);
/* setting this to NULL means that it can be reused */
rq->buf = NULL;
}
@@ -1755,7 +1784,7 @@ void *clientwr(void *arg) {
if (server->loststatsrv < 255)
server->loststatsrv++;
}
- free(rq->buf);
+ freerqdata(rq);
/* setting this to NULL means that it can be reused */
rq->buf = NULL;
pthread_mutex_unlock(&server->newrq_mutex);
@@ -1851,7 +1880,7 @@ void *udpaccserverrd(void *arg) {
continue;
}
debug(DBG_INFO, "udpaccserverrd: got something other than accounting-request, ignoring");
- free(rq.buf);
+ freerqdata(&rq);
}
}
diff --git a/radsecproxy.h b/radsecproxy.h
index 7332ae4..fb6a564 100644
--- a/radsecproxy.h
+++ b/radsecproxy.h
@@ -57,6 +57,7 @@ struct request {
uint8_t received;
struct timeval expiry;
struct client *from;
+ char *origusername;
uint8_t origid; /* used by servwr */
char origauth[16]; /* used by servwr */
struct sockaddr_storage fromsa; /* used by udpservwr */