Fix bug in ctdlload import of email addresses. master
authorArt Cancro <ajc@citadel.org>
Wed, 15 May 2024 19:37:05 +0000 (19:37 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 15 May 2024 19:37:05 +0000 (19:37 +0000)
Go figure.  A base64-encoded string sometimes doesn't include the null terminator.
Fixed that.

citadel/server/modules/smtp/dkim.c
citadel/server/modules/smtp/dkim_bindings.c
citadel/tests/dkimtester/dkimtester.c
citadel/utils/ctdlload.c

index f2a5d9d25aa8cdd0d2d9c6b4bec4d2751c90e0cb..4099e0ea6ffcea371426b00533ae84be2bcfb34f 100644 (file)
@@ -379,7 +379,7 @@ EVP_PKEY *dkim_import_key(char *pkey_in) {
        }
 
        // Load the private key into an OpenSSL "BIO" structure
-       BIO *bufio = BIO_new_mem_buf((void*)pkey_with_newlines, strlen(pkey_with_newlines));
+       BIO *bufio = BIO_new_mem_buf((void *)pkey_with_newlines, strlen(pkey_with_newlines));
        if (bufio == NULL) {
                syslog(LOG_ERR, "dkim: BIO_new_mem_buf() failed");
                free(pkey_with_newlines);
@@ -399,7 +399,7 @@ EVP_PKEY *dkim_import_key(char *pkey_in) {
        BIO_free(bufio);
 
        if (pkey == NULL) {
-               syslog(LOG_ERR, "dkim: PEM_read_bio_PrivateKey() failed");
+               syslog(LOG_ERR, "dkim: PEM_read_bio_PrivateKey() failed with error 0x%lx", ERR_get_error());
        }
 
        return(pkey);
index e762ecf65173394230954264b984fc730fd8dec5..e7491c15468c52da4897802eb747e822fc47d505 100644 (file)
@@ -137,8 +137,8 @@ void dkim_check_advisory(char *inetcfg_in) {
                StrBuf *message = NewStrBuf();
                StrBufAppendBufPlain(message, HKEY(
                        "Content-type: text/plain\r\n"
-                       "\r\n"
-                       "Your domain configuration may have changed.\r\n"
+                       "\r\n\r\n"
+                       "Your domain configuration may have changed.\r\n\r\n"
                        "To allow the DKIM signatures of outbound mail to be verified,\r\n"
                        "please ensure that the following DNS records are created:\r\n"
                        "\r\n"
@@ -154,11 +154,14 @@ void dkim_check_advisory(char *inetcfg_in) {
                                StrBufAppendPrintf(message, "Record type: TXT\r\n");
                                StrBufAppendBufPlain(message, HKEY("Value      : v=DKIM1;k=rsa;p="), 0);
 
-                               // figure out the public key and get it
+                               // FIXME calculate the public key and add it here
 
-                               StrBufAppendPrintf(message, "\r\n");
+                               StrBufAppendPrintf(message, "\r\n\r\n");
+                       }
+                       ptr = strchr(ptr, '\n');
+                       if (ptr) {
+                               ++ptr;
                        }
-                       if (ptr) ++ptr;
                }
 
                quickie_message("Citadel",
@@ -167,7 +170,7 @@ void dkim_check_advisory(char *inetcfg_in) {
                        AIDEROOM,                       // room
                        ChrPtr(message),                // text
                        FMT_RFC822,                     // format
-                       "DKIM records"                  // subject
+                       "Confirm your DKIM records"     // subject
                );
                FreeStrBuf(&message);
        }
index 271a93f81f6241d4af2fd38d0936b94b6d2f3ee3..4a4bf33912ee74b290824085a54825ef8a903ea8 100644 (file)
@@ -15,7 +15,7 @@ int main(int argc, char *argv[]) {
        fprintf(stderr,
                "\033[44m\033[1m╔════════════════════════════════════════════════════════════════════════╗\033[0m\n"
                "\033[44m\033[1m║ DKIM signature test program for Citadel                                ║\033[0m\n"
-               "\033[44m\033[1m║ Copyright (c) 2024 by citadel.org et al.                               ║\033[0m\n"
+               "\033[44m\033[1m║ Copyright (c) 2024 by citadel.org (Art Cancro et al.)                  ║\033[0m\n"
                "\033[44m\033[1m║ This program is open source software.  Use, duplication, or disclosure ║\033[0m\n"
                "\033[44m\033[1m║ is subject to the terms of the GNU General Public license v3.          ║\033[0m\n"
                "\033[44m\033[1m╚════════════════════════════════════════════════════════════════════════╝\033[0m\n"
@@ -23,36 +23,10 @@ int main(int argc, char *argv[]) {
 
        openlog("dkim", LOG_PERROR, LOG_USER);
 
-       char *private_key =
-               "-----BEGIN PRIVATE KEY-----\n"
-               "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDfuefcepokRrnp\n"
-               "SSDsxu+QDqeD8GL9QnZz/N6IxTdBv6Wc10ExBe2IjS5dKI7AvhSSEK0zGE8Hkpmw\n"
-               "eccbiepQqeueteWzAMZ1uT43bD3k7eye7vWobiOP9QtoYGR6sG25h2W5Tbc91W4f\n"
-               "dvYnxYVJjx8wIVF0f3o25v+rQueoo0HlvGyA9/xi9GAaJL05OmK1xnMJgSvW/Q8Q\n"
-               "zq7apf1D6XPXHuhv5tevElkZ5jlvM2w0cTVyAzMrUh6Rkcn9xM4/NPWYghBc3jO4\n"
-               "TrPnSrobQGrX0fcizE/FN6I0in0Ke8Z+gMM8NeFcsjvLZe9MpY9i0pw/ygLIh5t3\n"
-               "O4qpwC1JAgMBAAECggEAIwiTCMEAGzciDKhhagJ66BWLYMtHTP5X2zDZThSH4xlW\n"
-               "HznL4RfbCtuEy5y6we7h/L90x8ACPB7WRz7CkYrmsMvy9A7q0b2I1k10MyyVgqBJ\n"
-               "QdgMitv4YKYQK7+QbG/tNrS/lqVXUOz3iiDQSgkRpqOtUBWfkj0WD7vbhF99NDhV\n"
-               "dxaehFkKv3yNy0bXJlHJBJ6KtOUnDwub8TExh8dyj3kB8Qzj4I98shaXPNUSSaOw\n"
-               "zG6QG72yrxlMs495jkIPbF2JDidmLrX+oVISwKyaBWx+BkFV/KFAEKgaB5/nCw7+\n"
-               "qq/jxsmXim3HuQ3MIAjq1yw9aGRH1HMi8Gn7tYlNGwKBgQDy6EEKpuEiW9wwlI2+\n"
-               "GVuSkhSTTX1h6qK/ay8Jtyb8yJM/BxogAQlfjdgFixiZHy5MaomTbfeT2GDji553\n"
-               "+RsnZ60+g7FI9nHwabSxtuCQ+vjbFqCsdMPAiSeG0bEzo0zf5TjASdUtuZL0vXjl\n"
-               "yMZWDEuESoVNlYlvCOVkw2nvIwKBgQDryPuSq6PNVHRWsKRRs5ju4wKs/1ucBOg5\n"
-               "gCcN8lE03mFCWAlZhypE4/fAhTQ/a5KQoAzc0QZcXRueDyNsnc+QWw3/QWf8/fkV\n"
-               "HPfTWS3Dcuj+4RnWUucaZ/mKFlTC3+eNSlpyaPIMlCjXGsJ9GlPrsaAi9KPbD2v/\n"
-               "XcMq/PMOowKBgHVf7S3sfZVQthFzdxqIvksQ84hKRW/vJT1B2bTkH56+fQhTsjgM\n"
-               "yC64J85l7DjxbDnYsSngVWXHhOnvKV/nq0tbOcefcydCjsQREBNfvxvPajjTskgj\n"
-               "FAQRQlxPL0U4f4khBk9EXhJ+PZithaHjZpNl1YfTSp62x3Yz4kTSeHnpAoGAGn5m\n"
-               "5kArE7NdrzACBrwrfww7DL1Uyd8zSOLBgKutvEcQnqfNxSWO9la3TAarrESmH2Ic\n"
-               "j+Nc15wOsl/5FwdUf1/73qa2zJKtHlY28qSeo8uRqrIYeSCvnyP3wjBoLc2C8zlb\n"
-               "mGd6azdqr2DuYahHrcAzwjnC/6Zn+DXM7FOn7AkCgYBp1xxY88cCoF24yffkD3MC\n"
-               "ACUury4qRSDTGx6/qCCkIyWxg1vuiDrlPWhSwQznxHvovcfpdjdbWcFY87IK6mpG\n"
-               "aJHwMJ7Kw+baoxGPZWHwdg6BgvUCihe3xlcaq6rOBoLviD6FOzbogg++Tvi0LemG\n"
-               "y/wEs/mZkaRzW4n41ir0Xw==\n"
-               "-----END PRIVATE KEY-----\n"
-       ;
+       // dkim.c can handle a PEM-encoded PKCS#7 private key that has had all of the newlines replaced by underscores.
+       // It will convert them back to newlines before importing the key.
+       // This is the format that Citadel Server uses to store the key in its configuration database.
+       char *private_key = "-----BEGIN PRIVATE KEY-----_MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDfuefcepokRrnp_SSDsxu+QDqeD8GL9QnZz/N6IxTdBv6Wc10ExBe2IjS5dKI7AvhSSEK0zGE8Hkpmw_eccbiepQqeueteWzAMZ1uT43bD3k7eye7vWobiOP9QtoYGR6sG25h2W5Tbc91W4f_dvYnxYVJjx8wIVF0f3o25v+rQueoo0HlvGyA9/xi9GAaJL05OmK1xnMJgSvW/Q8Q_zq7apf1D6XPXHuhv5tevElkZ5jlvM2w0cTVyAzMrUh6Rkcn9xM4/NPWYghBc3jO4_TrPnSrobQGrX0fcizE/FN6I0in0Ke8Z+gMM8NeFcsjvLZe9MpY9i0pw/ygLIh5t3_O4qpwC1JAgMBAAECggEAIwiTCMEAGzciDKhhagJ66BWLYMtHTP5X2zDZThSH4xlW_HznL4RfbCtuEy5y6we7h/L90x8ACPB7WRz7CkYrmsMvy9A7q0b2I1k10MyyVgqBJ_QdgMitv4YKYQK7+QbG/tNrS/lqVXUOz3iiDQSgkRpqOtUBWfkj0WD7vbhF99NDhV_dxaehFkKv3yNy0bXJlHJBJ6KtOUnDwub8TExh8dyj3kB8Qzj4I98shaXPNUSSaOw_zG6QG72yrxlMs495jkIPbF2JDidmLrX+oVISwKyaBWx+BkFV/KFAEKgaB5/nCw7+_qq/jxsmXim3HuQ3MIAjq1yw9aGRH1HMi8Gn7tYlNGwKBgQDy6EEKpuEiW9wwlI2+_GVuSkhSTTX1h6qK/ay8Jtyb8yJM/BxogAQlfjdgFixiZHy5MaomTbfeT2GDji553_+RsnZ60+g7FI9nHwabSxtuCQ+vjbFqCsdMPAiSeG0bEzo0zf5TjASdUtuZL0vXjl_yMZWDEuESoVNlYlvCOVkw2nvIwKBgQDryPuSq6PNVHRWsKRRs5ju4wKs/1ucBOg5_gCcN8lE03mFCWAlZhypE4/fAhTQ/a5KQoAzc0QZcXRueDyNsnc+QWw3/QWf8/fkV_HPfTWS3Dcuj+4RnWUucaZ/mKFlTC3+eNSlpyaPIMlCjXGsJ9GlPrsaAi9KPbD2v/_XcMq/PMOowKBgHVf7S3sfZVQthFzdxqIvksQ84hKRW/vJT1B2bTkH56+fQhTsjgM_yC64J85l7DjxbDnYsSngVWXHhOnvKV/nq0tbOcefcydCjsQREBNfvxvPajjTskgj_FAQRQlxPL0U4f4khBk9EXhJ+PZithaHjZpNl1YfTSp62x3Yz4kTSeHnpAoGAGn5m_5kArE7NdrzACBrwrfww7DL1Uyd8zSOLBgKutvEcQnqfNxSWO9la3TAarrESmH2Ic_j+Nc15wOsl/5FwdUf1/73qa2zJKtHlY28qSeo8uRqrIYeSCvnyP3wjBoLc2C8zlb_mGd6azdqr2DuYahHrcAzwjnC/6Zn+DXM7FOn7AkCgYBp1xxY88cCoF24yffkD3MC_ACUury4qRSDTGx6/qCCkIyWxg1vuiDrlPWhSwQznxHvovcfpdjdbWcFY87IK6mpG_aJHwMJ7Kw+baoxGPZWHwdg6BgvUCihe3xlcaq6rOBoLviD6FOzbogg++Tvi0LemG_y/wEs/mZkaRzW4n41ir0Xw==_-----END PRIVATE KEY-----";
 
        char *domain = "dev.citadel.org";
        char *selector = "foo";
index a4bdb50478940fb2406b1d9d16a9a63147ae5770..cc25ef28a8a896882e6c027b8f932d133cc8cb9b 100644 (file)
@@ -1,6 +1,6 @@
 // Load (restore) the Citadel database from a flat file created by ctdldump
 //
-// Copyright (c) 2023-2024 by Art Cancro citadel.org
+// Copyright (c) 2023-2024 by citadel.org (Art Cancro et al.)
 //
 // This program is open source software.  Use, duplication, or disclosure
 // is subject to the terms of the GNU General Public License, version 3.
@@ -163,8 +163,13 @@ int import_user(char *line, struct cdbkeyval *kv) {
                                u->msgnum_pic = atol(token);
                                break;
                        case 12:
-                               CtdlDecodeBase64(token, token, strlen(token));                  // Decode in place
-                               safestrncpy(u->emailaddrs, token, sizeof(u->emailaddrs));
+                               int dlen;
+                               dlen = CtdlDecodeBase64(token, token, strlen(token));                   // Decode in place
+                               if (dlen >= sizeof(u->emailaddrs)) {
+                                       dlen = sizeof(u->emailaddrs) - 1;
+                               }
+                               memcpy(u->emailaddrs, token, dlen);
+                               u->emailaddrs[dlen] = 0;
                                break;
                        case 13:
                                u->msgnum_inboxrules = atol(token);