Initial Commit

This commit is contained in:
Riley Schneider
2025-12-03 16:38:10 +01:00
parent c5e26bf594
commit b732d8d4b5
17680 changed files with 5977495 additions and 2 deletions

View File

@@ -0,0 +1,110 @@
version 32 (18 june 2011)
- fix handling of invalid recipients
version 31 (15 sep, 2010)
- fix encoding of 8-bit data
version 30 (30 aug, 2010)
- update to latest indy version (fixes many issues)
- add about/version
version 29 (sep 8, 2009)
- fix for another indy 10 "range check error" (when using ssl)
version 28 (aug 12, 2009)
- set ERRORLEVEL to -1 to assist php
version 27 (aug 3, 2009)
- don't treat log write errors as fatal
version 26 (apr 1, 2009)
- no longer require -t parameter
- skip first line if it starts with "from " (mail spool delimiting line)
version 25 (mar 29, 2009)
- added force_recipient
version 24 (dec 2, 2008)
- fixes for ssl
version 23 (apr 24, 2008)
- fix timezone in date header
version 22 (jan 14, 2008)
- fixes to error handling
version 21 (jan 2, 2008)
- added TLS support
version 20 (apr 3, 2007)
- fixed race condition in IIS's pickup delivery
version 19 (jul 24, 2006)
- added support for delivery via IIS's pickup directory
- optionally reads settings from the registry (in absense of the ini file)
version 18 (may 1, 2006)
- fix for indy 10 "range check error"
version 17 (nov 2, 2005)
- only process message header
- optionally use madexcept for detailed crash dumps
version 16 (sep 12, 2005)
- send hostname and domain with HELO/EHLO
- configurable HELO/EHLO hostname
- upgraded to indy 10
version 15 (aug 23, 2005)
- fixes error messages when debug_logfile is not specified
version 14 (jun 28, 2005)
- errors output to STDERR
- fixes for delphi 7 compilation
- added 'connecting to..' debug logging
- reworked error and debug log format
version 13 (jun 8, 2005)
- added fix to work around invalid multiple header instances
version 12 (apr 30, 2005)
- added cc and bcc support
version 11 (feb 17, 2005)
- added pop3 support (for pop before smtp authentication)
version 10 (feb 11, 2005)
- added support for specifying a different smtp port
version 9 (sep 22, 2004)
- added force_sender
version 8 (sep 22, 2004)
- *really* fixes broken smtp auth
version 7 (sep 22, 2004)
- fixes broken smtp auth
version 6 (sep 22, 2004)
- correctly quotes MAIL FROM and RCPT TO addresses in <>
version 5 (sep 16, 2004)
- now sends the message unchanged (rather than getting indy
to regenerate it)
version 4 (aug 17, 2004)
- added debug_logfile parameter
- improved error messages
version 3 (jul 15, 2004)
- smtp authentication support
- clearer error message when missing from or to address
- optional error logging
- adds date: if missing
version 2 (jul 6, 2004)
- reads default domain from registry (.ini setting overrides)
version 1 (jul 1, 2004)
- initial release

View File

@@ -0,0 +1,127 @@
LICENSE ISSUES
==============
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts. Actually both licenses are BSD-style
Open Source licenses. In case of any license issues related to OpenSSL
please contact openssl-core@openssl.org.
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/

View File

@@ -0,0 +1,66 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>fake sendmail for windows</title>
<style>
body {
background-color: #ffffff;
}
pre {
font-size: 11px;
line-height: 14px;
font-family: Andale Mono, monospace;
}
.head {
color: #cc6666;
font-weight: bold;
}
.sub {
color: #cc6666;
}
a {
text-decoration: none;
}
</style>
</head>
<body bgcolor="#ffffff" link="#1084d0" text="#555555" vlink="#1084d0">
<pre><span class="head">fake sendmail for bugzilla/windows</span>
glob.com.au/sendmail
sendmail@glob.com.au
<span class="sub">about</span>
sendmail.exe is a simple windows console application that emulates sendmail's
"-t" option to deliver emails piped via stdin.
it is intended to ease running unix code that has /usr/lib/sendmail hardcoded
as an email delivery means.
it doesn't support deferred delivery, and requires an smtp server to perform
the actual delivery of the messages.
<span class="sub">install</span>
(1) <a href="http://www.glob.com.au/sendmail/sendmail.zip">download sendmail.zip</a>
(2) copy sendmail.exe and sendmail.ini to \usr\lib on the drive where the
unix application is installed.
eg. if your application is installed in c:\bugzilla, sendmail.exe and
sendmail.ini need to be copied to c:\usr\lib\sendmail.exe and
c:\usr\lib\sendmail.ini
(3) configure smtp server and default domain in sendmail.ini
<span class="sub">license and source</span>
this program is released under the <a href="license.txt">bsd license</a>.
the license details and full source (delphi 2007) are included in the zip.
</body>
</html>

Binary file not shown.

View File

@@ -0,0 +1,32 @@
fake sendmail for windows
Copyright (c) 2004-2011, Byron Jones, sendmail@glob.com.au
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the glob nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Binary file not shown.

View File

@@ -0,0 +1,72 @@
; configuration for fake sendmail
; if this file doesn't exist, sendmail.exe will look for the settings in
; the registry, under HKLM\Software\Sendmail
[sendmail]
; you must change mail.mydomain.com to your smtp server,
; or to IIS's "pickup" directory. (generally C:\Inetpub\mailroot\Pickup)
; emails delivered via IIS's pickup directory cause sendmail to
; run quicker, but you won't get error messages back to the calling
; application.
smtp_server=mail.mydomain.com
; smtp port (normally 25)
smtp_port=25
; SMTPS (SSL) support
; auto = use SSL for port 465, otherwise try to use TLS
; ssl = alway use SSL
; tls = always use TLS
; none = never try to use SSL
smtp_ssl=auto
; the default domain for this server will be read from the registry
; this will be appended to email addresses when one isn't provided
; if you want to override the value in the registry, uncomment and modify
;default_domain=mydomain.com
; log smtp errors to error.log (defaults to same directory as sendmail.exe)
; uncomment to enable logging
error_logfile=error.log
; create debug log as debug.log (defaults to same directory as sendmail.exe)
; uncomment to enable debugging
;debug_logfile=debug.log
; if your smtp server requires authentication, modify the following two lines
auth_username=
auth_password=
; if your smtp server uses pop3 before smtp authentication, modify the
; following three lines. do not enable unless it is required.
pop3_server=
pop3_username=
pop3_password=
; force the sender to always be the following email address
; this will only affect the "MAIL FROM" command, it won't modify
; the "From: " header of the message content
force_sender=
; force the sender to always be the following email address
; this will only affect the "RCTP TO" command, it won't modify
; the "To: " header of the message content
force_recipient=
; sendmail will use your hostname and your default_domain in the ehlo/helo
; smtp greeting. you can manually set the ehlo/helo name if required
hostname=

View File

@@ -0,0 +1,932 @@
program sendmail;
{
<license.txt>
fake sendmail for windows
Copyright (c) 2004-2011, Byron Jones, sendmail@glob.com.au
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the glob nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</license.txt>
<ChangeLog.txt>
version 32 (18 june 2011)
- fix handling of invalid recipients
version 31 (15 sep, 2010)
- fix encoding of 8-bit data
version 30 (30 aug, 2010)
- update to latest indy version (fixes many issues)
- add about/version
version 29 (sep 8, 2009)
- fix for another indy 10 "range check error" (when using ssl)
version 28 (aug 12, 2009)
- set ERRORLEVEL to -1 to assist php
version 27 (aug 3, 2009)
- don't treat log write errors as fatal
version 26 (apr 1, 2009)
- no longer require -t parameter
- skip first line if it starts with "from " (mail spool delimiting line)
version 25 (mar 29, 2009)
- added force_recipient
version 24 (dec 2, 2008)
- fixes for ssl
version 23 (apr 24, 2008)
- fix timezone in date header
version 22 (jan 14, 2008)
- fixes to error handling
version 21 (jan 2, 2008)
- added TLS support
version 20 (apr 3, 2007)
- fixed race condition in IIS's pickup delivery
version 19 (jul 24, 2006)
- added support for delivery via IIS's pickup directory
- optionally reads settings from the registry (in absense of the ini file)
version 18 (may 1, 2006)
- fix for indy 10 "range check error"
version 17 (nov 2, 2005)
- only process message header
- optionally use madexcept for detailed crash dumps
version 16 (sep 12, 2005)
- send hostname and domain with HELO/EHLO
- configurable HELO/EHLO hostname
- upgraded to indy 10
version 15 (aug 23, 2005)
- fixes error messages when debug_logfile is not specified
version 14 (jun 28, 2005)
- errors output to STDERR
- fixes for delphi 7 compilation
- added 'connecting to..' debug logging
- reworked error and debug log format
version 13 (jun 8, 2005)
- added fix to work around invalid multiple header instances
version 12 (apr 30, 2005)
- added cc and bcc support
version 11 (feb 17, 2005)
- added pop3 support (for pop before smtp authentication)
version 10 (feb 11, 2005)
- added support for specifying a different smtp port
version 9 (sep 22, 2004)
- added force_sender
version 8 (sep 22, 2004)
- *really* fixes broken smtp auth
version 7 (sep 22, 2004)
- fixes broken smtp auth
version 6 (sep 22, 2004)
- correctly quotes MAIL FROM and RCPT TO addresses in &lt;&gt;
version 5 (sep 16, 2004)
- now sends the message unchanged (rather than getting indy
to regenerate it)
version 4 (aug 17, 2004)
- added debug_logfile parameter
- improved error messages
version 3 (jul 15, 2004)
- smtp authentication support
- clearer error message when missing from or to address
- optional error logging
- adds date: if missing
version 2 (jul 6, 2004)
- reads default domain from registry (.ini setting overrides)
version 1 (jul 1, 2004)
- initial release
</ChangeLog.txt>
requires indy 10.2 or higher
i use a Tiburon branch svn pull
https://svn.atozed.com:444/svn/Indy10/branches/Tiburon
http://www.indyproject.org/Sockets/Docs/Indy10Installation.EN.aspx
}
{$APPTYPE CONSOLE}
{$I IdCompilerDefines.inc}
{$IFNDEF INDY100}indy version 10 is required; built against 10_5_6{$ENDIF}
{$DEFINE USE_MADEXCEPT}
uses
Windows, Classes, SysUtils, Registry, IniFiles,
IdGlobal, IdResourceStringsCore, IdGlobalProtocols, IdResourceStrings, IdExplicitTLSClientServerBase,
IDSmtp, IDPOP3, IdMessage, IdEmailAddress, IdLogFile, IdWinSock2, IdIOHandler, IdSSLOpenSSL, IdException
{$IFDEF USE_MADEXCEPT}
, madExcept, madLinkDisAsm, madListHardware, madListProcesses, madListModules
{$ENDIF}
;
// ---------------------------------------------------------------------------
const
VERSION = '32';
// ---------------------------------------------------------------------------
function buildLogLine(data, prefix: string) : string;
// ensure the output of error and debug logs are in the same format, regardless of source
begin
data := StringReplace(data, EOL, RSLogEOL, [rfReplaceAll]);
data := StringReplace(data, CR, RSLogCR, [rfReplaceAll]);
data := StringReplace(data, LF, RSLogLF, [rfReplaceAll]);
result := FormatDateTime('yy/mm/dd hh:nn:ss', now) + ' ';
if (prefix <> '') then
result := result + prefix + ' ';
result := result + data + EOL;
end;
// ---------------------------------------------------------------------------
type
// TidLogFile using buildLogLine function
TlogFile = class(TidLogFile)
protected
procedure LogReceivedData(const AText, AData: string); override;
procedure LogSentData(const AText, AData: string); override;
procedure LogStatus(const AText: string); override;
public
procedure LogWriteString(const AText: string); override;
end;
// ---------------------------------------------------------------------------
procedure TlogFile.LogReceivedData(const AText, AData: string);
begin
// ignore AText as it contains the date/time
LogWriteString(buildLogLine(Adata, '<<'));
end;
// ---------------------------------------------------------------------------
procedure TlogFile.LogSentData(const AText, AData: string);
begin
// ignore AText as it contains the date/time
LogWriteString(buildLogLine(Adata, '>>'));
end;
// ---------------------------------------------------------------------------
procedure TlogFile.LogStatus(const AText: string);
begin
LogWriteString(buildLogLine(AText, '**'));
end;
// ---------------------------------------------------------------------------
procedure TlogFile.LogWriteString(const AText: string);
begin
// protected --> public
inherited;
end;
// ---------------------------------------------------------------------------
var
errorLogFile: string;
debugLogFile: string;
debug : TlogFile;
// ---------------------------------------------------------------------------
procedure writeToLog(const logFilename, logMessage: string; const prefix: string = '');
var
f: TextFile;
begin
AssignFile(f, logFilename);
try
if (not FileExists(logFilename)) then
begin
ForceDirectories(ExtractFilePath(logFilename));
Rewrite(f);
end
else
Append(f);
write(f, buildLogLine(logMessage, prefix));
closeFile(f);
except
on e:Exception do
writeln(ErrOutput, 'sendmail: Error writing to ' + logFilename + ': ' + logMessage);
end;
end;
// ---------------------------------------------------------------------------
procedure debugLog(const logMessage: string);
begin
if (debug <> nil) and (debug.Active) then
debug.LogWriteString(buildLogLine(logMessage, '**'))
else if (debugLogFile <> '') then
writeToLog(debugLogFile, logMessage, '**');
end;
// ---------------------------------------------------------------------------
procedure errorLog(const logMessage: string);
begin
if (errorLogFile <> '') then
writeToLog(errorLogFile, logMessage, ':');
debugLog(logMessage);
end;
// ---------------------------------------------------------------------------
function appendDomain(const address, domain: string): string;
begin
Result := address;
if (Pos('@', address) <> 0) then
Exit;
Result := Result + '@' + domain;
end;
// ---------------------------------------------------------------------------
function joinMultiple(const messageContent: string; fieldName: string): string;
// the rfc says that some fields are only allowed once in a message header
// for example, to, from, subject
// this function joins multiple instances of the specified field into a single comma seperated line
var
sl : TstringList;
i : integer;
s : string;
n : integer;
count : integer;
values: TstringList;
begin
fieldName := LowerCase(fieldName);
sl := TStringList.Create;
values := TStringList.Create;
try
sl.text := messageContent;
result := '';
// only modify the header if there's more than one instance of the field
count := 0;
for i := 0 to sl.count - 1 do
begin
s := sl[i];
if (s = '') then
break;
n := pos(':', s);
if (n = 0) then
break;
if (lowerCase(copy(s, 1, n - 1)) = fieldName) then
inc(count);
end;
if (count <= 1) then
begin
result := messageContent;
exit;
end;
// more than on instance of the field, combine into single entry, ignore fields with empty values
while (sl.count > 0) do
begin
s := sl[0];
if (s = '') then
break;
n := pos(':', s);
if (n = 0) then
break;
if (lowerCase(copy(s, 1, n - 1)) = fieldName) then
begin
s := trim(copy(s, n + 1, length(s)));
if (s <> '') then
values.Add(s);
end
else
result := result + s + #13#10;
sl.Delete(0);
end;
if (values.count <> 0) then
begin
s := UpCaseFirst(fieldName) + ': ';
for i := 0 to values.count - 1 do
s := s + values[i] + ', ';
setLength(s, length(s) - 2);
result := result + s + #13#10;
end;
result := result + sl.Text;
finally
values.Free;
sl.free;
end;
end;
// ---------------------------------------------------------------------------
function DateTimeToInternetStr(const Value: TDateTime): string;
var
day : word;
month: word;
year : word;
begin
DecodeDate(Value, year, month, day);
Result := Format(
'%s, %d %s %d %s %s',
[
wdays[DayOfWeek(Value)],
day,
monthnames[month],
year,
FormatDateTime('HH":"mm":"ss', Value),
UTCOffsetToStr(OffsetFromUTC, false)
]
);
end;
// ---------------------------------------------------------------------------
{$IFDEF USE_MADEXCEPT}
procedure madExceptionHandler(const exceptIntf: IMEException; var handled: boolean);
var
path: string;
i : integer;
fs : TFileStream;
s : string;
begin
handled := true;
path := extractFilePath(debugLogFile);
deleteFile(path + 'crash-5.txt');
for i := 4 downto 1 do
if (fileExists(path + 'crash-' + intToStr(i) + '.txt')) then
RenameFile(path + 'crash-'+ intToStr(i) + '.txt', path + 'crash-' + intToStr(i + 1) + '.txt');
if (fileExists(path + 'crash.txt')) then
RenameFile(path + 'crash.txt', path + 'crash-1.txt');
fs := TFileStream.Create(path + 'crash.txt', fmCreate);
try
s := exceptIntf.GetBugReport;
fs.Write(s[1], length(s));
finally
fs.free;
end;
ExitProcess(DWORD(-1));
end;
{$ENDIF}
// ---------------------------------------------------------------------------
var
smtpServer : string;
smtpPort : string;
smtpSSL : (ssAuto, ssSSL, ssTLS, ssNone);
defaultDomain : string;
messageContent: string;
authUsername : string;
authPassword : string;
forceSender : string;
forceRcpt : string;
pop3server : string;
pop3username : string;
pop3password : string;
hostname : string;
isPickup : boolean;
reg : TRegistry;
ini : TCustomIniFile;
pop3: TIdPop3;
smtp: TIdSmtp;
i : integer;
s : string;
ss : TStringStream;
msg : TIdMessage;
sl : TStringList;
header: boolean;
fs : TFileStream;
validRecipientCount: integer;
begin
// command line help
if (ParamStr(1) = '-h') then
begin
writeln('fake sendmail version ' + VERSION);
writeln('http://glob.com.au/sendmail');
halt(1);
end;
// read default domain from registry
reg := TRegistry.Create;
try
reg.RootKey := HKEY_LOCAL_MACHINE;
if (reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters')) then
defaultDomain := reg.ReadString('Domain');
finally
reg.Free;
end;
// read ini
s := ChangeFileExt(ParamStr(0), '.ini');
if (FileExists(s)) then
ini := TIniFile.Create(s)
else
begin
ini := TRegistryIniFile.Create('\software');
TRegistryIniFile(ini).RegIniFile.RootKey := HKEY_LOCAL_MACHINE;
TRegistryIniFile(ini).RegIniFile.OpenKey(TRegistryIniFile(ini).FileName, true);
end;
try
smtpServer := ini.ReadString('sendmail', 'smtp_server', 'mail.mydomain.com');
smtpPort := ini.ReadString('sendmail', 'smtp_port', '25');
defaultDomain := ini.ReadString('sendmail', 'default_domain', defaultDomain);
hostname := ini.ReadString('sendmail', 'hostname', '');
errorLogFile := ini.ReadString('sendmail', 'error_logfile', '');
debugLogFile := ini.ReadString('sendmail', 'debug_logfile', '');
authUsername := ini.ReadString('sendmail', 'auth_username', '');
authPassword := ini.ReadString('sendmail', 'auth_password', '');
forceSender := ini.ReadString('sendmail', 'force_sender', '');
forceRcpt := ini.ReadString('sendmail', 'force_recipient', '');
pop3server := ini.ReadString('sendmail', 'pop3_server', '');
pop3username := ini.ReadString('sendmail', 'pop3_username', '');
pop3password := ini.ReadString('sendmail', 'pop3_password', '');
s := LowerCase(ini.ReadString('sendmail', 'smtp_ssl', 'auto'));
if (s = 'ssl') then
smtpSSL := ssSSL
else if (s = 'tls') then
smtpSSL := ssTLS
else if (s = 'none') then
smtpSSL := ssNone
else
smtpSSL := ssAuto;
if (smtpServer = 'mail.mydomain.com') or (defaultDomain = 'mydomain.com') then
begin
writeln(ErrOutput, 'You must configure the smtp_server and default_domain in:');
writeln(ErrOutput, ' ' + ini.fileName);
writeln(ErrOutput, ' or');
writeln(ErrOutput, ' HKLM\Software\Sendmail');
ExitProcess(DWORD(-1));
end;
finally
ini.Free;
end;
if (errorLogFile <> '') and (ExtractFilePath(errorLogFile) = '') then
errorLogFile := ExtractFilePath(ParamStr(0)) + errorLogFile;
if (debugLogFile <> '') and (ExtractFilePath(debugLogFile) = '') then
debugLogFile := ExtractFilePath(ParamStr(0)) + debugLogFile;
isPickup := DirectoryExists(smtpServer);
if (isPickup) then
smtpServer := IncludeTrailingPathDelimiter(smtpServer);
s := ParamStr(1);
if (s <> '') and (s[1] <> '-') and (FileExists(s)) then
begin
// read email from file
fs := TFileStream.Create(ParamStr(1), fmOpenRead + fmShareDenyWrite);
try
setLength(messageContent, fs.Size);
fs.Read(messageContent[1], length(messageContent));
finally
fs.Free;
end;
end
else
begin
// read email from stdin
messageContent := '';
while (not eof(Input)) do
begin
readln(Input, s);
if (messageContent = '') and (copy(s, 1, 5) = 'From ') then
continue;
messageContent := messageContent + s + #13#10;
end;
end;
// make sure message is CRLF delimited
if (pos(#10, messageContent) = 0) then
messageContent := stringReplace(messageContent, #13, #13#10, [rfReplaceAll]);
if (debugLogFile <> '') then
begin
debugLog('--- MESSAGE BEGIN ---');
sl := TStringList.Create;
try
sl.Text := messageContent;
for i := 0 to sl.Count - 1 do
debugLog(sl[i]);
finally
sl.Free;
end;
debugLog('--- MESSAGE END ---');
end;
// fix multiple to, cc, bcc and subject fields
messageContent := joinMultiple(messageContent, 'to');
messageContent := joinMultiple(messageContent, 'cc');
messageContent := joinMultiple(messageContent, 'bcc');
messageContent := joinMultiple(messageContent, 'subject');
// deliver message
{$IFDEF USE_MADEXCEPT}
RegisterExceptionHandler(madExceptionHandler, stTrySyncCallAlways);
{$ENDIF}
try
if (isPickup) then
begin
// drop to IIS's pickup directory
ForceDirectories(smtpServer + 'Temp');
// generate filename (in the temp directory)
setLength(s, MAX_PATH);
if (GetTempFileName(pChar(smtpServer + 'Temp'), 'sm', 0, @s[1]) = 0) then
RaiseLastOSError;
s := strPas(pChar(s));
// write
fs := TFileStream.Create(s, fmCreate);
try
fs.Write(messageContent[1], length(messageContent));
finally
fs.free;
end;
// move into the real pickup directory
if (not RenameFile(s, smtpServer + ChangeFileExt(ExtractFileName(s), '.eml'))) then
RaiseLastOSError;
RemoveDir(smtpServer + 'Temp');
end
else
begin
// deliver via smtp
// load message into stream
ss := TStringStream.Create(messageContent);
msg := nil;
try
// load message
msg := TIdMessage.Create(nil);
try
msg.LoadFromStream(ss, true);
except
on e:exception do
raise exception.create('Failed to read email message: ' + e.message);
end;
// check for from and to
if (forceSender = '') and (Msg.From.Address = '') then
raise Exception.Create('Message is missing sender''s address');
if (forceRcpt = '') and (Msg.Recipients.Count = 0) and (Msg.CCList.Count = 0) and (Msg.BccList.Count = 0) then
raise Exception.Create('Message is missing recipient''s address');
if (debugLogFile <> '') then
begin
try
debug := TlogFile.Create(nil);
debug.FileName := debugLogFile;
debug.Active := True;
except
// silently ignore
debug := nil;
end;
end
else
debug := nil;
if ((pop3server <> '') and (pop3username <> '')) then
begin
// pop3 before smtp auth
debugLog('Authenticating with POP3 server');
pop3 := TIdPOP3.Create(nil);
try
if (debug <> nil) then
begin
pop3.IOHandler := TIdIOHandler.MakeDefaultIOHandler(pop3);
pop3.IOHandler.Intercept := debug;
pop3.IOHandler.OnStatus := pop3.OnStatus;
pop3.ManagedIOHandler := True;
end;
pop3.Host := pop3server;
pop3.Username := pop3username;
pop3.Password := pop3password;
pop3.ConnectTimeout := 10 * 1000;
pop3.Connect;
pop3.Disconnect;
finally
pop3.free;
end;
end;
smtp := TIdSMTP.Create(nil);
try
// if openSSL libraries are available, use SSL for TLS support
smtp.IOHandler := nil;
smtp.ManagedIOHandler := True;
if (smtpSSL <> ssNone) then
begin
try
TIdSSLContext.Create.Free;
smtp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(smtp);
if (smtpSSL = ssAuto) then
if (strToIntDef(smtpPort, 25) = 465) then
smtpSSL := ssSSL
else
smtpSSL := ssTLS;
if (smtpSSL = ssSSL) then
smtp.UseTLS := utUseImplicitTLS
else
smtp.UseTLS := utUseExplicitTLS;
except
on e:exception do
begin
debugLog('Failed to load SSL libraries: ' + e.message);
smtp.IOHandler := nil;
end;
end;
end;
if (smtp.IOHandler = nil) then
begin
smtp.IOHandler := TIdIOHandler.MakeDefaultIOHandler(smtp);
smtp.UseTLS := utNoTLSSupport;
end;
if (debug <> nil) then
begin
smtp.IOHandler.Intercept := debug;
smtp.IOHandler.OnStatus := smtp.OnStatus;
end;
// set host, port
i := pos(':', smtpServer);
if (i = 0) then
begin
smtp.host := smtpServer;
smtp.port := strToIntDef(smtpPort, 25);
end
else
begin
smtp.host := copy(smtpServer, 1, i - 1);
smtp.port := strToIntDef(copy(smtpServer, i + 1, length(smtpServer)), 25);
end;
// set hostname (for helo/ehlo)
if (hostname = '') then
begin
setLength(hostname, 255);
GetHostName(pChar(hostname), length(hostname));
hostname := string(pChar(hostname));
if (pos('.', hostname) = 0) and (defaultDomain <> '') then
hostname := hostname + '.' + defaultDomain;
end;
smtp.HeloName := hostname;
// connect to server
debugLog('Connecting to ' + smtp.Host + ':' + intToStr(smtp.Port));
smtp.ConnectTimeout := 10 * 1000;
smtp.Connect;
// set up authentication
if (authUsername <> '') then
begin
debugLog('Authenticating as ' + authUsername);
smtp.AuthType := satDefault;
smtp.Username := authUsername;
smtp.Password := authPassword;
end;
// authenticate and start tls
smtp.Authenticate;
// sender and recipients
validRecipientCount := 0;
if (forceSender = '') then
smtp.SendCmd('MAIL FROM: <' + appendDomain(Msg.From.Address, defaultDomain) + '>', [250])
else
smtp.SendCmd('MAIL FROM: <' + appendDomain(forceSender, defaultDomain) + '>', [250]);
if (forceRcpt = '') then
begin
for i := 0 to msg.Recipients.Count - 1 do
if (smtp.SendCmd('RCPT TO: <' + appendDomain(Msg.Recipients[i].Address, defaultDomain) + '>', [250, 550]) = 250) then
inc(validRecipientCount)
else
errorLog('Invalid recipient <' + appendDomain(Msg.Recipients[i].Address, defaultDomain) + '>');
for i := 0 to msg.ccList.Count - 1 do
if (smtp.SendCmd('RCPT TO: <' + appendDomain(Msg.ccList[i].Address, defaultDomain) + '>', [250, 550]) = 250) then
inc(validRecipientCount)
else
errorLog('Invalid recipient <' + appendDomain(Msg.ccList[i].Address, defaultDomain) + '>');
for i := 0 to msg.BccList.Count - 1 do
if (smtp.SendCmd('RCPT TO: <' + appendDomain(Msg.BccList[i].Address, defaultDomain) + '>', [250, 550]) = 250) then
inc(validRecipientCount)
else
errorLog('Invalid recipient <' + appendDomain(Msg.BccList[i].Address, defaultDomain) + '>');
end
else
if (smtp.SendCmd('RCPT TO: <' + appendDomain(forceRcpt, defaultDomain) + '>', [250, 550]) = 250) then
inc(validRecipientCount)
else
errorLog('Invalid recipient <' + appendDomain(forceRcpt, defaultDomain) + '>');
if (validRecipientCount = 0) then
raise Exception.Create('No valid recipients were found');
// start message content
smtp.SendCmd('DATA', [354]);
// add date header if missing
if (Msg.Headers.Values['date'] = '') then
smtp.IOHandler.WriteLn('Date: ' + DateTimeToInternetStr(Now));
// send message line by line
sl := TStringList.Create;
try
sl.Text := messageContent;
header := true;
for i := 0 to sl.Count - 1 do
begin
if (i = 0) and (sl[i] = '') then
continue;
if (sl[i] = '') then
header := false;
if (header) and (LowerCase(copy(sl[i], 1, 5)) = 'bcc: ') then
continue;
smtp.IOHandler.WriteLn(sl[i], TIdTextEncoding.Default);
end;
finally
sl.Free;
end;
// done
smtp.SendCmd('.', [250]);
try
smtp.SendCmd('QUIT');
except
on e:EIdConnClosedGracefully do
;// ignore
on e:Exception do
raise;
end;
finally
if (smtp.Connected) then
debugLog('Disconnecting from ' + smtp.Host + ':' + intToStr(smtp.Port));
smtp.Free;
end;
finally
msg.Free;
ss.Free;
end;
end;
except
on e:Exception do
begin
writeln(ErrOutput, 'sendmail: Error during delivery: ' + e.message);
errorLog(e.Message);
{$IFDEF USE_MADEXCEPT}
raise;
{$ELSE}
ExitProcess(DWORD(-1));
{$ENDIF}
end;
end;
end.

View File

@@ -0,0 +1,144 @@
[GeneralSettings]
HandleExceptions=1
AppendMapFileToBinary=1
NoOwnMadExceptSettings=0
CheckFileCrc=1
CheckForFrozenMainThread=0
FreezeTimeout=60000
AutomaticallySaveBugReport=0
AutoSaveBugReportIfNotSent=1
AutomaticallyMailBugReport=0
AutoMailProgressBox=0
CopyBugReportToClipboard=0
SuspendAllRunningThreads=0
ShowPleaseWaitBox=1
PleaseWaitIcon=plwait1
AutomaticallyContinueApplication=0
AutomaticallyRestartApplication=0
AutomaticallyCloseApplication=0
MailAddress=
SendInBackground=1
Send32Icon=send321
MailAsSmtpServer=0
MailAsSmtpClient=0
UploadViaHttp=0
MailViaMapi=1
MailViaMailto=1
SmtpServer=
SmtpPort=25
SmtpAccount=
SmtpPassword=
HttpServer=
HttpPort=80
HttpAccount=
HttpPassword=
BugReportFile=bugreport.txt
AttachBugReport=1
AttachBugReportFile=1
DeleteBugReportFile=1
BugReportSendAs=bugreport.txt
BugReportZip=
ScreenShotDepth=8
ScreenShotAppOnly=0
ScreenShotSendAs=screenshot.png
ScreenShotZip=
AdditionalAttachments=
AppendBugReports=1
BugReportFileSize=100000
DontSaveDuplicateExceptions=1
DontSaveDuplicateFreezings=1
DuplicateExceptionDefinition=1
DuplicateFreezeDefinition=2
ShowExceptionBox=1
OkBtnText=&OK
DetailsBtnText=&Details
PleaseWaitTitle=Information
PleaseWaitText=Please wait a moment...
MailSubject=bug report
MailBody=please find the bug report attached
SendBoxTitle=Sending bug report...
PrepareAttachMsg=Preparing attachments...
MxLookupMsg=Searching for mail server...
ConnectMsg=Connecting to server...
AuthMsg=Authentication...
SendMailMsg=Sending mail...
FieldsMsg=Setting fields...
SendAttachMsg=Sending attachments...
SendFinalizeMsg=Finalizing...
MailFailureMsg=Sorry, sending the bug report didn't work.
VersionVariable=
[ExceptionBox]
ShowButtonMailBugReport=0
ShowButtonSaveBugReport=0
ShowButtonPrintBugReport=0
ShowButtonShowBugReport=1
ShowButtonContinueApplication=1
ShowButtonRestartApplication=1
ShowButtonCloseApplication=1
IconButtonSendBugReport=send1
IconButtonSaveBugReport=save1
IconButtonPrintBugReport=print1
IconButtonShowBugReport=show1
IconButtonContinueApplication=continue1
IconButtonCantContinueApplication=cantContinue1
IconButtonRestartApplication=restart1
IconButtonCloseApplication=close1
FocusedButton=3
SendAssistant=SendAssistant
SaveAssistant=SaveAssistant
PrintAssistant=PrintAssistant
AutomaticallyShowBugReport=0
NoOwnerDrawButtons=0
BigExceptionIcon=big1
TitleBar=%25appname%25
ExceptionMessage=An error occurred in the application.
FrozenMessage=The application seems to be frozen.
BitFaultMsg=The file "%25modname%25" seems to be corrupt!
MailBugReportText=send bug report
SaveBugReportText=save bug report
PrintBugReportText=print bug report
ShowBugReportText=show bug report
ContinueApplicationText=continue application
RestartApplicationText=restart application
CloseApplicationText=close application
[BugReport]
ListThreads=1
ListModules=0
ListHardware=0
ShowCpuRegisters=0
ShowStackDump=1
Disassembly=1
HideUglyItems=0
ShowRelativeAddrs=1
ShowRelativeLines=1
FormatDisassembly=0
LimitDisassembly=5
EnabledPlugins=
[Filters]
Filter1ExceptionClasses=EDBEditError
Filter1DontCreateBugReport=1
Filter1DontCreateScreenshot=1
Filter1DontSuspendThreads=1
Filter1DontCallHandlers=1
Filter1ShowBox=3
Filter1Assis=
Filter2ExceptionClasses=
Filter2DontCreateBugReport=0
Filter2DontCreateScreenshot=0
Filter2DontSuspendThreads=0
Filter2DontCallHandlers=0
Filter2ShowBox=0
Filter2Assis=
GeneralDontCreateBugReport=0
GeneralDontCreateScreenshot=0
GeneralDontSuspendThreads=0
GeneralDontCallHandlers=0
GeneralShowBox=0
GeneralAssis=
[Assistants]
Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm
Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm
Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm
Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00
Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c'%00%00%00in which situation did the error occur?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00
Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00

Binary file not shown.