Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -0,0 +1,320 @@
// CBase64.cpp: implementation of the CBase64 class.
//
//////////////////////////////////////////////////////////////////////
#include "Base64.h"
// Digits...
static char Base64Digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
BOOL CBase64::m_Init = FALSE;
char CBase64::m_DecodeTable[256];
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif
#ifndef ROUNDTOPAGE
#define ROUNDTOPAGE(a) (((a/4096)+1)*4096)
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBase64::CBase64()
: m_pDBuffer(NULL),
m_pEBuffer(NULL),
m_nDBufLen(0),
m_nEBufLen(0),
m_nDDataLen(0),
m_nEDataLen(0)
{
}
CBase64::~CBase64()
{
if(m_pDBuffer != NULL)
delete [] m_pDBuffer;
if(m_pEBuffer != NULL)
delete [] m_pEBuffer;
}
LPCSTR CBase64::DecodedMessage() const
{
return (LPCSTR) m_pDBuffer;
}
LPCSTR CBase64::EncodedMessage() const
{
return (LPCSTR) m_pEBuffer;
}
void CBase64::AllocEncode(DWORD nSize)
{
if(m_nEBufLen < nSize)
{
if(m_pEBuffer != NULL)
delete [] m_pEBuffer;
m_nEBufLen = ROUNDTOPAGE(nSize);
m_pEBuffer = new BYTE[m_nEBufLen];
}
::ZeroMemory(m_pEBuffer, m_nEBufLen);
m_nEDataLen = 0;
}
void CBase64::AllocDecode(DWORD nSize)
{
if(m_nDBufLen < nSize)
{
if(m_pDBuffer != NULL)
delete [] m_pDBuffer;
m_nDBufLen = ROUNDTOPAGE(nSize);
m_pDBuffer = new BYTE[m_nDBufLen];
}
::ZeroMemory(m_pDBuffer, m_nDBufLen);
m_nDDataLen = 0;
}
void CBase64::SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
{
DWORD i = 0;
AllocEncode(nBufLen);
while(i < nBufLen)
{
if(!_IsBadMimeChar(pBuffer[i]))
{
m_pEBuffer[m_nEDataLen] = pBuffer[i];
m_nEDataLen++;
}
i++;
}
}
void CBase64::SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen)
{
AllocDecode(nBufLen);
::CopyMemory(m_pDBuffer, pBuffer, nBufLen);
m_nDDataLen = nBufLen;
}
void CBase64::Encode(const PBYTE pBuffer, DWORD nBufLen)
{
SetDecodeBuffer(pBuffer, nBufLen);
AllocEncode(nBufLen * 2);
TempBucket Raw;
DWORD nIndex = 0;
while((nIndex + 3) <= nBufLen)
{
Raw.Clear();
::CopyMemory(&Raw, m_pDBuffer + nIndex, 3);
Raw.nSize = 3;
_EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
nIndex += 3;
m_nEDataLen += 4;
}
if(nBufLen > nIndex)
{
Raw.Clear();
Raw.nSize = (BYTE) (nBufLen - nIndex);
::CopyMemory(&Raw, m_pDBuffer + nIndex, nBufLen - nIndex);
_EncodeToBuffer(Raw, m_pEBuffer + m_nEDataLen);
m_nEDataLen += 4;
}
}
void CBase64::Encode(LPCSTR szMessage)
{
if(szMessage != NULL)
CBase64::Encode((const PBYTE)szMessage, lstrlenA(szMessage));
}
void CBase64::Decode(const PBYTE pBuffer, DWORD dwBufLen)
{
if(!CBase64::m_Init)
_Init();
SetEncodeBuffer(pBuffer, dwBufLen);
AllocDecode(dwBufLen);
TempBucket Raw;
DWORD nIndex = 0;
while((nIndex + 4) <= m_nEDataLen)
{
Raw.Clear();
Raw.nData[0] = CBase64::m_DecodeTable[m_pEBuffer[nIndex]];
Raw.nData[1] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 1]];
Raw.nData[2] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 2]];
Raw.nData[3] = CBase64::m_DecodeTable[m_pEBuffer[nIndex + 3]];
if(Raw.nData[2] == 255)
Raw.nData[2] = 0;
if(Raw.nData[3] == 255)
Raw.nData[3] = 0;
Raw.nSize = 4;
_DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
nIndex += 4;
m_nDDataLen += 3;
}
// If nIndex < m_nEDataLen, then we got a decode message without padding.
// We may want to throw some kind of warning here, but we are still required
// to handle the decoding as if it was properly padded.
if(nIndex < m_nEDataLen)
{
Raw.Clear();
for(DWORD i = nIndex; i < m_nEDataLen; i++)
{
Raw.nData[i - nIndex] = CBase64::m_DecodeTable[m_pEBuffer[i]];
Raw.nSize++;
if(Raw.nData[i - nIndex] == 255)
Raw.nData[i - nIndex] = 0;
}
_DecodeToBuffer(Raw, m_pDBuffer + m_nDDataLen);
m_nDDataLen += (m_nEDataLen - nIndex);
}
}
void CBase64::Decode(LPCSTR szMessage)
{
if(szMessage != NULL)
CBase64::Decode((const PBYTE)szMessage, lstrlenA(szMessage));
}
DWORD CBase64::_DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
{
TempBucket Data;
DWORD nCount = 0;
_DecodeRaw(Data, Decode);
for(int i = 0; i < 3; i++)
{
pBuffer[i] = Data.nData[i];
if(pBuffer[i] != 255)
nCount++;
}
return nCount;
}
void CBase64::_EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer)
{
TempBucket Data;
_EncodeRaw(Data, Decode);
for(int i = 0; i < 4; i++)
pBuffer[i] = Base64Digits[Data.nData[i]];
switch(Decode.nSize)
{
case 1:
pBuffer[2] = '=';
case 2:
pBuffer[3] = '=';
}
}
void CBase64::_DecodeRaw(TempBucket &Data, const TempBucket &Decode)
{
BYTE nTemp;
Data.nData[0] = Decode.nData[0];
Data.nData[0] <<= 2;
nTemp = Decode.nData[1];
nTemp >>= 4;
nTemp &= 0x03;
Data.nData[0] |= nTemp;
Data.nData[1] = Decode.nData[1];
Data.nData[1] <<= 4;
nTemp = Decode.nData[2];
nTemp >>= 2;
nTemp &= 0x0F;
Data.nData[1] |= nTemp;
Data.nData[2] = Decode.nData[2];
Data.nData[2] <<= 6;
nTemp = Decode.nData[3];
nTemp &= 0x3F;
Data.nData[2] |= nTemp;
}
void CBase64::_EncodeRaw(TempBucket &Data, const TempBucket &Decode)
{
BYTE nTemp;
Data.nData[0] = Decode.nData[0];
Data.nData[0] >>= 2;
Data.nData[1] = Decode.nData[0];
Data.nData[1] <<= 4;
nTemp = Decode.nData[1];
nTemp >>= 4;
Data.nData[1] |= nTemp;
Data.nData[1] &= 0x3F;
Data.nData[2] = Decode.nData[1];
Data.nData[2] <<= 2;
nTemp = Decode.nData[2];
nTemp >>= 6;
Data.nData[2] |= nTemp;
Data.nData[2] &= 0x3F;
Data.nData[3] = Decode.nData[2];
Data.nData[3] &= 0x3F;
}
BOOL CBase64::_IsBadMimeChar(BYTE nData)
{
switch(nData)
{
case '\r': case '\n': case '\t': case ' ' :
case '\b': case '\a': case '\f': case '\v':
return TRUE;
default:
return FALSE;
}
}
void CBase64::_Init()
{ // Initialize Decoding table.
int i;
for(i = 0; i < 256; i++)
CBase64::m_DecodeTable[i] = -2;
for(i = 0; i < 64; i++)
{
CBase64::m_DecodeTable[Base64Digits[i]] = (CHAR)i;
CBase64::m_DecodeTable[Base64Digits[i]|0x80] = (CHAR)i;
}
CBase64::m_DecodeTable['='] = -1;
CBase64::m_DecodeTable['='|0x80] = -1;
CBase64::m_Init = TRUE;
}

View File

@ -0,0 +1,63 @@
// CBase64.h: interface for the CBase64 class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CBase64_H__B2E45717_0625_11D2_A80A_00C04FB6794C__INCLUDED_)
#define AFX_CBase64_H__B2E45717_0625_11D2_A80A_00C04FB6794C__INCLUDED_
#include <windows.h>
#define lCONTEXT char
#define PlCONTEXT lCONTEXT*
class CBase64
{
// Internal bucket class.
class TempBucket
{
public:
BYTE nData[4];
BYTE nSize;
void Clear() { ::ZeroMemory(nData, 4); nSize = 0; };
};
PBYTE m_pDBuffer;
PBYTE m_pEBuffer;
DWORD m_nDBufLen;
DWORD m_nEBufLen;
DWORD m_nDDataLen;
DWORD m_nEDataLen;
public:
CBase64();
virtual ~CBase64();
public:
virtual void Encode(const PBYTE, DWORD);
virtual void Decode(const PBYTE, DWORD);
virtual void Encode(LPCSTR sMessage);
virtual void Decode(LPCSTR sMessage);
virtual LPCSTR DecodedMessage() const;
virtual LPCSTR EncodedMessage() const;
virtual void AllocEncode(DWORD);
virtual void AllocDecode(DWORD);
virtual void SetEncodeBuffer(const PBYTE pBuffer, DWORD nBufLen);
virtual void SetDecodeBuffer(const PBYTE pBuffer, DWORD nBufLen);
protected:
virtual void _EncodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
virtual ULONG _DecodeToBuffer(const TempBucket &Decode, PBYTE pBuffer);
virtual void _EncodeRaw(TempBucket &, const TempBucket &);
virtual void _DecodeRaw(TempBucket &, const TempBucket &);
virtual BOOL _IsBadMimeChar(BYTE);
static char m_DecodeTable[256];
static BOOL m_Init;
void _Init();
};
#endif // !defined(AFX_CBase64_H__B2E45717_0625_11D2_A80A_00C04FB6794C__INCLUDED_)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,245 @@
// Smtp.h: interface for the CSmtp class.
//
// Written by Robert Simpson (robert@blackcastlesoft.com)
// Created 11/1/2000
// Version 1.7 -- Last Modified 06/18/2001
// See smtp.cpp for details of this revision
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_SMTP_H__F5ACA8FA_AF73_11D4_907D_0080C6F7C752__INCLUDED_)
#define AFX_SMTP_H__F5ACA8FA_AF73_11D4_907D_0080C6F7C752__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma comment(lib,"wsock32.lib")
#include <atlbase.h>
#include <winsock.h>
#include <string>
#include "Base64.h"
// Some ATL string conversion enhancements
// ATL's string conversions allocate memory on the stack, which can
// be undesirable if converting huge strings. These enhancements
// provide for a pre-allocated memory block to be used as the
// destination for the string conversion.
#define _W2A(dst,src) AtlW2AHelper(dst,src,lstrlenW(src)+1)
#define _A2W(dst,src) AtlA2WHelper(dst,src,lstrlenA(src)+1)
typedef std::wstring StringW;
typedef std::string StringA;
#ifdef _UNICODE
typedef StringW String;
#define _W2T(dst,src) lstrcpyW(dst,src)
#define _T2W(dst,src) lstrcpyW(dst,src)
#define _T2A(dst,src) _W2A(dst,src)
#define _A2T(dst,src) _A2W(dst,src)
#else
typedef StringA String;
#define _W2T(dst,src) _W2A(dst,src)
#define _T2W(dst,src) _A2W(dst,src)
#define _T2A(dst,src) lstrcpyA(dst,src)
#define _A2T(dst,src) lstrcpyA(dst,src)
#endif
// When the SMTP server responds to a command, this is the
// maximum size of a response I expect back.
#ifndef CMD_RESPONSE_SIZE
#define CMD_RESPONSE_SIZE 1024
#endif
// The CSmtp::SendCmd() function will send blocks no larger than this value
// Any outgoing data larger than this value will trigger an SmtpProgress()
// event for all blocks sent.
#ifndef CMD_BLOCK_SIZE
#define CMD_BLOCK_SIZE 1024
#endif
// Default mime version is 1.0 of course
#ifndef MIME_VERSION
#define MIME_VERSION _T("1.0")
#endif
// This is the message that would appear in an e-mail client that doesn't support
// multipart messages
#ifndef MULTIPART_MESSAGE
#define MULTIPART_MESSAGE _T("This is a multipart message in MIME format")
#endif
// Default message body encoding
#ifndef MESSAGE_ENCODING
#define MESSAGE_ENCODING _T("text/plain")
#endif
// Default character set
#ifndef MESSAGE_CHARSET
#define MESSAGE_CHARSET _T("iso-8859-1")
#endif
// Some forward declares
class CSmtp;
class CSmtpAddress;
class CSmtpMessage;
class CSmtpAttachment;
class CSmtpMessageBody;
class CSmtpMimePart;
// These are the only 4 encoding methods currently supported
typedef enum EncodingEnum
{
encodeGuess,
encode7Bit,
encode8Bit,
encodeQuotedPrintable,
encodeBase64
};
// This code supports three types of mime-types, and can optionally guess a mime type
// based on message content.
typedef enum MimeTypeEnum
{
mimeGuess,
mimeMixed,
mimeAlternative,
mimeRelated
};
// Attachments and message bodies inherit from this class
// It allows each part of a multipart MIME message to have its own attributes
class CSmtpMimePart
{
public:
String Encoding; // Content encoding. Leave blank to let the system discover it
String Charset; // Character set for text attachments
String ContentId; // Unique content ID, leave blank to let the system handle it
EncodingEnum TransferEncoding; // How to encode for transferring to the server
};
// This class represents a user's text name and corresponding email address
class CSmtpAddress
{
public: // Constructors
CSmtpAddress(LPCTSTR pszAddress = NULL, LPCTSTR pszName = NULL);
public: // Operators
const CSmtpAddress& operator=(LPCTSTR pszAddress);
const CSmtpAddress& operator=(const String& strAddress);
public: // Member Variables
String Name;
String Address;
};
// This class represents a file attachment
class CSmtpAttachment : public CSmtpMimePart
{
public: // Constructors
CSmtpAttachment(LPCTSTR pszFilename = NULL, LPCTSTR pszAltName = NULL, BOOL bIsInline = FALSE, LPCTSTR pszEncoding = NULL, LPCTSTR pszCharset = MESSAGE_CHARSET, EncodingEnum encode = encodeGuess);
public: // Operators
const CSmtpAttachment& operator=(LPCTSTR pszFilename);
const CSmtpAttachment& operator=(const String& strFilename);
public: // Member Variables
String FileName; // Fully-qualified path and filename of this attachment
String AltName; // Optional, an alternate name for the file to use when sending
BOOL Inline; // Is this an inline attachment?
};
// Multiple message body part support
class CSmtpMessageBody : public CSmtpMimePart
{
public: // Constructors
CSmtpMessageBody(LPCTSTR pszBody = NULL, LPCTSTR pszEncoding = MESSAGE_ENCODING, LPCTSTR pszCharset = MESSAGE_CHARSET, EncodingEnum encode = encodeGuess);
public: // Operators
const CSmtpMessageBody& operator=(LPCTSTR pszBody);
const CSmtpMessageBody& operator=(const String& strBody);
public: // Member Variables
String Data; // Message body;
};
// This class represents a single message that can be sent via CSmtp
class CSmtpMessage
{
public: // Constructors
CSmtpMessage();
public: // Member Variables
CSmtpAddress Sender; // Who the message is from
CSmtpAddress Recipient; // The intended recipient
String Subject; // The message subject
CSimpleArray<CSmtpMessageBody> Message; // An array of message bodies
CSimpleArray<CSmtpAddress> CC; // Carbon Copy recipients
CSimpleArray<CSmtpAddress> BCC; // Blind Carbon Copy recipients
CSimpleArray<CSmtpAttachment> Attachments; // An array of attachments
CSimpleMap<String,String> Headers; // Optional headers to include in the message
SYSTEMTIME Timestamp; // Timestamp of the message
MimeTypeEnum MimeType; // Type of MIME message this is
String MessageId; // Optional message ID
private: // Private Member Variables
int GMTOffset; // GMT timezone offset value
public: // Public functions
void Parse(String& strDest);
private: // Private functions to finalize the message headers & parse the message
EncodingEnum GuessEncoding(LPBYTE pByte, DWORD dwLen);
void EncodeMessage(EncodingEnum code, String& strMsg, String& strMethod, LPBYTE pByte = NULL, DWORD dwSize = 0);
void Make7Bit(String& strDest, String& strSrc);
void CommitHeaders();
void BreakMessage(String& strDest, String& strSrc, int nLength = 76);
void EncodeQuotedPrintable(String& strDest, String& strSrc);
};
// The main class for connecting to a SMTP server and sending mail.
class CSmtp
{
public: // Constructors
CSmtp();
virtual ~CSmtp();
public: // Member Variables. Feel free to modify these to change the system's behavior
BOOL m_bExtensions; // Use ESMTP extensions (TRUE)
DWORD m_dwCmdTimeout; // Timeout for issuing each command (30 seconds)
WORD m_wSmtpPort; // Port to communicate via SMTP (25)
String m_strUser; // Username for authentication
String m_strPass; // Password for authentication
private: // Private Member Variables
SOCKET m_hSocket; // Socket being used to communicate to the SMTP server
String m_strResult; // String result from a SendCmd()
BOOL m_bConnected; // Connected to SMTP server
BOOL m_bUsingExtensions;// Whether this SMTP server uses ESMTP extensions
public: // These represent the primary public functionality of this class
BOOL Connect(LPTSTR pszServer);
int SendMessage(CSmtpMessage& msg);
int SendMessage(CSmtpAddress& addrFrom, CSmtpAddress& addrTo, LPCTSTR pszSubject, LPTSTR pszMessage, LPVOID pvAttachments = NULL, DWORD dwAttachmentCount = 0);
int SendMessage(LPTSTR pszAddrFrom, LPTSTR pszAddrTo, LPTSTR pszSubject, LPTSTR pszMessage, LPVOID pvAttachments = NULL, DWORD dwAttachmentCount = 0);
void Close();
public: // These represent the overridable methods for receiving events from this class
virtual int SmtpWarning(int nWarning, LPTSTR pszWarning);
virtual int SmtpError(int nCode, LPTSTR pszErr);
virtual void SmtpCommandResponse(LPTSTR pszCmd, int nResponse, LPTSTR pszResponse);
virtual BOOL SmtpProgress(LPSTR pszBuffer, DWORD dwSent, DWORD dwTotal);
private: // These functions are used privately to conduct a SMTP session
int SendCmd(LPTSTR pszCmd);
int SendAuthentication();
int SendHello();
int SendQuitCmd();
int SendFrom(LPTSTR pszFrom);
int SendTo(LPTSTR pszTo);
int SendData(CSmtpMessage &msg);
int RaiseWarning(int nWarning);
int RaiseError(int nError);
};
#endif // !defined(AFX_SMTP_H__F5ACA8FA_AF73_11D4_907D_0080C6F7C752__INCLUDED_)