Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
письмо по SMTP из консоли. Delphi. |

03.08.2009, 21:44
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
письмо по SMTP из консоли. Delphi.
сабж.
требуется отправить письмо на ящик reciever@yandex.ru
сожержащее в body кое-какие данные.
"отпраивтель" - без разницы, главное - содержание письма и его доставка по назначению.
smtp ya.ru: 213.180.204.3 , port: 25.
нарыл код, который вроде реализует через сокеты (не работал с ними раньше)
(нарыл здась: http://forum.antichat.ru/showthread.php?p=671692)
после небольшой редакции компилица, трассируеца... сниффаеца.
Код:
TCP
192.168.0.100 2652
205.188.12.134 5190
132 байт
и, соответственно, нифига не работает так, как должен =\
код:
Код:
program Project1;
uses
SysUtils,
Winsock,
Windows;
{
smtp - ip адрес smtp сервера
port - порт smtp сервера, по умолчанию 25
from - адрес отправителя
dest - адрес получателя
subject - тема письма
body - текст писма
Возвращает True если письмо было успешно отправленно...
}
function mail(smtp: string; port: integer; from, dest, subject, body: string): bool;
const
cl = #13#10;
var
WSAData: TWSAData;
Host: TSockAddrIn;
Sock: TSocket;
res: Integer;
buff: array[1..255] of Char;
{ отправляем данные через сокет }
procedure senddata(str: string);
var
i: integer;
begin
for i := 1 to Length(str) do
if send(Sock, str[i], 1, 0) = SOCKET_ERROR then
exit;
end;
{ получаем ответ от команды }
function recvdata(accept: string): bool;
var
buff: array[1..255] of Char;
begin
res := recv(Sock, buff, SizeOf(buff), 0);
Result := ((Res = SOCKET_ERROR) or (Copy(buff, 1, 3) = accept));
end;
begin
try
result := false;
{ инициализация сокета }
WSAStartUp(257, WSAData);
Sock := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if Sock = INVALID_SOCKET then
Exit;
{ устанавливаем хост и порт сервера }
res := inet_addr(PChar(smtp));
if res <= 0 then
exit;
Host.sin_family := AF_INET;
Host.sin_port := htons(port);
Host.sin_addr.S_addr := res;
{ подключаемся к серверу }
if connect(Sock, Host, SizeOf(Host)) > 0 then
Exit;
{ приветствие сервера }
if not recvdata('220') then
Exit;
{ EHLO }
senddata('EHLO' + cl);
if not recvdata('250') then
Exit;
{ MAIL FROM: }
senddata('MAIL FROM:' + from + cl);
if not recvdata('250') then
Exit;
{ RCPT TO: }
senddata('RCPT TO:' + dest + cl);
if not recvdata('250') then
Exit;
{ DATA }
senddata('DATA' + cl);
if not recvdata('354') then
Exit;
{ отправляем текст сообщения }
senddata('Subject:' + subject + cl + cl + body + cl + '.');
if not recvdata('250') then
Exit;
{ отключаемся от сервера }
senddata('QUIT' + cl);
result := true;
finally
{ убиваем сокет }
closesocket(sock);
WSACleanup;
end;
end;
//----------------------------------------------
begin
mail('213.180.204.3',25,'reciever@yandex.ru' ,'admin@company.mail', 'subj', 'body text');
end.
сабж мне как бэ нужен, так что разбирусь и сам..
но за любую помощь буду признателен.
Как по данному коду, так и по любому другому, _рабочему_ методу отправки e-mail на заранее заданный адрес на заранее заданном почтовике, содержащему в body (или как альтернатива - аттачменте) те или иные "данные" (текстовый файл)
Последний раз редактировалось ErrorNeo; 03.08.2009 в 22:09..
|
|
|

03.08.2009, 22:10
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
Любое письмо так посланное будет скорее всего в спаме.
К таму же тебе нужно не на абы какие адреса слать письма,
а именно на MX шлюзы(потому что тока они принимают письма без авторизации и с левых адресов)
Когдато давно писал примитивную тестовую версию для этих целей
Код:
program sm;
{$APPTYPE CONSOLE}
uses
Windows,WinDNS,Winsock;
function MXResolve(Domain: PChar): string;
var
pQueryResultsSet: PDNS_RECORDA;
Name: PChar;
begin
pQueryResultsSet := nil;
if DnsQuery_A(Domain, DNS_TYPE_MX, DNS_QUERY_STANDARD, nil, @pQueryResultsSet, nil) = 0 then
begin
Result:=pQueryResultsSet^.Data.MX.pNameExchange;
GlobalFree(dword(pQueryResultsSet));
end;
end;
function GetIPAddress(name: string): string;
var
p: PHostEnt;
begin
p:=GetHostByName(PChar(name));
if p=nil then result:=name else
result:=inet_ntoa(PInAddr(p.h_addr_list^)^);
end;
var
buf:array[0..1023] of char;
s:string;
f:textfile;
c:char;
mail_from,mail_to,mail_file:string;
MX_SERVER:string;
WSData:TWSAData;
so:thandle;
ca:sockaddr_in;
begin
writeln('SendMail (C) SLESH (ICQ: 266-334-734)');
writeln('Usage: sm.exe MAIL_FROM MAIL_TO MAIL_FILE');
mail_from:=paramstr(1);
mail_to:=paramstr(2);
mail_file:=paramstr(3);
if (mail_from='') or (mail_to='') or (mail_file='') then exit;
MX_SERVER:=MAIL_TO;
delete(MX_SERVER,1,pos('@',MX_SERVER));
write('[*] WSAStartup...');
if WSAStartup($101, WSData)=-1 then begin write('ERROR');exit;end;
writeln('OK');
write('[*] RESOLVE MX SERVER...');
MX_SERVER:=MXResolve(Pansichar(MX_SERVER));
if MX_SERVER='' then
begin
write('ERROR');
exit;
end;
writeln('OK');
write('[*] RESOLVE IP MX SERVER...');
MX_SERVER:=GetIPAddress(MX_SERVER);
if MX_SERVER='' then
begin
write('ERROR');
exit;
end;
writeln('OK');
write('[*] Create Socket...');
so:=socket(AF_INET, SOCK_STREAM, 0);
if so=-1 then begin
writeln('ERROR');
exit;
end;
writeln('OK');
ca.sin_family:=AF_INET;
ca.sin_port:=htons(25);
ca.sin_addr.s_addr:=inet_addr(Pansichar(MX_SERVER));
write('[*] Connect to server...');
if connect(so,ca,sizeof(ca))=-1 then begin
closesocket(so);
writeln('ERROR');
exit;
end;
writeln('OK');
recv(so,buf,sizeof(buf),0);
s:='EHLO server'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'250' then
begin
writeln('[-] HELO ERROR');
writeln(buf);
exit;
end;
s:='MAIL FROM:<'+MAIL_FROM+'>'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'250' then
begin
writeln('[-] MAIL FROM ERROR');
writeln(buf);
exit;
end;
s:='RCPT TO:<'+MAIL_TO+'>'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'250' then
begin
writeln('[-] RCPT TO ERROR');
writeln(buf);
exit;
end;
s:='DATA'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'354' then
begin
writeln('[-] DATA ERROR');
writeln(buf);
exit;
end;
assignfile(f,mail_file);
reset(f);
while not eof(f) do begin
readln(f,s);
s:=s+#13#10;
send(so,s[1],length(s),0);
end;
closefile(f);
s:=#13#10+'.'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'250' then
begin
writeln('[-] SEND ERROR');
writeln(buf);
exit;
end;
s:='QUIT'+#13#10;
send(so,s[1],length(s),0);
recv(so,buf,sizeof(buf),0);
if copy(buf,1,3)<>'221' then
begin
writeln('[-] QUIT ERROR');
writeln(buf);
exit;
end;
closehandle(so);
writeln('[+] SEND OK');
end.
Для работу нужен модуль WinDNS - его можно где угодно найти в инете.
или если нужно то вот.
Код:
//******************************************************************************
// Nom : WinDns.pas
// Utilisation : Fonction et Type pour l'acces a DnsApi.dll
// Auteur : uncle_khemi@hotmail.com
// Date : 27 Aout 2003
//
// Modifications :
// Date :
//******************************************************************************
unit WinDNS;
interface
uses
Windows;
const
// Options for DnsQuery
DNS_QUERY_STANDARD = 0;
DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 1;
DNS_QUERY_USE_TCP_ONLY = 2;
DNS_QUERY_NO_RECURSION = 4;
DNS_QUERY_BYPASS_CACHE = 8;
//autres
DNS_ATMA_MAX_ADDR_LENGTH = 20;
DNS_ATMA_AESA_ADDR_LENGTH = 20;
DNS_TYPE_A = 1;
DNS_TYPE_CNAME = 5;
DNS_TYPE_PTR = 12;
DNS_TYPE_MX = 15;
DNS_UPDATE_SECURITY_USE_DEFAULT = 0;
type
IP6_ADDRESS = array[0..3] of dword;
IP4_ADDRESS = DWORD;
DNS_A_DATA = IP4_ADDRESS;
DNS_PTR_DATA = PChar;
DNS_PTR_DATAA = DNS_PTR_DATA;
DNS_PTR_DATAW = DNS_PTR_DATA;
DNS_AAAA_DATA = IP6_ADDRESS;
DNS_STATUS = LongInt;
PIP4_ARRAY = ^IP4_ARRAY;
//validation d'un nom DNS
DNS_NAME_FORMAT = (DnsNameDomain,
DnsNameDomainLabel,
DnsNameHostnameFull,
DnsNameHostnameLabel,
DnsNameWildcard,
DnsNameSrvRecord);
//definie le type de liberation pour avec DnsFreeRecordList
DNS_FREE_TYPE = (
DnsFreeFlat,
DnsFreeRecordList,
DnsFreeParsedMessageFields
);
//tableau d'adresse IP
IP4_ARRAY = record
AddrCount: DWORD;
AddrArray: array[0..10] of IP4_ADDRESS; //[0..10]
end;
DNS_SRV_DATAA = record
pNameTarget: PChar;
wPriority: Word;
wWeighty: Word;
wPorty: Word;
Pady: Word; // keep ptrs DWORD aligned
end;
DNS_TSIG_DATAA = record
pNameAlgorithm: PChar;
pAlgorithmPacket: ^Byte;
pSignature: ^Byte;
pOtherData: ^Byte;
i64CreateTime: longlong;
wFudgeTime: Word;
wOriginalXid: Word;
wError: Word;
wSigLength: Word;
wOtherLength: Word;
cAlgNameLength: UCHAR;
bPacketPointers: Boolean;
end;
DNS_NXT_DATAA = record
pNameNext: PChar;
wNumTypes: Word;
wTypes: array[0..1] of Word;
end;
DNS_WINSR_DATA = record
dwMappingFlag: DWORD;
dwLookupTimeout: DWORD;
dwCacheTimeout: DWORD;
pNameResultDomain: PWideChar;
end;
DNS_WINSR_DATAA = record
dwMappingFlag: DWORD;
dwLookupTimeout: DWORD;
dwCacheTimeout: DWORD;
pNameResultDomain: PChar;
end;
DNS_RECORD_FLAGS = record
Section: DWORD; //DWORD Section : 2;
Delete: DWORD; //DWORD Delete : 1;
CharSet: DWORD; //DWORD CharSet : 2;
Unused: DWORD; //DWORD Unused : 3;
Reserved: DWORD; //DWORD Reserved : 24;
end;
DNS_TXT_DATAA = record
dwStringCount: DWORD;
pStringArray: array[0..10] of PChar;
end;
DNS_NULL_DATA = record
dwByteCount: DWORD;
Data: array[0..10] of Byte;
end;
DNS_KEY_DATA = record
wFlags: Word;
chProtocol: Byte;
chAlgorithm: Byte;
Key: array[0..0] of Byte;
end;
DNS_SIG_DATAA = record
pNameSigner: PChar;
wTypeCovered: Word;
chAlgorithm: Byte;
chLabelCount: Byte;
dwOriginalTtl: DWORD;
dwExpiration: DWORD;
dwTimeSigned: DWORD;
wKeyTag: Word;
Pad: Word; // keep Byte field aligned
Signature: array[0..0] of Byte;
end;
DNS_ATMA_DATA = record
AddressType: Byte;
Address: array[0..(DNS_ATMA_MAX_ADDR_LENGTH - 1)] of Byte;
end;
DNS_WKS_DATA = record
IpAddress: IP4_ADDRESS;
chProtocol: UCHAR;
BitMask: array[0..0] of Byte; // BitMask[1];
end;
DNS_MX_DATAA = record
pNameExchange: PChar;
wPreference: Word;
Pad: Word;
end;
DNS_MINFO_DATAA = record
pNameMailbox: PChar;
pNameErrorsMailbox: PChar;
end;
DNS_WINS_DATA = record
dwMappingFlag: DWORD;
dwLookupTimeout: DWORD;
dwCacheTimeout: DWORD;
cWinsServerCount: DWORD;
WinsServers: array[0..0] of IP4_ADDRESS;
end;
DNS_TKEY_DATAA = record
pNameAlgorithm: PChar;
pAlgorithmPacket: ^Byte;
pKey: ^Byte;
pOtherData: ^Byte;
dwCreateTime: DWORD;
dwExpireTime: DWORD;
wMode: Word;
wError: Word;
wKeyLength: Word;
wOtherLength: Word;
cAlgNameLength: UCHAR;
bPacketPointers: Boolean;
end;
DNS_SOA_DATAA = record
pNamePrimaryServer: PChar;
pNameAdministrator: PChar;
dwSerialNo: DWORD;
dwRefresh: DWORD;
dwRetry: DWORD;
dwExpire: DWORD;
dwDefaultTtl: DWORD;
end;
//probleme non resolu lorsqu'on utilise les flags de type S
TFlags = record
case Integer of
1: (DW: DWORD); // flags as DWORD
2: (S: ^DNS_RECORD_FLAGS); // flags as structure ???
end;
TDataA = record
case Integer of
1: (A: DNS_A_DATA); // A;
2: (SOA: DNS_SOA_DATAA); // SOA, Soa;
3: (PTR: DNS_PTR_DATAA); //PTR, Ptr, NS, Ns, CNAME, Cname, MB, Mb, MD, Md, MF, Mf, MG, Mg, MR, Mr;
4: (MINFO: DNS_MINFO_DATAA); //MINFO, Minfo, RP, Rp;
5: (MX: DNS_MX_DATAA); //MX, Mx, AFSDB, Afsdb, RT, Rt;
6: (HINFO: DNS_TXT_DATAA); //HINFO, Hinfo, ISDN, Isdn, TXT, Txt, X25;
7: (Null: DNS_NULL_DATA); //Null;
8: (WKS: DNS_WKS_DATA); //WKS, Wks;
9: (AAAA: DNS_AAAA_DATA); //AAAA;
10: (KEY: DNS_KEY_DATA); //KEY, Key;
11: (SIG: DNS_SIG_DATAA); //SIG, Sig;
12: (ATMA: DNS_ATMA_DATA); //ATMA, Atma;
13: (NXT: DNS_NXT_DATAA); //NXT, Nxt;
14: (SRV: DNS_SRV_DATAA); //SRV, Srv;
15: (TKEY: DNS_TKEY_DATAA); //TKEY, Tkey;
16: (TSIG: DNS_TSIG_DATAA); //TSIG, Tsig;
17: (DWINS: DNS_WINS_DATA); //WINS, Wins;
18: (WINSR: DNS_WINSR_DATA); //WINSR, WinsR, NBSTAT, Nbstat;
end;
PDNS_RECORDA = ^DNS_RECORDA;
DNS_RECORDA = record
pnext: PDNS_RECORDA; // struct _DnsRecordW *
pName: PChar; //PSTR
wType: Word; //WORD //WORD wType;
wDataLength: Word; //WORD
flags: TFlags; //
dwTtl: DWORD; //DWORD;
dwReserved: DWORD; //DWORD;
Data: TDataA;
end;
//------------------------------------------------------------------------------
//Fonctions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//voir un enregistrement
function DnsQuery_A(
pszName: PChar;
wType: Word;
Options: DWORD;
aipServers: PIP4_ARRAY;
ppQueryResults: Pointer;
pReserved: Pointer
): DNS_STATUS; stdcall; external 'dnsapi.dll';
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//ajouter, modifier et supprimer un enregistrement
function DnsModifyRecordsInSet_A(
pAddRecords: PDNS_RECORDA;
pDeleteRecords: PDNS_RECORDA;
Options: DWORD;
hContext: Hwnd;
pServerList: PIP4_ARRAY;
pReserved: Pointer
): DNS_STATUS; stdcall; external 'dnsapi.dll';
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//verifie si un nom DNS est correct
function DnsValidateName_A(
pszName: PChar;
Format: DNS_NAME_FORMAT
): DNS_STATUS; stdcall; external 'dnsapi.dll';
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//supprime la memoire aloue pour la reponse par un DNS_QUERY
procedure DnsRecordListFree(
pRecordList: PDNS_RECORDA;
FreeType: DNS_FREE_TYPE
); stdcall; external 'dnsapi.dll';
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//supprime la memoire aloue pour la reponse par un DNS_QUERY
//procedure DnsFreeRecordListDeep(
// pRecordList: PDNS_RECORDA;
// FreeType: DNS_FREE_TYPE
// ); stdcall; external 'dnsapi.dll';
//------------------------------------------------------------------------------
implementation
end.
|
|
|

03.08.2009, 22:13
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
но знай - если у почтовика стоит SPF фильтр, то забудь про такой метод отправки.
|
|
|

03.08.2009, 22:33
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
Дата: <date here, cut out>
От кого: sadrick@yandex.ru Это не спам… В адресную книгу… В белый список…
Кому: Noaddress
Тема: (Без темы) РаспечататьВ виде HTMLСвойства письма
koi8 | win | dos | utf-8 | mac
<message here, cut out>
+15, slesh
it works!
Последний раз редактировалось ErrorNeo; 04.08.2009 в 12:31..
|
|
|

03.08.2009, 22:49
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
Ну яндекс самый лоальный к такого роду письмам.
А вот на AOL, HOTMAIL и MAIL.RU ты врядли вообще сможешь отправить сообщение.
|
|
|

04.08.2009, 15:32
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
*отправил себе примерно 10 сообщений, поленился удалить их из спама - сервер блокнул дальнейший прием сообщений с того IP. Разумно.
*как добавлять аттачменты(этим методом) - не фкурил, но, почитав фак по командам SMTP пришел к выводу, что скорее всего никак.
(http://book.itep.ru/4/44/smtp4414.htm - неплохой фак)
*данные, содержищие специальные и не читаемые символы можно удобно пересылать, предварительно проеобразовав их в hex формат.
|
|
|

04.08.2009, 22:42
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
4 функции для преобразования текста в hex и обратно:
построчно и по-символьно.
Если вдруг вам когда-либо нужно будет надо переслать себе по почте(из консоли) файл, содержащий служебные или спец. символы...
Код:
{преобразовать строку в 16-ричный формат}
function StringToHex(S: String): String;
var I: Integer;
begin
Result:= '';
for I := 1 to length (S) do
Result:= Result+IntToHex(ord(S[i]),2);
end;
{преобразовать символ в 16-ричный формат}
function ChrToHex(S: Char): String;
begin
Result:= IntToHex(ord(S),2);
end;
{преобразовать строку в 16-ричном формате обратно в текст}
function HexToString(H: String): String;
var I: Integer;
begin
Result:= '';
for I := 1 to length (H) div 2 do
Result:= Result+Char(StrToInt('$'+Copy(H,(I-1)*2+1,2)));
end;
{преобразовать "символ" в 16-ричном формате в обычный символ}
function HexToChr(H: String): Char;
begin
Result:= Char(StrToInt('$'+Copy(H,1,2)));
end;
очень удобно. И не надо никаких аттачментов.
Последний раз редактировалось ErrorNeo; 04.08.2009 в 22:57..
|
|
|

04.08.2009, 22:57
|
|
Banned
Регистрация: 12.07.2008
Сообщений: 206
Провел на форуме: 801258
Репутация:
33
|
|
Чувак взгляни на это.....
http://www.glob.com.au/sendmail/sendmail.zip
Работает 100% !!!!
|
|
|

04.08.2009, 23:24
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
Сообщение от aqqa
Чувак взгляни на это.....
http://www.glob.com.au/sendmail/sendmail.zip
Работает 100% !!!!
хорошая ссылка, пусть тоже будет тут.
зы. 100% того, мне было "нужно" я уже реализовал с помощью кода slesh. Причем, как и хотел, с использованием одного лишь winsock.
Сюда же докидываю инфу, которая может в дальнейшем пригодиться тем, кому так же как и мне нужно будет наладить пересылку сообщений (и файлов) по SMTP из консоли средствами одного лишь win-api
|
|
|

05.08.2009, 21:10
|
|
Moderator - Level 7
Регистрация: 02.05.2009
Сообщений: 894
Провел на форуме: 4297091
Репутация:
2261
|
|
обратил внимание, что на этот код просто _нереально_ "обозлилась" целая куча а-вирей. =\
Не кошерно.
Использовать 'as is' нельзя.
Проблема, как ни странно, решается редактированием всего-лишь одной строки кода.
Последний раз редактировалось ErrorNeo; 05.08.2009 в 21:58..
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|