diff options
Diffstat (limited to 'sqmail-4.3.07/src/qmail-dkim.cpp')
-rw-r--r-- | sqmail-4.3.07/src/qmail-dkim.cpp | 343 |
1 files changed, 0 insertions, 343 deletions
diff --git a/sqmail-4.3.07/src/qmail-dkim.cpp b/sqmail-4.3.07/src/qmail-dkim.cpp deleted file mode 100644 index fba94fe..0000000 --- a/sqmail-4.3.07/src/qmail-dkim.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/***************************************************************************** -* Copyright 2005 Alt-N Technologies, Ltd. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* This code incorporates intellectual property owned by Yahoo! and licensed -* pursuant to the Yahoo! DomainKeys Patent License Agreement. -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* Changes done by ¢feh@fehcom.de obeying the above license -* -* Comment: Awful mixture of C and C++ making use of the worst parts of it. -* Style: Partial Hungarian notation (see Torvalds comments) -* C++: Obsolete classes, allocators, virtual constructors w/o destructors -* C: Stdio interface routines -* OpenSSL: Brain demaged EVP_Digest calls with memory leaks. -* Network: Sigh, exchanged internal DNS routines by fehQlibs resolver -* -*****************************************************************************/ -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <stdlib.h> -#include <unistd.h> -#include "dkim.h" -extern "C" { -#include "dns.h" -} - -// change these to your selector name, domain name, etc -#define MYRSASELECTOR "default" -#define MYECCSELECTOR "eddy" -#define MYDOMAIN "" //"bardenhagen.com" -#define MYIDENTITY "" //"dkimtest@bardenhagen.com" - -#define strnicmp strncasecmp -#define FDLOG stderr /* writing to another FD requires a method */ - -int DKIM_CALL SignThisHeader(const char* szHeader) -{ - if (strnicmp(szHeader,"X-",2) == 0 ) { return 0; } - return 1; -} - -int DKIM_CALL SelectorCallback(const char* szFQDN,char* szBuffer,int nBufLen) -{ - return 0; -} - -void usage() -{ - char version[] = "1.4.0"; - fprintf(FDLOG,"qmail-dkim %s \n",version); - fprintf(FDLOG,"Usage: qmail-dkim [-h|-v|-s] [tags] <msgfile> [<RSAkeyfile> <outfile> <Ed25519keyfile>]\n\n"); - fprintf(FDLOG, "Options:\n\t-h show this help\n"); - fprintf(FDLOG, "\t-s sign the message \n"); - fprintf(FDLOG, "\t-v verify the message\n"); - fprintf(FDLOG, "\t-V verify the message and write result to output file (Pass/Fail)\n\n"); - fprintf(FDLOG, "These tags are available:\n"); - fprintf(FDLOG, "\t-c<canonicalization> - r=relaxed [DEFAULT], s=simple, t=relaxed/simple, u=simple/relaxed\n"); - fprintf(FDLOG, "\t-d<sdid> - Signing Domain Identifier (if not provided it will be determined from the sender/from header)\n"); - fprintf(FDLOG, "\t-i<auid> - Agent User Identifier, usually the sender's email address (optional)\n"); - fprintf(FDLOG, "\t-l - include body length tag (optional)\n"); - fprintf(FDLOG, "\t-q - include query method tag\n"); - fprintf(FDLOG, "\t-t - include a timestamp tag (optional)\n"); - fprintf(FDLOG, "\t-x<expire_time> - the expire time in seconds since epoch (optional, DEFAULT = current time + 604800)\n"); - fprintf(FDLOG, "\t-y<selector> - set RSA selector (DEFAULT: default)\n"); - fprintf(FDLOG, "\t-Y<selector> - set Ed25519 selector (DEFAULT: default)\n"); - fprintf(FDLOG, "\t-z<hash> - set signature algorithm type (1=rsa-sha1, 2=rsa-sha256, 3=both, 4=ed25519, 5=hybrid)\n"); -} - -int main(int argc, char* argv[]) -{ - int n; - const char* RSAKeyFile = "rsa.pem"; - const char* ECCKeyFile = "ed25519.pem"; - const char* MsgFile = "test.msg"; - const char* OutFile = "signed.msg"; - int nKeyLen; - char RSAPrivKey[4196]; // storge for private key FILE including header and DER envelope - char ECCPrivKey[128]; - char Buffer[1000]; - int BufLen; - char szSignature[8192]; - time_t t; - DKIMContext ctxt; - DKIMSignOptions opts = {0}; - - opts.nHash = DKIM_HASH_SHA256; // default - - time(&t); - - opts.nCanon = DKIM_SIGN_RELAXED; - opts.nIncludeBodyLengthTag = 0; - opts.nIncludeQueryMethod = 0; - opts.nIncludeTimeStamp = 0; - opts.expireTime = t + 604800; // expires in 1 week - strcpy(opts.szSelector,MYRSASELECTOR); - strcpy(opts.szSelectorE,MYECCSELECTOR); - strcpy(opts.szDomain,MYDOMAIN); - strcpy(opts.szIdentity,MYIDENTITY); - opts.pfnHeaderCallback = SignThisHeader; - strcpy(opts.szRequiredHeaders,"NonExistant"); - opts.nIncludeCopiedHeaders = 0; - - int nArgParseState = 0; - bool bSign = true; - bool bRes = false; - - if (argc < 2){ - usage(); - exit(1); - } - - for (n = 1; n < argc; n++) { - if (argv[n][0] == '-' && strlen(argv[n]) > 1) { - switch (argv[n][1]) { - case 'c': // canonicalization - if (argv[n][2] == 'r') { opts.nCanon = DKIM_SIGN_RELAXED; } - else if (argv[n][2] == 's') { opts.nCanon = DKIM_SIGN_SIMPLE; } - else if (argv[n][2] == 't') { opts.nCanon = DKIM_SIGN_RELAXED_SIMPLE; } - else if (argv[n][2] == 'u') { opts.nCanon = DKIM_SIGN_SIMPLE_RELAXED; } - break; - case 'd': - strncpy(opts.szDomain,(const char*)(argv[n] + 2),sizeof(opts.szDomain) - 1); - break; - case 'l': // body length tag - opts.nIncludeBodyLengthTag = 1; - break; - case 'h': - usage(); - return 0; - case 'i': // identity - if (argv[n][2] == '-') { opts.szIdentity[0] = '\0'; } - else { strncpy(opts.szIdentity, argv[n] + 2,sizeof(opts.szIdentity) - 1); } - break; - case 'q': // query method tag - opts.nIncludeQueryMethod = 1; - break; - case 's': // sign with and use potentially Ed25519 private key - bSign = true; - break; - case 't': // timestamp tag - opts.nIncludeTimeStamp = 1; - break; - case 'v': // verify - bSign = false; - break; - case 'V': // verify and write result to OutFile - bSign = false; - bRes = true; - break; - case 'x': // expire time - if (argv[n][2] == '-') { opts.expireTime = 0; } - else { opts.expireTime = t + atoi(argv[n] + 2); } - break; - case 'y': - strncpy(opts.szSelector,argv[n] + 2,sizeof(opts.szSelector) - 1); - break; - case 'Y': - strncpy(opts.szSelectorE,argv[n] + 2,sizeof(opts.szSelectorE) - 1); - break; - case 'z': // sign w/ sha1, sha256, both, ed25519, hybrid - opts.nHash = atoi(&argv[n][2]); - } - } - else { - switch (nArgParseState) { - case 0: - MsgFile = argv[n]; - break; - case 1: - RSAKeyFile = argv[n]; - break; - case 2: - OutFile = argv[n]; - break; - case 3: - ECCKeyFile = argv[n]; - break; - } - nArgParseState++; - } - } - -/** Go for DKIM signing ... **/ - - if (bSign) { - if (opts.nHash != 4) { - FILE* RSAPrivKeyFP = fopen(RSAKeyFile,"r"); - if (RSAPrivKeyFP == NULL) { -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: can't open private key file (%s) \n",RSAKeyFile); -#endif - exit(1); - } - nKeyLen = fread(RSAPrivKey,1,sizeof(RSAPrivKey),RSAPrivKeyFP); // we read sizeof(RSAPrivKey) members with size of 1 byte each; sigh -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: private key file (%s) - length %i \n",RSAKeyFile,nKeyLen); -#endif - if (nKeyLen >= sizeof(RSAPrivKey)) { /* (TC9) on return, we get the number of members read! */ -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: private key buffer isn't big enough for private key length %i \n",nKeyLen); -#endif - exit(1); - } - RSAPrivKey[nKeyLen] = '\0'; - fclose(RSAPrivKeyFP); - } - -/** Ed25519 signing **/ - - if (opts.nHash == 4 || opts.nHash == 5) { - FILE* ECCPrivKeyFP = fopen(ECCKeyFile,"r"); - if (ECCPrivKeyFP == NULL) { -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: can't open Ed25519 private key file (%s) \n",ECCKeyFile); -#endif - exit(1); - } - nKeyLen = fread(ECCPrivKey,1,sizeof(ECCPrivKey),ECCPrivKeyFP); -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: Ed25519 private key file (%s) - length %i \n",ECCKeyFile,nKeyLen); -#endif - if (nKeyLen >= sizeof(ECCPrivKey)) { -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: ECC private key buffer isn't big enough for ECC private key length %i \n",nKeyLen); -#endif - exit(1); - } - ECCPrivKey[nKeyLen] = '\0'; - fclose(ECCPrivKeyFP); - } - -/** Input message for signing **/ - - FILE* MsgFP = fopen(MsgFile,"rb"); - if (MsgFP == NULL) { -#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: can't open msg file (%s) \n",MsgFile); -#endif - exit(1); - } - - n = DKIMSignInit(&ctxt,&opts); - - while (1) { - BufLen = fread(Buffer,1,sizeof(Buffer),MsgFP); - if (BufLen > 0) { DKIMSignProcess(&ctxt,Buffer,BufLen); } - else { break; } - } - fclose(MsgFP); - - char* pSig = NULL; - -/** Do the actual signing **/ - - n = DKIMSignGetSig2(&ctxt,RSAPrivKey,ECCPrivKey,&pSig); - - strcpy(szSignature,pSig); - - DKIMSignFree(&ctxt); - - FILE* in = fopen(MsgFile,"rb"); - FILE* out = fopen(OutFile,"wb+"); - -#ifdef SHOWLOG - fprintf(FDLOG," outfile written %s \n",OutFile); -#endif - - fwrite(szSignature,1,strlen(szSignature),out); - fwrite("\r\n",1,2,out); - - while (1) { - BufLen = fread(Buffer,1,sizeof(Buffer),in); - if (BufLen > 0) { fwrite(Buffer,1,BufLen,out); } - else { break; } - } - fclose(in); - - } - -/** Now go for verification **/ - - else { - FILE* in = fopen(MsgFile,"rb"); - if (in == NULL) { -//#ifdef SHOWLOG - fprintf(FDLOG," qmail-dkim: can't open input file\n"); -//#endif - return 0; // bad option -- no CTX set up yet - } - - DKIMVerifyOptions vopts = {0}; - vopts.pfnSelectorCallback = NULL; //SelectorCallback; - - n = DKIMVerifyInit(&ctxt,&vopts); - - while (1) { - BufLen = fread(Buffer,1,sizeof(Buffer),in); - if (BufLen > 0) { DKIMVerifyProcess(&ctxt,Buffer,BufLen); } - else { break; } - } - - n = DKIMVerifyResults(&ctxt); - - int nSigCount = 0; - DKIMVerifyDetails* pDetails; - char szPolicy[512]; - - n = DKIMVerifyGetDetails(&ctxt,&nSigCount,&pDetails,szPolicy); - - for (int i = 0; i < nSigCount; i++) { - const char s[] = "pass"; - const char f[] = "fail"; - const char* error = DKIM_ErrorResult(pDetails[i].nResult); - if (!bRes) - fprintf(FDLOG," Signature #%d: ",i + 1); - if (pDetails[i].nResult >= 0 ) { - if (bRes) { - _DKIM_ReportResult(OutFile,s,0); - } else - printf(" Pass\n"); - } else { // fail - if (bRes) { - _DKIM_ReportResult(OutFile,f,error); - } else - printf(" Fail %s \n",error); - } - } - DKIMVerifyFree(&ctxt); - } - return 0; -} |