Отправить письмо с C ++ - PullRequest
       1

Отправить письмо с C ++

20 голосов
/ 04 сентября 2011

Я работаю над проектом на C ++, который включает функцию отправки информации кому-либо в виде «вложения электронной почты».

Все сделано, кроме этой 'электронной почты'. Я не знаю, как сделать эту программу способной отправлять электронную почту без использования почтового клиента или открытия браузера . Я много искал в интернете, но не смог найти ничего работающего (у меня нет знаний о socket, Winsock и т. Д.).

Ответы [ 5 ]

21 голосов
/ 04 сентября 2011

Я не уверен, что согласен с тем, что вы делаете, чтобы шпионить за пользователями за их действиями, но, несмотря на это, здесь есть код C ++, полезный для отправки писем:

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <windows.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

// Insist on at least Winsock v1.1
const VERSION_MAJOR = 1;
const VERSION_MINOR = 1;

#define CRLF "\r\n"                 // carriage-return/line feed pair

void ShowUsage(void)
{
  cout << "Usage: SENDMAIL mailserv to_addr from_addr messagefile" << endl
       << "Example: SENDMAIL smtp.myisp.com rcvr@elsewhere.com my_id@mydomain.com message.txt" << endl;

  exit(1);
}

// Basic error checking for send() and recv() functions
void Check(int iStatus, char *szFunction)
{
  if((iStatus != SOCKET_ERROR) && (iStatus))
    return;

  cerr << "Error during call to " << szFunction << ": " << iStatus << " - " << GetLastError() << endl;
}

int main(int argc, char *argv[])
{
  int         iProtocolPort        = 0;
  char        szSmtpServerName[64] = "";
  char        szToAddr[64]         = "";
  char        szFromAddr[64]       = "";
  char        szBuffer[4096]       = "";
  char        szLine[255]          = "";
  char        szMsgLine[255]       = "";
  SOCKET      hServer;
  WSADATA     WSData;
  LPHOSTENT   lpHostEntry;
  LPSERVENT   lpServEntry;
  SOCKADDR_IN SockAddr;

  // Check for four command-line args
  if(argc != 5)
    ShowUsage();

  // Load command-line args
  lstrcpy(szSmtpServerName, argv[1]);
  lstrcpy(szToAddr, argv[2]);
  lstrcpy(szFromAddr, argv[3]);

  // Create input stream for reading email message file
  ifstream MsgFile(argv[4]);

  // Attempt to intialize WinSock (1.1 or later)
  if(WSAStartup(MAKEWORD(VERSION_MAJOR, VERSION_MINOR), &WSData))
  {
    cout << "Cannot find Winsock v" << VERSION_MAJOR << "." << VERSION_MINOR << " or later!" << endl;

    return 1;
  }

  // Lookup email server's IP address.
  lpHostEntry = gethostbyname(szSmtpServerName);
  if(!lpHostEntry)
  {
    cout << "Cannot find SMTP mail server " << szSmtpServerName << endl;

    return 1;
  }

  // Create a TCP/IP socket, no specific protocol
  hServer = socket(PF_INET, SOCK_STREAM, 0);
  if(hServer == INVALID_SOCKET)
  {
    cout << "Cannot open mail server socket" << endl;

    return 1;
  }

  // Get the mail service port
  lpServEntry = getservbyname("mail", 0);

  // Use the SMTP default port if no other port is specified
  if(!lpServEntry)
    iProtocolPort = htons(IPPORT_SMTP);
  else
    iProtocolPort = lpServEntry->s_port;

  // Setup a Socket Address structure
  SockAddr.sin_family = AF_INET;
  SockAddr.sin_port   = iProtocolPort;
  SockAddr.sin_addr   = *((LPIN_ADDR)*lpHostEntry->h_addr_list);

  // Connect the Socket
  if(connect(hServer, (PSOCKADDR) &SockAddr, sizeof(SockAddr)))
  {
    cout << "Error connecting to Server socket" << endl;

    return 1;
  }

  // Receive initial response from SMTP server
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() Reply");

  // Send HELO server.com
  sprintf(szMsgLine, "HELO %s%s", szSmtpServerName, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() HELO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() HELO");

  // Send MAIL FROM: <sender@mydomain.com>
  sprintf(szMsgLine, "MAIL FROM:<%s>%s", szFromAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() MAIL FROM");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() MAIL FROM");

  // Send RCPT TO: <receiver@domain.com>
  sprintf(szMsgLine, "RCPT TO:<%s>%s", szToAddr, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() RCPT TO");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() RCPT TO");

  // Send DATA
  sprintf(szMsgLine, "DATA%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() DATA");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() DATA");

  // Send all lines of message body (using supplied text file)
  MsgFile.getline(szLine, sizeof(szLine));             // Get first line

  do         // for each line of message text...
  {
    sprintf(szMsgLine, "%s%s", szLine, CRLF);
    Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() message-line");
    MsgFile.getline(szLine, sizeof(szLine)); // get next line.
  } while(MsgFile.good());

  // Send blank line and a period
  sprintf(szMsgLine, "%s.%s", CRLF, CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() end-message");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() end-message");

  // Send QUIT
  sprintf(szMsgLine, "QUIT%s", CRLF);
  Check(send(hServer, szMsgLine, strlen(szMsgLine), 0), "send() QUIT");
  Check(recv(hServer, szBuffer, sizeof(szBuffer), 0), "recv() QUIT");

  // Report message has been sent
  cout << "Sent " << argv[4] << " as email message to " << szToAddr << endl;

  // Close server socket and prepare to exit.
  closesocket(hServer);

  WSACleanup();

  return 0;
}

множество ссылок в Интернете дляпохожая проблема, я нашел это:

http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/12345906-8a17-41c2-846f-fd3e1a135238/

17 голосов
/ 04 сентября 2011

Престижность за то, что вы пытались закодировать это самостоятельно.Это поднимает тебя над обычным сценаристом, детка.

Но позор себя за шпионажем над своим братом.Его частный бизнес - это ЕГО бизнес, и он не принадлежит вам.

Кроме того, если ваш брат немного умен, он не влюбится в какое-нибудь исполняемое вложение электронной почты.Кроме того, большинство почтовых программ и веб-рассылок будут предупреждать против выполнения этой вещи.Если вы хотите сделать эту защиту надежной, вам нужно будет найти уязвимости в используемых почтовых клиентах, чтобы внедрить код, лучший способ - атаковать загрузчик изображений и подпрограммы сжатия, но в идеале вам придется найти 0-й день,в противном случае эти эксплойты могли быть исправлены до того, как вы выпустили шпионское ПО.Некоторые темы, которые вы, возможно, захотите прочитать:

  • эксплойты переполнения стека
  • распыление кучи
  • программирование на основе возврата (используется для противодействия W ^ X-защите и умеренным реализациямрандомизация адресного пространства)

Отправка электронной почты сводится к реализации протокола SMTP, описанного в http://www.faqs.org/rfcs/rfc821.html

Технически можно было отправить электронную почту непосредственно на целевой сервер, но обычно она отклоняетсяписьма, поступающие напрямую через модемные подключения, поскольку это дешевый, но эффективный метод противодействия спаму.Так что вам лучше пройти MTA с правильными записями MX.Freemailers ваш друг, Hotmail очень популярен для этого.Однако тогда вам также придется реализовать SMTP-Auth.Документировано в http://www.faqs.org/rfcs/rfc2554.html

Конечно, вместо отправки электронного письма вы можете просто загрузить файл куда-нибудь.Или вы можете внедрить IMAP и использовать IMAP-совместимый freemailer для хранения данных в каталоге черновиков IMAP.

Так что, если вам удастся выполнить это самостоятельно, с помощью собственного кода, то я думаю, что вы заслуживаете успеха,но только если это не касается сторонних библиотек комплектов конструирования вредоносных программ (да, они существуют).

9 голосов
/ 22 ноября 2015

Рабочее решение для отправки электронной почты с использованием cURL


Загрузите cURL из здесь и извлеките.Теперь запустите исполняемый файл из кода C ++, используя WinExec() из windows.h.

Вот демонстрация для Gmail:

#include <windows.h>

int main(void){
    char* command = "curl smtp://smtp.gmail.com:587 -v --mail-from \"SENDER.EMAIL@gmail.com\" --mail-rcpt \"RECEIVER.EMAIL@gmail.com\" --ssl -u SENDER.EMAIL@gmail.com:PASSWORD -T \"ATTACHMENT.FILE\" -k --anyauth";
    WinExec(command, SW_HIDE);
    return 0;
}

Поместите curl.exe втот же каталог.Введите свой адрес электронной почты и пароль в command.Здесь сообщение сохраняется в текстовом файле (ATTACHMENT.FILE).

Внимание: command может не поддерживать некоторые специальные символы (например, &).


Для более глубокого применения вы можете использовать libcurl .

5 голосов
/ 01 января 2012

indy также имеет компоненты для отправки электронной почты через SMTP

TIdSMTP *IdSMTP1 = new TIdSMTP(this);
IdSMTP1->Host = "myhost";
IdSMTP1->Port = 25;
TIdMessage *MSG = new TIdMessage(this);
MSG->Clear();
MSG->From->Address = "someone@someone.com";
MSG->From->Name = "Someone";
MSG->Subject = "Spy Email";
MSG->Recipients->EMailAddresses = "Watcher@watch.com";
MSG->Body->Text = "your being watched ";
IdSMTP1->Connect();
IdSMTP1->Send(MSG);
IdSMTP1->Disconnect(true);
delete MSG;
delete IdSMTP1;

, и теперь он устанавливается вместе с Builder

3 голосов
/ 04 сентября 2011

Я бы порекомендовал прекрасную библиотеку VMime . Это настоящая библиотека C ++, которая обрабатывает все электронные письма.

Мне также сказали, что cURL имеет поддержку SMTP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...