1 /* Copyright (C) 2011 NORDUnet A/S
2 * See LICENSE for information about licensing.
5 #include <stdio.h> /* For sprintf(). */
7 #include <nettle/sha.h>
8 #include <nettle/hmac.h>
14 #include "radsecproxy.h"
20 format_hash(const uint8_t *hash, size_t out_len, uint8_t *out)
24 for (i = 0; i < out_len / 2 - 1; i++)
25 sprintf((char *) out + i*2, "%02x", hash[i % SHA256_DIGEST_SIZE]);
29 hash(const uint8_t *in,
35 struct sha256_ctx ctx;
36 uint8_t hash[SHA256_DIGEST_SIZE];
39 sha256_update(&ctx, strlen((char *) in), in);
40 sha256_digest(&ctx, sizeof(hash), hash);
41 format_hash(hash, out_len, out);
44 struct hmac_sha256_ctx ctx;
45 uint8_t hash[SHA256_DIGEST_SIZE];
47 hmac_sha256_set_key(&ctx, strlen((char *) key), key);
48 hmac_sha256_update(&ctx, strlen((char *) in), in);
49 hmac_sha256_digest(&ctx, sizeof(hash), hash);
50 format_hash(hash, out_len, out);
55 fticks_configure(struct options *options,
61 const char *reporting = (const char *) *reportingp;
62 const char *mac = (const char *) *macp;
64 if (reporting == NULL)
67 if (strcasecmp(reporting, "None") == 0)
68 options->fticks_reporting = RSP_FTICKS_REPORTING_NONE;
69 else if (strcasecmp(reporting, "Basic") == 0)
70 options->fticks_reporting = RSP_FTICKS_REPORTING_BASIC;
71 else if (strcasecmp(reporting, "Full") == 0)
72 options->fticks_reporting = RSP_FTICKS_REPORTING_FULL;
74 debugx(1, DBG_ERR, "config error: invalid FTicksReporting value: %s",
80 if (strcasecmp(mac, "Static") == 0)
81 options->fticks_mac = RSP_FTICKS_MAC_STATIC;
82 else if (strcasecmp(mac, "Original") == 0)
83 options->fticks_mac = RSP_FTICKS_MAC_ORIGINAL;
84 else if (strcasecmp(mac, "VendorHashed") == 0)
85 options->fticks_mac = RSP_FTICKS_MAC_VENDOR_HASHED;
86 else if (strcasecmp(mac, "VendorKeyHashed") == 0)
87 options->fticks_mac = RSP_FTICKS_MAC_VENDOR_KEY_HASHED;
88 else if (strcasecmp(mac, "FullyHashed") == 0)
89 options->fticks_mac = RSP_FTICKS_MAC_FULLY_HASHED;
90 else if (strcasecmp(mac, "FullyKeyHashed") == 0)
91 options->fticks_mac = RSP_FTICKS_MAC_FULLY_KEY_HASHED;
93 debugx(1, DBG_ERR, "config error: invalid FTicksMAC value: %s", mac);
99 && (options->fticks_mac == RSP_FTICKS_MAC_VENDOR_KEY_HASHED
100 || options->fticks_mac == RSP_FTICKS_MAC_FULLY_KEY_HASHED)) {
102 "config error: FTicksMAC %s requires an FTicksKey", mac);
103 options->fticks_mac = RSP_FTICKS_MAC_STATIC;
109 options->fticks_key = *keyp;
112 if (*reportingp != NULL) {
123 /** Hash the MAC in \a IN, keying with \a KEY if it's not NULL.
125 \a IN and \a KEY are NULL terminated strings.
127 \a IN is sanitised by lowercasing it, removing all but [0-9a-f]
128 and truncating it at first ';' (due to RADIUS praxis with tacking
129 on SSID to MAC in Calling-Station-Id). */
131 fticks_hashmac(const uint8_t *in,
136 /* TODO: lowercase */
137 /* TODO: s/[!0-9a-f]//1 */
138 /* TODO: truncate after first ';', if any */
140 hash(in, key, out_len, out);
144 fticks_log(const struct options *options,
145 const struct client *client,
146 const struct radmsg *msg,
147 const struct rqout *rqout)
149 uint8_t *username = NULL;
150 uint8_t *realm = NULL;
151 uint8_t visinst[8+40+1+1]; /* Room for 40 octets of VISINST. */
152 uint8_t *macin = NULL;
153 uint8_t macout[2*32+1]; /* Room for ASCII representation of SHA256. */
155 username = radattr2ascii(radmsg_gettype(rqout->rq->msg,
156 RAD_Attr_User_Name));
157 if (username != NULL) {
158 realm = (uint8_t *) strrchr((char *) username, '@');
163 realm = (uint8_t *) "";
165 memset(visinst, 0, sizeof(visinst));
166 if (options->fticks_reporting == RSP_FTICKS_REPORTING_FULL) {
167 snprintf((char *) visinst, sizeof(visinst), "VISINST=%s#",
171 memset(macout, 0, sizeof(macout));
172 if (options->fticks_mac == RSP_FTICKS_MAC_STATIC) {
173 strncpy((char *) macout, "undisclosed", sizeof(macout) - 1);
176 macin = radattr2ascii(radmsg_gettype(rqout->rq->msg,
177 RAD_Attr_Calling_Station_Id));
179 switch (options->fticks_mac)
181 case RSP_FTICKS_MAC_ORIGINAL:
182 memcpy(macout, macin, sizeof(macout));
184 case RSP_FTICKS_MAC_VENDOR_HASHED:
185 memcpy(macout, macin, 9);
186 fticks_hashmac(macin + 9, NULL, sizeof(macout) - 9, macout + 9);
188 case RSP_FTICKS_MAC_VENDOR_KEY_HASHED:
189 memcpy(macout, macin, 9);
190 fticks_hashmac(macin + 9, options->fticks_key,
191 sizeof(macout) - 9, macout + 9);
193 case RSP_FTICKS_MAC_FULLY_HASHED:
194 fticks_hashmac(macin, NULL, sizeof(macout), macout);
196 case RSP_FTICKS_MAC_FULLY_KEY_HASHED:
197 fticks_hashmac(macin, options->fticks_key, sizeof(macout),
201 debugx(2, DBG_ERR, "invalid fticks mac configuration: %d",
202 options->fticks_mac);
207 "F-TICKS/eduroam/1.0#REALM=%s#VISCOUNTRY=%s#%sCSI=%s#RESULT=%s#",
209 client->conf->fticks_viscountry,
212 msg->code == RAD_Access_Accept ? "OK" : "FAIL");
215 if (username != NULL)
219 /* Local Variables: */
220 /* c-file-style: "stroustrup" */