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