#include <stdio.h>
+#include <strings.h>
#include "chanserv.h"
#include "../core/error.h"
+#include "../core/config.h"
#include "../lib/prng.h"
#include "../lib/sha1.h"
#include "../lib/sha2.h"
#include "../lib/md5.h"
#include "../lib/hmac.h"
-prngctx rng;
+static prngctx rng;
+static sstring *secret, *codesecret, *ticketsecret;
+static sstring *combinesecret(char *str) {
+ SHA256_CTX ctx;
+ unsigned char digest[32];
+ char hexbuf[sizeof(digest) * 2 + 1];
+
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, (unsigned char *)secret->content, secret->length);
+ SHA256_Update(&ctx, (unsigned char *)":", 1);
+ SHA256_Update(&ctx, (unsigned char *)str, strlen(str));
+ SHA256_Final(digest, &ctx);
+
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, digest, sizeof(digest));
+ SHA256_Final(digest, &ctx);
+ hmac_printhex(digest, hexbuf, sizeof(digest));
+
+ return getsstring(hexbuf, strlen(hexbuf));
+}
+
void chanservcryptoinit(void) {
int ret;
}
prnginit(&rng, 1);
+
+ secret=getcopyconfigitem("chanserv","secret","",128);
+ 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);
+ hmac_printhex(buf, hexbuf, sizeof(buf));
+ 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) {
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(!strcasecmp(hmac_printhex(digest, hexbuf, sizeof(digest)), response))
+ return 1;
+
+ return 0;
+}
+
CRAlgorithm cs_cralgorithm(const char *algorithm) {
if(!strcasecmp(algorithm, "hmac-sha-1"))
return crsha1;
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;
}
return 1;
}
+
+char *csc_generateresetcode(time_t lockuntil, char *username) {
+ unsigned char digest[32];
+ static char hexbuf[sizeof(digest) * 2 + 1];
+ hmacsha256 hmac;
+ SHA256_CTX ctx;
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%s:%lu", username, lockuntil);
+
+ SHA256_Init(&ctx);
+ SHA256_Update(&ctx, (unsigned char *)buf, strlen(buf));
+ SHA256_Final(digest, &ctx);
+
+ hmac_printhex(digest, hexbuf, sizeof(digest));
+
+ hmacsha256_init(&hmac, (unsigned char *)codesecret->content, codesecret->length);
+ hmacsha256_update(&hmac, (unsigned char *)hexbuf, strlen(hexbuf));
+ hmacsha256_final(&hmac, digest);
+
+ hmac_printhex(digest, hexbuf, sizeof(digest));
+
+ 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(!strcasecmp(hexbuf, digest))
+ return 0;
+
+ return 1;
+}