]> code.citadel.org Git - citadel.git/commitdiff
begin config hash message
authorArt Cancro <ajc@citadel.org>
Tue, 14 May 2024 21:58:59 +0000 (14:58 -0700)
committerArt Cancro <ajc@citadel.org>
Tue, 14 May 2024 21:58:59 +0000 (14:58 -0700)
citadel/server/modules/inetcfg/serv_inetcfg.c
citadel/server/modules/smtp/dkim.c
citadel/server/modules/smtp/smtp_util.h

index 19e5fd9f4eff5be15ec26db09dd32a8d5d9d40cd..e7e9ebdb559118e10d92db2153e9f7f5d5d4deab 100644 (file)
 #include "../../genstamp.h"
 #include "../../domain.h"
 #include "../../ctdl_module.h"
+#include "../smtp/smtp_util.h"
 
 
 void inetcfg_setTo(struct CtdlMessage *msg) {
        char *conf;
        char buf[SIZ];
-       
+
        if (CM_IsEmpty(msg, eMessageText)) return;
        conf = strdup(msg->cm_fields[eMessageText]);
 
@@ -51,6 +52,7 @@ void inetcfg_setTo(struct CtdlMessage *msg) {
 
                if (inetcfg != NULL) free(inetcfg);
                inetcfg = conf;
+               dkim_check_advisory();                  // this will check to see if we have to advise the admin about dkim
        }
 }
 
index 96f4d03ebb35e3bcabe63edfe3690f228bd553e6..beb1681e2f4276bc770ce37124b739c45a459c75 100644 (file)
@@ -30,6 +30,7 @@
 #include <openssl/evp.h>
 #include <libcitadel.h>
 #include "../../config.h"
+#include "../../internet_addressing.h"
 
 
 // This utility function is used by the body canonicalizer
@@ -390,7 +391,7 @@ void dkim_sign(StrBuf *email, char *pkey_in, char *domain, char *selector) {
 
        // hash of the canonicalized body
        unsigned char *body_hash = malloc(SHA256_DIGEST_LENGTH);
-       SHA256((unsigned char*)relaxed_body, relaxed_body_len, body_hash);
+       SHA256((unsigned char *)relaxed_body, relaxed_body_len, body_hash);
        free(relaxed_body);                                                     // all we need now is the hash
        relaxed_body = NULL;
 
@@ -605,3 +606,82 @@ void dkim_init(void) {
                CtdlSetConfigStr("dkim_selector", new_selector);
        }
 }
+
+
+// If the DKIM key, DKIM selector, or set of signing domains has changed, we need to tell the administrator about it.
+void dkim_check_advisory(void) {
+
+       // If there is no DKIM ... there is nothing to discuss
+       if (IsEmptyStr(CtdlGetConfigStr("dkim_private_key"))) return;
+       if (IsEmptyStr(CtdlGetConfigStr("dkim_selector"))) return;
+
+       // We're going to build a hash of the private key, the selector, and all signing domains.
+       // The way we build it doesn't matter, and it doesn't even have to be secure.
+       // This is just to let us know that we have to post an update to the administrator if the hash changes.
+
+       StrBuf *hashsrc = NewStrBuf();
+       if (!hashsrc) {
+               return;
+       }
+
+       StrBufAppendBufPlain(hashsrc, CtdlGetConfigStr("dkim_private_key"), strlen(CtdlGetConfigStr("dkim_private_key")), 0);
+       StrBufAppendBufPlain(hashsrc, CtdlGetConfigStr("dkim_selector"), strlen(CtdlGetConfigStr("dkim_selector")), 0);
+
+       char *ptr = inetcfg;
+       while (ptr && *ptr) {
+               char *sep = strchr(ptr, '|');
+               if (sep && !strncasecmp(sep+1, HKEY("localhost"))) {
+                       StrBufAppendBufPlain(hashsrc, ptr, sep-ptr, 0);
+               }
+               ptr = strchr(ptr, '\n');
+               if (ptr) ++ptr;
+       }
+
+       // make a hash from the string...
+       unsigned char *config_hash = malloc(SHA256_DIGEST_LENGTH);
+       SHA256((unsigned char *)ChrPtr(hashsrc), StrLength(hashsrc), config_hash);
+       FreeStrBuf(&hashsrc);
+
+       // base64 encode it...
+       char *encoded_config_hash = malloc(SHA256_DIGEST_LENGTH * 2);
+       CtdlEncodeBase64(encoded_config_hash, config_hash, SHA256_DIGEST_LENGTH, BASE64_NO_LINEBREAKS);
+       free(config_hash);                                                      // all we need now is the encoded hash
+
+       // Does it match the saved hash?
+       if (    (IsEmptyStr(CtdlGetConfigStr("dkim_config_hash")))
+               || (strcmp(encoded_config_hash, CtdlGetConfigStr("dkim_config_hash")))
+       ) {
+               // No?  Post an Aide notification.
+               StrBuf *message = NewStrBuf();
+               StrBufAppendPrintf(message, "%s",
+                       " \n"
+                       " Your domain configuration may have changed.\n"
+                       " To allow the DKIM signatures of outbound mail to be verified, "
+                       "please ensure that the following DNS records are created:\n"
+                       " \n"
+               );
+
+               ptr = inetcfg;
+               while (ptr && *ptr) {
+                       char *sep = strchr(ptr, '|');
+                       if (sep && !strncasecmp(sep+1, HKEY("localhost"))) {
+                               StrBufAppendPrintf(message, " Record name : %s._domainkey.%s\n",
+                                       CtdlGetConfigStr("dkim_selector"),
+                                       "fixme.FIXME.com"
+                               );
+                               StrBufAppendPrintf(message, " Record type : TXT\n");
+                               StrBufAppendPrintf(message, " Record value: c=dkim1 etc. etc. etc.\n");
+                               StrBufAppendPrintf(message, " \n");
+                       }
+                       ptr = strchr(ptr, '\n');
+                       if (ptr) ++ptr;
+               }
+
+               CtdlAideMessage(ChrPtr(message), "DKIM records");
+               FreeStrBuf(&message);
+       }
+
+       // Save it to the config database so we don't do this except when it changes.
+       CtdlSetConfigStr("dkim_config_hash", encoded_config_hash);
+       free(encoded_config_hash);
+}
index 4975934066ee82ea616d30e78fdde1790ca287bf..8f30226435abb1c98e9bcde774835a23ca5a3c33 100644 (file)
@@ -31,3 +31,4 @@ void smtp_do_bounce(const char *instr, int is_final);
 char *smtpstatus(int code);
 void dkim_sign(StrBuf *email, char *pkey_in, char *domain, char *selector);
 void dkim_init(void);
+void dkim_check_advisory(void);