web-dev-qa-db-fra.com

Envoyer un e-mail avec pièce jointe en C ++

Je travaille sur un projet en C++, qui comprend une fonction d'envoi d'informations à quelqu'un en tant que "pièce jointe à un e-mail".

Tout est fait sauf cette chose "e-mail". Je ne sais pas comment rendre ce programme capable d'envoyer un e-mail sans utiliser de client de messagerie ni ouvrir de navigateur. J'ai beaucoup cherché sur Internet mais je n'ai rien trouvé de fonctionnel (je n'ai aucune connaissance de socket, Winsock, etc.).

20
Mohammad Salman

Je ne suis pas sûr d'être d'accord avec ce que vous faites pour espionner les utilisateurs sur ce qu'ils font, mais malgré tout, voici du code C++ utile pour envoyer des e-mails:

#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 [email protected] [email protected] 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: <[email protected]>
  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: <[email protected]>
  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;
}

beaucoup de liens sur Internet pour un problème similaire, j'ai trouvé ceci:

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

22
Davide Piras

Bravo à vous pour avoir essayé de le coder vous-même. Cela vous élève au-dessus du kiddy de script moyen.

Mais faites-vous honte d'espionner votre frère. Son entreprise privée est SON entreprise et aucune des vôtres.

De plus, si votre frère n'est qu'un peu intelligent, il ne tombera pas pour une pièce jointe exécutable. De plus, la plupart des programmes de messagerie et des webmailers mettront en garde contre l'exécution de cette chose. Si vous deviez faire cela à toute épreuve, vous auriez besoin de trouver des vulnérabilités dans le ou les clients de messagerie utilisés, pour injecter du code, la meilleure façon de procéder est d'attaquer le chargeur d'images et les routines de compression, mais vous devrez trouver un 0day idéalement, sinon, ces exploits peuvent avoir été corrigés avant que vous ne sortiez votre logiciel espion. Certains sujets que vous voudrez peut-être lire sont

  • exploits de débordement de pile
  • heap spraying
  • programmation basée sur le retour (utilisée pour contrer la protection W ^ X et les implémentations douces de la randomisation de l'espace d'adressage)

L'envoi d'e-mails se résume à implémenter le protocole SMTP documenté dans http://www.faqs.org/rfcs/rfc821.html

Techniquement, on pourrait envoyer un e-mail directement à un serveur cible, mais ceux-ci rejetteront généralement les e-mails provenant directement des connexions d'accès à distance, car il s'agit d'une méthode bon marché mais efficace pour lutter contre le spam. Donc, vous feriez mieux de passer en revue un MTA avec des enregistrements MX appropriés. Les freemailers sont vos amis, Hotmail est très populaire pour cela. Cependant, vous devrez également implémenter SMTP-Auth. Documenté en http://www.faqs.org/rfcs/rfc2554.html

Bien sûr, au lieu d'envoyer un e-mail, vous pouvez tout aussi bien télécharger un fichier quelque part. Ou vous pouvez implémenter IMAP et utiliser un freemailer compatible IMAP pour stocker les données dans le répertoire des brouillons IMAP.

Donc, si vous parvenez à le faire vous-même, avec votre propre code, je pense que vous méritez le succès, mais seulement si cela n'implique pas des bibliothèques tierces de kits de construction de logiciels malveillants (oui, ils existent).

18
datenwolf

Une solution de travail pour envoyer des e-mails à l'aide de cURL


Téléchargez cURL à partir de ici et extrayez. Maintenant, exécutez l'exécutable à partir du code C++ en utilisant WinExec() from windows.h.

Voici une démonstration pour Gmail:

#include <windows.h>

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

Placez curl.exe dans le même répertoire. Saisissez votre adresse e-mail et votre mot de passe dans command. Ici, le message est enregistré dans un fichier texte (ATTACHMENT.FILE).

Attention: command peut ne pas prendre en charge certains caractères spéciaux (comme- &).


Pour une application plus approfondie, vous pouvez tilisez libcurl .

9
Minhas Kamal

indy possède également des composants pour l'envoi d'e-mails via SMTP

TIdSMTP *IdSMTP1 = new TIdSMTP(this);
IdSMTP1->Host = "myhost";
IdSMTP1->Port = 25;
TIdMessage *MSG = new TIdMessage(this);
MSG->Clear();
MSG->From->Address = "[email protected]";
MSG->From->Name = "Someone";
MSG->Subject = "Spy Email";
MSG->Recipients->EMailAddresses = "[email protected]";
MSG->Body->Text = "your being watched ";
IdSMTP1->Connect();
IdSMTP1->Send(MSG);
IdSMTP1->Disconnect(true);
delete MSG;
delete IdSMTP1;

et il est installé avec Builder maintenant

5
Shaun07776

Je devrais recommander la bibliothèque fine VMime . C'est une véritable bibliothèque C++ et gère tout le courrier électronique.

On me dit également que cURL a un support SMTP.

3
Kerrek SB