#include "../lib/hmac.h"
static prngctx rng;
-static sstring *secret, *codesecret;
+static sstring *secret, *codesecret, *ticketsecret;
static sstring *combinesecret(char *str) {
SHA256_CTX ctx;
if(!secret || !secret->content || !secret->content[0]) {
unsigned char buf[32];
char hexbuf[sizeof(buf) * 2 + 1];
-
+ freesstring(secret);
Error("chanserv",ERR_WARNING,"Shared secret not set, generating a random string...");
cs_getrandbytes(buf, 32);
secret=getsstring(hexbuf, strlen(hexbuf));
}
codesecret=combinesecret("codegenerator");
+
+ ticketsecret=getcopyconfigitem("chanserv","ticketsecret","",256);
+ if(!ticketsecret || !ticketsecret->content || !ticketsecret->content[0]) {
+ Error("chanserv",ERR_WARNING,"Ticket secret not set, ticketauth disabled.");
+ freesstring(ticketsecret);
+ ticketsecret = NULL;
+ }
}
void chanservcryptofree(void) {
freesstring(secret);
freesstring(codesecret);
+ freesstring(ticketsecret);
}
ub4 cs_getrandint(void) {
}
const char *cs_cralgorithmlist(void) {
- return "HMAC-MD5 HMAC-SHA-1 HMAC-SHA-256";
+ return "HMAC-MD5 HMAC-SHA-1 HMAC-SHA-256 LEGACY-MD5";
}
int crsha1(char *username, const char *password, const char *challenge, const char *response) {
hmac_printhex(digest, hexbuf, sizeof(digest));
- if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+ if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
return 1;
return 0;
hmacsha256_update(&hmac, (unsigned char *)challenge, strlen(challenge));
hmacsha256_final(&hmac, digest);
- if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+ if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
return 1;
return 0;
hmacmd5_update(&hmac, (unsigned char *)challenge, strlen(challenge));
hmacmd5_final(&hmac, digest);
- if(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+ if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+ return 1;
+
+ return 0;
+}
+
+int crlegacymd5(char *username, const char *password, const char *challenge, const char *response) {
+ MD5Context ctx;
+ unsigned char digest[16];
+ char hexbuf[sizeof(digest) * 2 + 1];
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, (unsigned char *)password, strlen(password));
+ MD5Update(&ctx, (unsigned char *)" ", 1);
+ MD5Update(&ctx, (unsigned char *)challenge, strlen(challenge));
+ MD5Final(digest, &ctx);
+
+ if(!hmac_strcmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
return 1;
return 0;
if(!strcasecmp(algorithm, "hmac-md5"))
return crmd5;
+ if(!strcasecmp(algorithm, "legacy-md5"))
+ return crlegacymd5;
+
return 0;
}
SHA1Update(&ctx, entropy, ENTROPYLEN);
SHA1Final(buf, &ctx);
- hmac_printhex(buf, hexbuf, sizeof(buf));
+ hmac_printhex(buf, hexbuf, 16);
return hexbuf;
}
MD5Update(&ctx, (unsigned char *)buf, strlen(buf));
MD5Final(digest, &ctx);
- if(strcasecmp(hash, hmac_printhex(digest, hexbuf, sizeof(digest))))
+ if(hmac_strcmp(hash, hmac_printhex(digest, hexbuf, sizeof(digest))))
return 0;
return 1;
return hexbuf;
}
+
+int csc_verifyqticket(char *data, char *digest) {
+ hmacsha256 hmac;
+ unsigned char digestbuf[32];
+ char hexbuf[sizeof(digestbuf) * 2 + 1];
+
+ if(!ticketsecret)
+ return -1;
+
+ hmacsha256_init(&hmac, (unsigned char *)ticketsecret->content, ticketsecret->length);
+ hmacsha256_update(&hmac, (unsigned char *)data, strlen(data));
+ hmacsha256_final(&hmac, digestbuf);
+
+ hmac_printhex(digestbuf, hexbuf, sizeof(digestbuf));
+
+ if(!hmac_strcmp(hexbuf, digest))
+ return 0;
+
+ return 1;
+}