]> jfr.im git - irc/quakenet/newserv.git/blobdiff - chanserv/chanservcrypto.c
fix indentation
[irc/quakenet/newserv.git] / chanserv / chanservcrypto.c
index 80561f863046d7cc44c3d3077a3fc8f2d741e2e9..7906f8c7ca7eeac13e8c483adc2ebde72233dd83 100644 (file)
@@ -1,15 +1,37 @@
 #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;
 
+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;
 
@@ -28,6 +50,25 @@ void chanservcryptoinit(void) {
   }
 
   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");
+}
+
+
+void chanservcryptofree(void) {
+  freesstring(secret);
+  freesstring(codesecret);
 }
 
 ub4 cs_getrandint(void) {
@@ -42,7 +83,7 @@ void cs_getrandbytes(unsigned char *buf, size_t bytes) {
 }
 
 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) {
@@ -134,6 +175,23 @@ int crmd5(char *username, const char *password, const char *challenge, const cha
   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;
@@ -144,6 +202,9 @@ CRAlgorithm cs_cralgorithm(const char *algorithm) {
   if(!strcasecmp(algorithm, "hmac-md5"))
     return crmd5;
 
+  if(!strcasecmp(algorithm, "legacy-md5"))
+    return crlegacymd5;
+
   return 0;
 }
 
@@ -157,7 +218,7 @@ char *cs_calcchallenge(const unsigned char *entropy) {
   SHA1Update(&ctx, entropy, ENTROPYLEN);
   SHA1Final(buf, &ctx);
 
-  hmac_printhex(buf, hexbuf, sizeof(buf));
+  hmac_printhex(buf, hexbuf, 16);
 
   return hexbuf;
 }
@@ -178,3 +239,27 @@ int cs_checkhashpass(const char *username, const char *password, const char *jun
 
   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;
+}