radsecproxy-1.6.5.
[libradsec.git] / fticks.c
1 /* Copyright (C) 2011 NORDUnet A/S
2  * See LICENSE for information about licensing.
3  */
4
5 #include "radsecproxy.h"
6 #include "debug.h"
7 #include "fticks.h"
8 #include "fticks_hashmac.h"
9
10 int
11 fticks_configure(struct options *options,
12                  uint8_t **reportingp,
13                  uint8_t **macp,
14                  uint8_t **keyp)
15 {
16     int r = 0;
17     const char *reporting = (const char *) *reportingp;
18     const char *mac = (const char *) *macp;
19
20     /* Set defaults.  */
21     options->fticks_reporting = RSP_FTICKS_REPORTING_NONE;
22     options->fticks_mac = RSP_FTICKS_MAC_VENDOR_KEY_HASHED;
23
24     if (reporting != NULL) {
25         if (strcasecmp(reporting, "None") == 0)
26             options->fticks_reporting = RSP_FTICKS_REPORTING_NONE;
27         else if (strcasecmp(reporting, "Basic") == 0)
28             options->fticks_reporting = RSP_FTICKS_REPORTING_BASIC;
29         else if (strcasecmp(reporting, "Full") == 0)
30             options->fticks_reporting = RSP_FTICKS_REPORTING_FULL;
31         else {
32             debugx(1, DBG_ERR,
33                    "config error: invalid FTicksReporting value: %s",
34                    reporting);
35             r = 1;
36         }
37     }
38
39     if (mac != NULL) {
40         if (strcasecmp(mac, "Static") == 0)
41             options->fticks_mac = RSP_FTICKS_MAC_STATIC;
42         else if (strcasecmp(mac, "Original") == 0)
43             options->fticks_mac = RSP_FTICKS_MAC_ORIGINAL;
44         else if (strcasecmp(mac, "VendorHashed") == 0)
45             options->fticks_mac = RSP_FTICKS_MAC_VENDOR_HASHED;
46         else if (strcasecmp(mac, "VendorKeyHashed") == 0)
47             options->fticks_mac = RSP_FTICKS_MAC_VENDOR_KEY_HASHED;
48         else if (strcasecmp(mac, "FullyHashed") == 0)
49             options->fticks_mac = RSP_FTICKS_MAC_FULLY_HASHED;
50         else if (strcasecmp(mac, "FullyKeyHashed") == 0)
51             options->fticks_mac = RSP_FTICKS_MAC_FULLY_KEY_HASHED;
52         else {
53             debugx(1, DBG_ERR,
54                    "config error: invalid FTicksMAC value: %s", mac);
55             r = 1;
56         }
57     }
58
59     if (*keyp != NULL) {
60         options->fticks_key = *keyp;
61         if (options->fticks_mac != RSP_FTICKS_MAC_VENDOR_KEY_HASHED
62             && options->fticks_mac != RSP_FTICKS_MAC_FULLY_KEY_HASHED)
63             debugx(1, DBG_WARN, "config warning: FTicksKey not used");
64     }
65     else if (options->fticks_reporting != RSP_FTICKS_REPORTING_NONE
66              && (options->fticks_mac == RSP_FTICKS_MAC_VENDOR_KEY_HASHED
67                  || options->fticks_mac == RSP_FTICKS_MAC_FULLY_KEY_HASHED)) {
68         debugx(1, DBG_ERR,
69                "config error: FTicksMAC values VendorKeyHashed and "
70                "FullyKeyHashed require an FTicksKey");
71         options->fticks_reporting = RSP_FTICKS_REPORTING_NONE;
72         r = 1;
73     }
74
75     if (*reportingp != NULL) {
76         free(*reportingp);
77         *reportingp = NULL;
78     }
79     if (*macp != NULL) {
80         free(*macp);
81         *macp = NULL;
82     }
83     return r;
84 }
85
86 void
87 fticks_log(const struct options *options,
88            const struct client *client,
89            const struct radmsg *msg,
90            const struct rqout *rqout)
91 {
92     uint8_t *username = NULL;
93     uint8_t *realm = NULL;
94     uint8_t visinst[8+40+1+1]; /* Room for 40 octets of VISINST.  */
95     uint8_t *macin = NULL;
96     uint8_t macout[2*32+1]; /* Room for ASCII representation of SHA256.  */
97
98     username = radattr2ascii(radmsg_gettype(rqout->rq->msg,
99                                             RAD_Attr_User_Name));
100     if (username != NULL) {
101         realm = (uint8_t *) strrchr((char *) username, '@');
102         if (realm != NULL)
103             realm++;
104     }
105     if (realm == NULL)
106         realm = (uint8_t *) "";
107
108     memset(visinst, 0, sizeof(visinst));
109     if (options->fticks_reporting == RSP_FTICKS_REPORTING_FULL) {
110         if (client->conf->fticks_visinst != NULL ) {
111             snprintf((char *) visinst, sizeof(visinst), "VISINST=%s#",
112                      client->conf->fticks_visinst);
113         } else {
114             snprintf((char *) visinst, sizeof(visinst), "VISINST=%s#",
115                      client->conf->name);
116         }
117     }
118
119     memset(macout, 0, sizeof(macout));
120     if (options->fticks_mac == RSP_FTICKS_MAC_STATIC) {
121         strncpy((char *) macout, "undisclosed", sizeof(macout) - 1);
122     }
123     else {
124         macin = radattr2ascii(radmsg_gettype(rqout->rq->msg,
125                                              RAD_Attr_Calling_Station_Id));
126         if (macin) {
127             switch (options->fticks_mac)
128             {
129             case RSP_FTICKS_MAC_ORIGINAL:
130                 memcpy(macout, macin, sizeof(macout));
131                 break;
132             case RSP_FTICKS_MAC_VENDOR_HASHED:
133                 memcpy(macout, macin, 9);
134                 fticks_hashmac(macin, NULL, sizeof(macout) - 9, macout + 9);
135                 break;
136             case RSP_FTICKS_MAC_VENDOR_KEY_HASHED:
137                 memcpy(macout, macin, 9);
138                 /* We are hashing the first nine octets too for easier
139                  * correlation between vendor-key-hashed and
140                  * fully-key-hashed log records.  This opens up for a
141                  * known plaintext attack on the key but the
142                  * consequences of that is considered outweighed by
143                  * the convenience gained.  */
144                 fticks_hashmac(macin, options->fticks_key,
145                                sizeof(macout) - 9, macout + 9);
146                 break;
147             case RSP_FTICKS_MAC_FULLY_HASHED:
148                 fticks_hashmac(macin, NULL, sizeof(macout), macout);
149                 break;
150             case RSP_FTICKS_MAC_FULLY_KEY_HASHED:
151                 fticks_hashmac(macin, options->fticks_key, sizeof(macout),
152                                macout);
153                 break;
154             default:
155                 debugx(2, DBG_ERR, "invalid fticks mac configuration: %d",
156                        options->fticks_mac);
157             }
158         }
159     }
160     fticks_debug(
161           "F-TICKS/eduroam/1.0#REALM=%s#VISCOUNTRY=%s#%sCSI=%s#RESULT=%s#",
162           realm,
163           client->conf->fticks_viscountry,
164           visinst,
165           macout,
166           msg->code == RAD_Access_Accept ? "OK" : "FAIL");
167     if (macin != NULL)
168         free(macin);
169     if (username != NULL)
170         free(username);
171 }
172
173 /* Local Variables: */
174 /* c-file-style: "stroustrup" */
175 /* End: */