1 /* Copyright (c) 2007-2009, UNINETT AS
2  * Copyright (c) 2010-2012,2016, NORDUnet A/S */
3 /* See LICENSE for licensing information. */
4 
5 #include <sys/time.h>
6 #include <stdint.h>
7 #include <pthread.h>
8 #include <regex.h>
9 #include <netinet/in.h>
10 #include "list.h"
11 #include "radmsg.h"
12 #include "gconfig.h"
13 #include "rewrite.h"
14 
15 #define DEBUG_LEVEL 2
16 
17 #define CONFIG_MAIN SYSCONFDIR"/radsecproxy.conf"
18 
19 /* MAX_REQUESTS must be 256 due to Radius' 8 bit ID field */
20 #define MAX_REQUESTS 256
21 #define MAX_LOSTRQS 16
22 #define REQUEST_RETRY_INTERVAL 5
23 #define REQUEST_RETRY_COUNT 2
24 #define DUPLICATE_INTERVAL REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT
25 #define MAX_CERT_DEPTH 5
26 #define STATUS_SERVER_PERIOD 25
27 #define IDLE_TIMEOUT 300
28 
29 /* We want PTHREAD_STACK_SIZE to be 32768, but some platforms
30  * have a higher minimum value defined in PTHREAD_STACK_MIN. */
31 #define PTHREAD_STACK_SIZE 32768
32 #if defined(PTHREAD_STACK_MIN)
33 #if PTHREAD_STACK_MIN > PTHREAD_STACK_SIZE
34 #undef PTHREAD_STACK_SIZE
35 #define PTHREAD_STACK_SIZE PTHREAD_STACK_MIN
36 #endif
37 #endif
38 
39 /* For systems that only support RFC 2292 Socket API, but not RFC 3542
40  * like Cygwin */
41 #ifndef IPV6_RECVPKTINFO
42 #define IPV6_RECVPKTINFO IPV6_PKTINFO
43 #endif
44 
45 /* 27262 is vendor DANTE Ltd. */
46 #define DEFAULT_TTL_ATTR "27262:1"
47 #define DEFAULT_FTICKS_PREFIX "F-TICKS/eduroam/1.0"
48 
49 #define RAD_UDP 0
50 #define RAD_TLS 1
51 #define RAD_TCP 2
52 #define RAD_DTLS 3
53 #define RAD_PROTOCOUNT 4
54 
55 enum rsp_fticks_reporting_type {
56     RSP_FTICKS_REPORTING_NONE = 0, /* Default.  */
57     RSP_FTICKS_REPORTING_BASIC,
58     RSP_FTICKS_REPORTING_FULL
59 };
60 
61 enum rsp_mac_type {
62     RSP_MAC_STATIC = 0,
63     RSP_MAC_ORIGINAL,
64     RSP_MAC_VENDOR_HASHED,
65     RSP_MAC_VENDOR_KEY_HASHED, /* Default.  */
66     RSP_MAC_FULLY_HASHED,
67     RSP_MAC_FULLY_KEY_HASHED
68 };
69 
70 enum rsp_server_state {
71     RSP_SERVER_STATE_STARTUP = 0, /* default */
72     RSP_SERVER_STATE_CONNECTED,
73     RSP_SERVER_STATE_RECONNECTING,
74     RSP_SERVER_STATE_FAILING
75 };
76 
77 enum rsp_statsrv {
78 	RSP_STATSRV_OFF = 0,
79 	RSP_STATSRV_ON,
80 	RSP_STATSRV_MINIMAL,
81 	RSP_STATSRV_AUTO
82 };
83 
84 struct options {
85     char *pidfile;
86     char *logdestination;
87     char *ftickssyslogfacility;
88     char *fticksprefix;
89     char *ttlattr;
90     uint32_t ttlattrtype[2];
91     uint8_t addttl;
92     uint8_t loglevel;
93 	uint8_t logtid;
94 	uint8_t logfullusername;
95     uint8_t loopprevention;
96 	enum rsp_mac_type log_mac;
97 	uint8_t *log_key;
98     enum rsp_fticks_reporting_type fticks_reporting;
99     enum rsp_mac_type fticks_mac;
100     uint8_t *fticks_key;
101     uint8_t ipv4only;
102     uint8_t ipv6only;
103 };
104 
105 struct commonprotoopts {
106     char **listenargs;
107     char *sourcearg;
108 };
109 
110 struct request {
111     struct timeval created;
112     uint32_t refcount;
113 	pthread_mutex_t refmutex;
114     uint8_t *buf, *replybuf;
115     struct radmsg *msg;
116     struct client *from;
117     struct server *to;
118     char *origusername;
119     uint8_t rqid;
120     uint8_t rqauth[16];
121     uint8_t newid;
122     int udpsock; /* only for UDP */
123 };
124 
125 /* requests that our client will send */
126 struct rqout {
127     pthread_mutex_t *lock;
128     struct request *rq;
129     uint8_t tries;
130     struct timeval expiry;
131 };
132 
133 struct gqueue {
134     struct list *entries;
135     pthread_mutex_t mutex;
136     pthread_cond_t cond;
137 };
138 
139 struct clsrvconf {
140     char *name;
141     uint8_t type; /* RAD_UDP/RAD_TLS/RAD_TCP */
142     const struct protodefs *pdef;
143     char **hostsrc;
144     int hostaf;
145     char *portsrc;
146     struct list *hostports;
147     char *confsecret;
148     uint8_t *secret;
149     int secret_len;
150     char *tls;
151     char *matchcertattr;
152     regex_t *certcnregex;
153     regex_t *certuriregex;
154     regex_t *certdnsregex;
155     struct in6_addr certipmatch;
156     int certipmatchaf;
157     char *confrewritein;
158     char *confrewriteout;
159     char *confrewriteusername;
160     struct modattr *rewriteusername;
161     char *dynamiclookupcommand;
162     enum rsp_statsrv statusserver;
163     uint8_t retryinterval;
164     uint8_t retrycount;
165     uint8_t dupinterval;
166     uint8_t certnamecheck;
167     uint8_t addttl;
168     uint8_t keepalive;
169     uint8_t loopprevention;
170     struct rewrite *rewritein;
171     struct rewrite *rewriteout;
172     pthread_mutex_t *lock; /* only used for updating clients so far */
173     struct tls *tlsconf;
174     struct list *clients;
175     struct server *servers;
176     char *fticks_viscountry;
177     char *fticks_visinst;
178 };
179 
180 #include "tlscommon.h"
181 
182 struct client {
183     struct clsrvconf *conf;
184     int sock;
185     SSL *ssl;
186 	pthread_mutex_t lock;
187     struct request *rqs[MAX_REQUESTS];
188     struct gqueue *replyq;
189     struct sockaddr *addr;
190     time_t expiry; /* for udp */
191 };
192 
193 struct server {
194     struct clsrvconf *conf;
195     int sock;
196     SSL *ssl;
197     pthread_mutex_t lock;
198     pthread_t clientth;
199     uint8_t clientrdgone;
200     struct timeval connecttime;
201     struct timeval lastreply;
202     enum rsp_server_state state;
203     uint8_t lostrqs;
204     char *dynamiclookuparg;
205     int nextid;
206     struct timeval lastrcv;
207     struct rqout *requests;
208     uint8_t newrq;
209 	uint8_t conreset;
210     pthread_mutex_t newrq_mutex;
211     pthread_cond_t newrq_cond;
212 };
213 
214 struct realm {
215     char *name;
216     char *message;
217     uint8_t accresp;
218     regex_t regex;
219     uint32_t refcount;
220     pthread_mutex_t refmutex;
221     pthread_mutex_t mutex;
222     struct realm *parent;
223     struct list *subrealms;
224     struct list *srvconfs;
225     struct list *accsrvconfs;
226 };
227 
228 struct protodefs {
229     char *name;
230     char *secretdefault;
231     int socktype;
232     char *portdefault;
233     uint8_t retrycountdefault;
234     uint8_t retrycountmax;
235     uint8_t retryintervaldefault;
236     uint8_t retryintervalmax;
237     uint8_t duplicateintervaldefault;
238     void (*setprotoopts)(struct commonprotoopts *);
239     char **(*getlistenerargs)();
240     void *(*listener)(void*);
241     int (*connecter)(struct server *, int, char *);
242     void *(*clientconnreader)(void*);
243     int (*clientradput)(struct server *, unsigned char *);
244     void (*addclient)(struct client *);
245     void (*addserverextra)(struct clsrvconf *);
246     void (*setsrcres)();
247     void (*initextra)();
248 };
249 
250 #define RADLEN(x) ntohs(((uint16_t *)(x))[1])
251 
252 struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
253 struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
254 struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur);
255 struct client *addclient(struct clsrvconf *conf, uint8_t lock);
256 void removelockedclient(struct client *client);
257 void removeclient(struct client *client);
258 struct gqueue *newqueue();
259 struct request *newrequest();
260 void freerq(struct request *rq);
261 int radsrv(struct request *rq);
262 void replyh(struct server *server, unsigned char *buf);
263 struct addrinfo *resolve_hostport_addrinfo(uint8_t type, char *hostport);
264 uint8_t *radattr2ascii(struct tlv *attr); /* TODO: mv this to radmsg? */
265 extern pthread_attr_t pthread_attr;
266 
267 /* Local Variables: */
268 /* c-file-style: "stroustrup" */
269 /* End: */
270