Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Send Mayl 1.0 beta - sendmayl.c

sendmayl.c

Caricato da: Piero Tofy
Scarica il programma completo

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #ifdef WIN32
  6.   #include <winsock2.h>
  7. #else
  8.   #define SOCKET_ERROR 0
  9.   #include <sys/socket.h>
  10.   #include <netinet/in.h>
  11.   #include <netdb.h>
  12. #endif
  13.  
  14.  
  15.  
  16. #define PROGRAM_NAME "Send Mayl 1.0 Beta"
  17. #define PORT 25
  18. #define MAX_CHAR_LENGTH 60
  19. #define MAX_MESSAGE_LENGTH 4096
  20.  
  21. //Funzione per chiudere il socket, visto che Microsoft deve avere sempre tutto diverso...
  22. #ifdef WIN32
  23. void close(int sock){
  24.   closesocket(sock);
  25.   return;
  26. }
  27. #endif
  28.  
  29.  
  30.  
  31. int init_smtp_sock(char *target);
  32. int send_packet(int sock, char *message);
  33. char *recv_packet(int sock);
  34. int check_ok(char *string);
  35. char *read_input(int maxlength, char *x_char);
  36. int remove_n(char *string);
  37. char *convert_to_mime(char *string, int change_spaces);
  38.  
  39. int main(int argc, char *argv[]){
  40.  //Dichiara le variabili...
  41.  int sock;
  42.  char *target;
  43.  char *mail_from;
  44.  char *mail_to;
  45.  char *subject;
  46.  char *message;
  47.  char *buffer;
  48.  
  49.  //Imposta l'helo...
  50.  char *helo;
  51.  helo=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  52.  strcpy(helo,"helo ");
  53.  strcat(helo,PROGRAM_NAME);
  54.  strcat(helo,"\n\0");
  55.  
  56.  
  57.  //Alloca la memoria...
  58.  target=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  59.  mail_from=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  60.  mail_to=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  61.  subject=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  62.  buffer=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  63.  
  64.  
  65.  printf("%s is starting up...\n\n",PROGRAM_NAME);
  66.  
  67.  printf("SMTP server address (mail.libero.it): ");
  68.  scanf("%s",target);
  69.  
  70.  //Connetti...
  71.  sock=init_smtp_sock(target);
  72.  
  73.  //Libera la memoria di target...
  74.  free(target);
  75.  
  76.  //Riceve il messaggio di benvenuto...
  77.  recv_packet(sock);
  78.  
  79.  //Invia il comando helo...
  80.  send_packet(sock,helo);
  81.  
  82.  //Riceve la risposta ad helo...
  83.  recv_packet(sock);
  84.  
  85.  //Chiede all'utente l'indirizzo del mittente e continua il ciclo finche il server non da l'OK
  86.  do{
  87.  
  88.  printf("Mail From (foo@linux.org): ");
  89.  scanf("%s",mail_from);
  90.  sprintf(buffer,"MAIL FROM:<%s>\n\0",mail_from);
  91.  
  92.  //Invia l'indirizzo del mittente...
  93.  send_packet(sock,buffer);
  94.  
  95.  }while(!check_ok(recv_packet(sock)));
  96.  
  97.  
  98.  //Stesso procedimento per l'indirizzo del destinatario...
  99.  do{
  100.  
  101.  printf("Mail To (victim@linux.org): ");
  102.  scanf("%s",mail_to);
  103.  sprintf(buffer,"RCPT TO:<%s>\n\0",mail_to);
  104.  
  105.  //Invia l'indirizzo del destinatario...
  106.  send_packet(sock,buffer);
  107.  
  108.  }while(!check_ok(recv_packet(sock)));
  109.  
  110. //Invia il comando DATA per iniziare a scrivere l'email...
  111.  send_packet(sock,"DATA\n\0");
  112.  
  113.  //Riceve la conferma con le specifiche per terminare il messaggio...
  114.  recv_packet(sock);
  115.  
  116.  //Invia il comando Message-ID:
  117.  send_packet(sock,"Message-ID:\n\0");
  118.  
  119.  //Invia nuovamente l'indirizzo del mittente... (MIME)
  120.  sprintf(buffer,"FROM:<%s>\n\0",mail_from);
  121.  send_packet(sock,buffer);
  122.  
  123.  //Invia nuovamente l'indirizzo del destinatario... (MIME)
  124.  sprintf(buffer,"TO:<%s>\n\0",mail_to);
  125.  send_packet(sock,buffer);
  126.  
  127.  //Libera la memoria di mail_from, mail_to
  128.  free(mail_from);
  129.  free(mail_to);
  130.  
  131.   //Chiede all'utente un Subject...
  132.  printf("Subject: ");
  133.  
  134.  //(non chiedetemi perchè ho messo 2 volte il comando fgets, ma senza metterlo 2 volte non funziona correttamente...)
  135.  fgets(subject,MAX_CHAR_LENGTH,stdin);
  136.  fgets(subject,MAX_CHAR_LENGTH,stdin);
  137.  remove_n(subject);
  138.  
  139.  //Se è ambiente diverso da windows si può modificare il Subject rendendolo compatibile con lo standard MIME...
  140.  #ifdef WIN32
  141.   //Invia il Subject senza il MIME (windows)
  142.   sprintf(buffer,"Subject: %s\n\0",subject);
  143.   send_packet(sock,buffer);
  144.  #else
  145.   subject=convert_to_mime(subject,1);
  146.   //Invia il Subject con il MIME (linux/unix)
  147.   sprintf(buffer,"Subject: =?iso-8859-1?Q?%s?=\n\0",subject);
  148.   send_packet(sock,buffer);
  149.  #endif
  150.  
  151.  //Chidede l'input per il testo dell'email...
  152.  printf("Message: ");
  153.  message=read_input(MAX_MESSAGE_LENGTH,"\n\n");
  154.  
  155.  //Se è ambiente diverso da windows si può modificare il messaggio rendendolo compatibile con lo standard MIME...
  156.  #ifdef WIN32
  157.   //Invia il messaggio...
  158.   sprintf(buffer,"\n%s\n\0",message);
  159.   send_packet(sock,buffer);
  160.  #else
  161.   //Modifica il messaggio rendendolo compatibile con lo standard MIME...
  162.   message=convert_to_mime(message,0);
  163.   //Invia le informazioni per la codifica...
  164.   send_packet(sock,"Content-Type: text/plain;charset=\"iso-8859-1\"\n\0");
  165.   send_packet(sock,"Content-Transfer-Encoding: quoted-printable\n\0");
  166.   //Invia il messaggio...
  167.   sprintf(buffer,"\n%s\n\0",message);
  168.   send_packet(sock,buffer);
  169.  #endif
  170.  
  171.  //Invia la conferma per l'invio...
  172.  printf("Sending message... ");
  173.  send_packet(sock,".\n\0");
  174.  check_ok(recv_packet(sock)) ? printf("OK\n") : printf("Failed\n");
  175.  
  176.  //Chiude la connessione...
  177.  printf("Closing connection... ");
  178.  send_packet(sock,"QUIT\n\0");
  179.  close(sock);
  180.  printf("OK\n");
  181.  
  182.  
  183.  //Chiude il programma correttamente...
  184.   exit(EXIT_SUCCESS);
  185. }
  186.  
  187.  
  188.  
  189. int remove_n(char *string){
  190.  int len=strlen(string);
  191.  int count;
  192.  
  193.  for(count=0;count<len;count++){
  194.   if (string[count]=='\n') string[count]='\0';
  195.  }
  196.  return 1;
  197. }
  198.  
  199.  
  200. //Ma quanto odio il MIME... tuttavia questa funzione risolve le cose (solo in ambiente linux/unix)
  201.  
  202. char *convert_to_mime(char *string, int change_spaces){
  203.  char *buffer;
  204.  unsigned char ch;
  205.  unsigned int count,pointer;
  206.  
  207.  
  208.  buffer=malloc(sizeof(char)*(strlen(string)*3)+1);
  209.  
  210.  for (count=pointer=0; count<strlen(string); pointer++){
  211.   ch=string[count++];
  212.  
  213.   //Se è un carattere esteso...
  214.   if (ch & 0x80){
  215.    sprintf(buffer+pointer,"=%X",ch);
  216.    pointer+=2;
  217.   }else{
  218.    buffer[pointer]=((change_spaces && ch==' ') ? '_' : ch);
  219.   }
  220.  }
  221.  
  222.  buffer[pointer]='\0';
  223.  return buffer;
  224.  
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231. char *read_input(int maxlength, char *x_char){
  232.  char *buffer;
  233.  char ch;
  234.  int count=0;
  235.  
  236.  buffer=malloc(sizeof(char)*maxlength);
  237.  
  238.  do{
  239.   ch=getchar();
  240.   buffer[count]=ch;
  241.   count++;
  242.  }while(!strstr(buffer,x_char));
  243.  buffer[count]='\0';
  244.  return buffer;
  245. }
  246.  
  247. int check_ok(char *string){
  248.  if(strstr(string,"OK") || strstr(string,"ok") || strstr(string,"250")){
  249.   return 1;
  250.  }else{
  251.   printf("%s\n",string);
  252.   return 0;
  253.  }
  254. }
  255.  
  256.  
  257. int send_packet(int sock, char *message){
  258.  int len=strlen(message);
  259.  
  260.  send(sock,message,len,0);
  261.  return 1;
  262. }
  263.  
  264.  
  265.  
  266. char *recv_packet(int sock){
  267.  char *buffer;
  268.  int res;
  269.  
  270.  buffer=malloc(sizeof(char)*MAX_CHAR_LENGTH);
  271.  
  272.  res=recv(sock,buffer,MAX_CHAR_LENGTH,0);
  273.  
  274.  //Se ha finito, chiude la stringa con il carattere di chiusura.
  275.  if (res>=0){
  276.   *(buffer+res)='\0';
  277.  }
  278.  return buffer;
  279. }
  280.  
  281.  
  282.  
  283.  
  284. int init_smtp_sock(char *target){
  285.  struct sockaddr_in client;
  286.  struct hostent *hostinfo;
  287.  int sock;
  288.  
  289.  //Se l'ambiente è windows bisogna inizializzare il socket...
  290. #ifdef WIN32
  291.  WORD version;
  292.  WSADATA WSAData;
  293.  version=MAKEWORD(1,1);
  294.  WSAStartup(version, &WSAData);
  295. #endif
  296.  
  297.  //Avvia il socket
  298.  printf("Initialyzing the socket... ");
  299.  if ((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR){
  300.   printf("Failed\n");
  301.   exit(EXIT_FAILURE);
  302.  }
  303.  printf("OK\n");
  304.  
  305.  //Risolve il DNS
  306.  printf("Resolving DNS... ");
  307.  hostinfo=gethostbyname(target);
  308.  if (hostinfo==NULL){
  309.   printf("Failed\n");
  310.   exit(EXIT_FAILURE);
  311.  }
  312.  printf("OK\n");
  313.  
  314.  //Imposta la connessione con il server...
  315.  client.sin_family=AF_INET;
  316.  client.sin_addr=*((struct in_addr *)hostinfo->h_addr);
  317.  client.sin_port=htons(PORT);
  318.  
  319.  
  320.  //Si connette al server...
  321.  printf("Connecting to %s... ",target);
  322.  if (connect(sock,(struct sockaddr *)&client, sizeof(client))){
  323.   printf("Failed\n");
  324.   exit(EXIT_FAILURE);
  325.  }
  326.  printf("OK\n\n");
  327.  
  328.  return sock;
  329. }