]> code.citadel.org Git - citadel.git/commitdiff
dkim: create key and selector if absent
authorArt Cancro <ajc@citadel.org>
Tue, 14 May 2024 05:02:40 +0000 (05:02 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 14 May 2024 05:02:40 +0000 (05:02 +0000)
citadel/server/modules/smtp/dkim.c
citadel/server/modules/smtp/serv_smtpclient.c
citadel/server/modules/smtp/smtp_util.h

index 639c5086d9901be425450ab576f16fe3d9d11a11..c187916c3f09741ac22e70d3bcc83ded7bce0177 100644 (file)
@@ -29,6 +29,7 @@
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <libcitadel.h>
+#include "../../config.h"
 
 
 // This utility function is used by the body canonicalizer
@@ -545,3 +546,63 @@ void dkim_sign(StrBuf *email, char *pkey_in, char *domain, char *selector) {
 
        // And we're done!
 }
+
+
+// Generate a private key and selector for DKIM if needed.  This is called during server startup.
+void dkim_init(void) {
+
+       char *dkim_private_key = CtdlGetConfigStr("dkim_private_key");
+       if (dkim_private_key) {
+               syslog(LOG_DEBUG, "dkim: private key exists and will continue to be used.");
+       }
+       else {
+               EVP_PKEY_CTX *ctx;
+               EVP_PKEY *pkey = NULL;  
+               BIO *bio = NULL;
+               ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+               if (ctx) {
+                       if (
+                               (EVP_PKEY_keygen_init(ctx) == 1)
+                               && (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) == 1)
+                               && (EVP_PKEY_keygen(ctx, &pkey) == 1)
+                       ) {
+                               syslog(LOG_DEBUG, "dkim: generated private key");
+                               bio = BIO_new(BIO_s_mem());
+                               if (bio) {
+                                       PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL);
+                                       char *b64key = malloc(4096);
+                                       if (b64key) {
+                                               size_t readbytes;
+                                               BIO_read_ex(bio, b64key, 4096, &readbytes);
+                                               b64key[readbytes] = 0;
+                                               char *nl = NULL;
+                                               while (nl=strchr(b64key, '\n'), nl) {           // convert newlines to underscores
+                                                       *nl = '_';
+                                               }
+                                               CtdlSetConfigStr("dkim_private_key", b64key);
+                                               free(b64key);
+                                       }
+                                       free(bio);
+                               }
+                       }
+                       EVP_PKEY_CTX_free(ctx);
+               }
+       }
+
+       char *dkim_selector = CtdlGetConfigStr("dkim_selector");
+       if (dkim_selector) {
+               syslog(LOG_DEBUG, "dkim: selector exists: %s", dkim_selector);
+       }
+       else {
+               // Quick and dirty algorithm to make up a five letter nonsense word as a selector
+               char new_selector[6];
+               int i;
+               for (i=0; i<5; ++i) {
+                       new_selector[i] = (rand() % 26) + 'a';
+               }
+               new_selector[5] = 0;
+               syslog(LOG_DEBUG, "dkim: selector created: %s", new_selector);
+               CtdlSetConfigStr("dkim_selector", new_selector);
+       }
+       abort();
+}
index 7247fb19e5b09153c444c05579e3dfba01db2112..3332cf4a5ce6555d43d923ca824a644be1e32096 100644 (file)
@@ -605,6 +605,7 @@ char *ctdl_module_init_smtpclient(void) {
                CtdlRegisterSessionHook(smtp_do_queue_quick, EVT_HOUSE, PRIO_AGGR + 51);
                CtdlRegisterSessionHook(smtp_do_queue_full, EVT_TIMER, PRIO_AGGR + 51);
                smtp_init_spoolout();
+               dkim_init();
        }
 
        // return our module id for the log
index 1a4e17162076fbade021b5567b0be6f4836db72d..4975934066ee82ea616d30e78fdde1790ca287bf 100644 (file)
@@ -30,3 +30,4 @@ enum {
 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);