summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--radsecproxy.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/radsecproxy.c b/radsecproxy.c
index 6e341c2..293fafb 100644
--- a/radsecproxy.c
+++ b/radsecproxy.c
@@ -768,6 +768,85 @@ unsigned char *radudpget(int s, struct client **client, struct server **server,
return rad;
}
+/* exactly one of client and server must be non-NULL */
+/* should probably take peer list (client(s) or server(s)) as argument instead */
+/* if *peer == NULL we return who we received from, else require it to be from peer */
+/* return from in sa if not NULL */
+unsigned char *radudpget2(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
+ int cnt, len;
+ unsigned char buf[4], *rad;
+ struct sockaddr_storage from;
+ socklen_t fromlen = sizeof(from);
+ struct clsrvconf *p;
+ struct list_node *node;
+
+ for (;;) {
+ cnt = recvfrom(s, buf, 4, MSG_PEEK, (struct sockaddr *)&from, &fromlen);
+ if (cnt == -1) {
+ debug(DBG_WARN, "radudpget: recv failed");
+ continue;
+ }
+
+ if (client)
+ if (*client)
+ p = checkconfaddr(RAD_UDP, (struct sockaddr *)&from, (*client)->conf);
+ else
+ p = find_conf(RAD_UDP, (struct sockaddr *)&from, clconfs, NULL);
+ else
+ if (*server)
+ p = checkconfaddr(RAD_UDP, (struct sockaddr *)&from, (*server)->conf);
+ else
+ p = find_conf(RAD_UDP, (struct sockaddr *)&from, srvconfs, NULL);
+
+ if (!p) {
+ debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from, fromlen));
+ recv(s, buf, 4, 0);
+ continue;
+ }
+
+ len = RADLEN(buf);
+ if (len < 20) {
+ debug(DBG_WARN, "radudpget: length too small");
+ recv(s, buf, 4, 0);
+ continue;
+ }
+
+ rad = malloc(len);
+ if (!rad) {
+ debug(DBG_ERR, "radudpget: malloc failed");
+ recv(s, buf, 4, 0);
+ continue;
+ }
+
+ cnt = recv(s, rad, len, MSG_TRUNC);
+ debug(DBG_DBG, "radudpget: got %d bytes from %s", cnt, addr2string((struct sockaddr *)&from, fromlen));
+
+ if (cnt < len) {
+ debug(DBG_WARN, "radudpget: packet smaller than length field in radius header");
+ free(rad);
+ continue;
+ }
+
+ if (cnt > len)
+ debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len);
+
+ if (client && !*client) {
+ node = list_first(p->clients);
+ *client = node ? (struct client *)node->data : addclient(p);
+ if (!*client) {
+ free(rad);
+ continue;
+ }
+ } else if (server && !*server)
+ *server = p->servers;
+
+ break;
+ }
+ if (sa)
+ *sa = from;
+ return rad;
+}
+
int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) {
int loc, i, l, n, r = 0;
char *v;