Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2015
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.81 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <netinet/in.h>
  6. #include <netdb.h>
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <openssl/bio.h>
  11. #include <openssl/ssl.h>
  12. #include <openssl/err.h>
  13.  
  14. #ifndef __cplusplus
  15. typedef enum {false, true} bool;
  16. #endif
  17.  
  18. bool ssl_init_count = 0;
  19.  
  20. typedef struct
  21. {
  22.     int sock;
  23.     const char* address;
  24.     unsigned short port;
  25. } sock_info;
  26.  
  27. typedef struct
  28. {
  29.     SSL* ssl;
  30.     SSL_CTX* ctx;
  31. } ssl_info;
  32.  
  33. typedef struct
  34. {
  35.     char b64username[256];
  36.     char b64password[256];
  37. } email;
  38.  
  39. bool initsocket()
  40. {
  41.     #if defined _WIN32 || defined _WIN64
  42.     WSADATA wsaData = {0};
  43.     return !WSAStartup(MAKEWORD(2, 2), &wsaData);
  44.     #else
  45.     return true;
  46.     #endif
  47. }
  48.  
  49. void destroysocket(sock_info* info)
  50. {
  51.     #if defined _WIN32 || defined _WIN64
  52.     shutdown(info->sock, SD_BOTH);
  53.     closesocket(info->sock);
  54.     WSACleanup();
  55.     #else
  56.     shutdown(info->sock, SHUT_RDWR);
  57.     close(info->sock);
  58.     #endif
  59. }
  60.  
  61. bool connectsocket(sock_info* info)
  62. {
  63.     struct sockaddr_in* sockaddr_ipv4 = NULL;
  64.     struct addrinfo* it = NULL, *result = NULL;
  65.     getaddrinfo(info->address, NULL, NULL, &result);
  66.  
  67.     for (it = result; it != NULL; it = it->ai_next)
  68.     {
  69.         sockaddr_ipv4 = (struct sockaddr_in*)it->ai_addr;
  70.         info->address = inet_ntoa(sockaddr_ipv4->sin_addr);
  71.  
  72.         if (strncmp(info->address, "0.0.0.0", 7))
  73.             break;
  74.     }
  75.     freeaddrinfo(result);
  76.  
  77.     if ((info->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  78.     {
  79.         perror("Error creating socket..");
  80.         return false;
  81.     }
  82.  
  83.     struct sockaddr_in SockAddr;
  84.     memset(&SockAddr, 0, sizeof(SockAddr));
  85.     SockAddr.sin_port = htons(info->port);
  86.     SockAddr.sin_family = AF_INET;
  87.     SockAddr.sin_addr.s_addr = inet_addr(info->address);
  88.  
  89.     if (connect(info->sock, (struct sockaddr*)&SockAddr, sizeof(SockAddr)) < 0)
  90.     {
  91.         perror("Error connecting socket..");
  92.         return false;
  93.     }
  94.  
  95.     return true;
  96. }
  97.  
  98. bool setssl(sock_info* sockinfo, ssl_info* sslinfo)
  99. {
  100.     sslinfo->ctx = SSL_CTX_new(SSLv23_client_method());
  101.  
  102.     if (sslinfo->ctx)
  103.     {
  104.         sslinfo->ssl = SSL_new(sslinfo->ctx);
  105.         SSL_set_fd(sslinfo->ssl, sockinfo->sock);
  106.         return SSL_connect(sslinfo->ssl) != -1;
  107.     }
  108.     return false;
  109. }
  110.  
  111. void removessl(sock_info* sockinfo, ssl_info* sslinfo)
  112. {
  113.     if (sslinfo->ctx)
  114.     {
  115.         SSL_CTX_free(sslinfo->ctx);
  116.     }
  117.  
  118.     if (sslinfo->ssl)
  119.     {
  120.         SSL_shutdown(sslinfo->ssl);
  121.         SSL_free(sslinfo->ssl);
  122.     }
  123.  
  124.     sslinfo->ssl = NULL;
  125.     sslinfo->ctx = NULL;
  126. }
  127.  
  128. void initssl()
  129. {
  130.     if (!ssl_init_count)
  131.     {
  132.         SSL_library_init();
  133.         SSL_load_error_strings();
  134.         OpenSSL_add_all_algorithms();
  135.     }
  136.  
  137.     ++ssl_init_count;
  138. }
  139.  
  140. void freessl()
  141. {
  142.     --ssl_init_count;
  143.     if (!ssl_init_count)
  144.     {
  145.         ERR_free_strings();
  146.         EVP_cleanup();
  147.         CRYPTO_cleanup_all_ex_data();
  148.     }
  149. }
  150.  
  151. void sslb64encode(const char* buffer, char* outbuffer)
  152. {
  153.     char* b64str = NULL;
  154.     BIO* b64 = BIO_new(BIO_f_base64());
  155.     BIO* mem = BIO_new(BIO_s_mem());
  156.  
  157.     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  158.     b64 = BIO_push(b64, mem);
  159.     BIO_write(b64, buffer, strlen(buffer));
  160.     BIO_flush(b64);
  161.  
  162.     int len = BIO_get_mem_data(mem, &b64str);
  163.     memcpy(outbuffer, b64str, len);
  164.     outbuffer[len] = '\0';
  165.     BIO_free_all(b64);
  166. }
  167.  
  168. void initemail(const char* username, const char* password, email* outemail)
  169. {
  170.     char ubuffer[256];
  171.     char pbuffer[256];
  172.     unsigned int bytes_written = 0;
  173.  
  174.     sslb64encode(username, &ubuffer[0]);
  175.     sslb64encode(password, &pbuffer[0]);
  176.  
  177.     sprintf(outemail->b64username, "%s", ubuffer);
  178.     sprintf(outemail->b64password, "%s", pbuffer);
  179. }
  180.  
  181. bool printsocketbuffer(ssl_info* sslinfo)
  182. {
  183.     char buffer[1024];
  184.     unsigned int bytes_read = SSL_read(sslinfo->ssl, &buffer[0], sizeof(buffer));
  185.     if (bytes_read > 0)
  186.     {
  187.         printf("%.*s", bytes_read, buffer);
  188.         return true;
  189.     }
  190.     return false;
  191. }
  192.  
  193. void sendemail(ssl_info* sslinfo, const char* username, const char* password, const char* recipient, const char* from, const char* to, const char* message, const char* subject, unsigned int messagelen)
  194. {
  195.     email em;
  196.     char buffer[512];
  197.     unsigned int bufflen = sizeof(buffer);
  198.     initemail(username, password, &em);
  199.  
  200.     SSL_write(sslinfo->ssl, "EHLO wolferine\r\n", 16);
  201.     printsocketbuffer(sslinfo);
  202.  
  203.     SSL_write(sslinfo->ssl, "AUTH LOGIN\r\n", 12);
  204.     printsocketbuffer(sslinfo);
  205.  
  206.     bufflen = sprintf(buffer, "%s\r\n", em.b64username);
  207.     SSL_write(sslinfo->ssl, buffer, bufflen);
  208.     printsocketbuffer(sslinfo);
  209.  
  210.     bufflen = sprintf(buffer, "%s\r\n", em.b64password);
  211.     SSL_write(sslinfo->ssl, buffer, bufflen);
  212.     printsocketbuffer(sslinfo);
  213.     printsocketbuffer(sslinfo);
  214.  
  215.     bufflen = sprintf(buffer, "MAIL FROM: <%s>\r\n", username);
  216.     SSL_write(sslinfo->ssl, buffer, bufflen);
  217.     printsocketbuffer(sslinfo);
  218.  
  219.     bufflen = sprintf(buffer, "RCPT TO: <%s>\r\n", recipient);
  220.     SSL_write(sslinfo->ssl, buffer, bufflen);
  221.     printsocketbuffer(sslinfo);
  222.  
  223.     SSL_write(sslinfo->ssl, "DATA\r\n", 6);
  224.     printsocketbuffer(sslinfo);
  225.  
  226.     bufflen = sprintf(buffer, "From: <%s><%s>\r\n", from, username);
  227.     bufflen += sprintf(&buffer[bufflen], "To: <%s><%s>\r\n", to, recipient);
  228.     bufflen += sprintf(&buffer[bufflen], "Subject: <%s>\r\n", subject);
  229.     SSL_write(sslinfo->ssl, buffer, bufflen);
  230.  
  231.     bufflen = 0;
  232.     while (bufflen < messagelen)
  233.     {
  234.         bufflen += SSL_write(sslinfo->ssl, &message[bufflen], messagelen - bufflen);
  235.     }
  236.  
  237.     SSL_write(sslinfo->ssl, "\r\n.\r\n", 5);
  238.     printsocketbuffer(sslinfo);
  239.  
  240.     SSL_write(sslinfo->ssl, "QUIT\r\n", 6);
  241.     printsocketbuffer(sslinfo);
  242. }
  243.  
  244. int main()
  245. {
  246.     ssl_info sslinfo = {0};
  247.     sock_info sockinfo = {0, "smtp.mail.ru", 465};
  248.  
  249.     const char* username = "d_tabriz@mail.ru";
  250.     const char* password = "password";
  251.     const char* recipient = "tabriz94@gmail.com";
  252.     const char* message = "hello there! sended from terminal";
  253.     const char* subject = "Test Subject";
  254.     const char* from = "wolferine";
  255.     const char* to = "test mail";
  256.     unsigned int messagelen = strlen(message);
  257.  
  258.  
  259.     if (initsocket())
  260.     {
  261.         if (connectsocket(&sockinfo))
  262.         {
  263.             initssl();
  264.  
  265.             if (setssl(&sockinfo, &sslinfo))
  266.             {
  267.                 sendemail(&sslinfo, username, password, recipient, from, to, message, subject, messagelen);
  268.             }
  269.             else
  270.             {
  271.                 ERR_print_errors_fp(stderr);
  272.             }
  273.  
  274.             removessl(&sockinfo, &sslinfo);
  275.             freessl();
  276.         }
  277.  
  278.         destroysocket(&sockinfo);
  279.     }
  280.  
  281.     return 0;
  282. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement