Breakermind Temat założony przez niniejszego użytkownika |
C++ ssl smtp email client with mx from dns » 2017-11-13 14:44:05 Witam czy może ktoś wysłać email i testnąć (mam bana na sieci na port 25) Ps. W ovh.pl sieroty nie potrafią Debiana przeinstalować przez 6 godzin (a cały weekend serwer nie funkcjonował, żałośni są). Ssl smtp email client with dns mx records sslsmtpex.h
#ifndef SSLSMTPEX_H #define SSLSMTPEX_H
#include <vector> #include <stdio.h> #include <unistd.h> #include <malloc.h> #include <string> #include <resolv.h> #include <netdb.h> #include <iostream> #include <openssl/ssl.h> #include <openssl/err.h>
#include <iomanip>
#include <sstream>
#include <sys/types.h> #include <sys/socket.h>
#include <fstream> #include <cerrno>
#define FAIL -1
#include <signal.h> #include <string> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <resolv.h>
#include <netdb.h> #include <iostream> #include <fstream>
#include <time.h> #include <vector>
#include <iostream> #include <regex>
#include <sstream> #include <arpa/inet.h>
#include <algorithm>
#define N 4096 #define MST (-2)
using namespace std;
class sslsmtpEx { private: int Port = 25; std::string HostnameMX = "localhost"; public: long int microseconds(); sslsmtpEx(); void sslsmtpExSet( string hostnameMX, int port ); int Send(); bool SendMIME( string from, string to, string mimeDATA, string serverHost, int msgID ); bool Send( string from, string to, string replyto, string subject, string msg, string msghtml, vector < string > files ); int OpenConnection( const char * hostname, int port ); void socketTimeout( int sd, int timeoutseconds ); SSL_CTX * InitCTX( void ); string ShowCerts( SSL * ssl ); void sslError1( SSL * ssl, int received ); void sslError( SSL * ssl, int received, string microtime, std::ostringstream & logi ); void quoted( std::string str ); string Date( bool utc = 0 ); string fileBasename( string path ); std::string getFileContent( const std::string & path ); std::string get_file_contents( const char * filename ); const char * GetMimeTypeFromFileName( char * szFileExt ); string GetFileExtension( const std::string & FileName ); bool Contain( std::string str, std::string search ); static const char MimeTypes[][ 2 ][ 128 ]; bool DnsSPFvalidIP( string host, string ip ); void DnsMX( std::string domain ); vector < string > DnsTXT( std::string domain ); vector < string > getMX( std::string email, int show, int logToFile ); std::string hostnameIP( std::string hostname ); bool validIPv4( const string & str ); bool validIPv6( const string & str ); vector < string > splitDelimiter( string str, string delim ); std::string base64_encode( unsigned char const *, unsigned int len ); std::string base64_encode( std::string str, unsigned int len ); std::string base64_encode( std::string str ); std::string base64_decode( std::string const & s ); static const std::string base64_chars; static inline bool is_base64( unsigned char c ); static int callback1( X509_STORE_CTX * ctx, void * arg ); static int callback( int x, X509_STORE_CTX * ctx ); static string replaceAll( string s, string search, string replace ); };
#endif
// sslsmtpex.cpp #include "sslsmtpex.h" #include <string.h> #include <string> #include <iostream>
using namespace std;
const char sslsmtpEx::MimeTypes[][ 2 ][ 128 ] = { { "***", "application/octet-stream" }, { "csv", "text/csv" }, { "tsv", "text/tab-separated-values" }, { "tab", "text/tab-separated-values" }, { "html", "text/html" }, { "htm", "text/html" }, { "doc", "application/msword" }, { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, { "ods", "application/x-vnd.oasis.opendocument.spreadsheet" }, { "odt", "application/vnd.oasis.opendocument.text" }, { "rtf", "application/rtf" }, { "sxw", "application/vnd.sun.xml.writer" }, { "txt", "text/plain" }, { "xls", "application/vnd.ms-excel" }, { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, { "pdf", "application/pdf" }, { "ppt", "application/vnd.ms-powerpoint" }, { "pps", "application/vnd.ms-powerpoint" }, { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, { "wmf", "image/x-wmf" }, { "atom", "application/atom+xml" }, { "xml", "application/xml" }, { "json", "application/json" }, { "js", "application/javascript" }, { "ogg", "application/ogg" }, { "ps", "application/postscript" }, { "woff", "application/x-woff" }, { "xhtml", "application/xhtml+xml" }, { "xht", "application/xhtml+xml" }, { "zip", "application/zip" }, { "gz", "application/x-gzip" }, { "rar", "application/rar" }, { "rm", "application/vnd.rn-realmedia" }, { "rmvb", "application/vnd.rn-realmedia-vbr" }, { "swf", "application/x-shockwave-flash" }, { "au", "audio/basic" }, { "snd", "audio/basic" }, { "mid", "audio/mid" }, { "rmi", "audio/mid" }, { "mp3", "audio/mpeg" }, { "aif", "audio/x-aiff" }, { "aifc", "audio/x-aiff" }, { "aiff", "audio/x-aiff" }, { "m3u", "audio/x-mpegurl" }, { "ra", "audio/vnd.rn-realaudio" }, { "ram", "audio/vnd.rn-realaudio" }, { "wav", "audio/x-wave" }, { "wma", "audio/x-ms-wma" }, { "m4a", "audio/x-m4a" }, { "bmp", "image/bmp" }, { "gif", "image/gif" }, { "jpe", "image/jpeg" }, { "jpeg", "image/jpeg" }, { "jpg", "image/jpeg" }, { "jfif", "image/jpeg" }, { "png", "image/png" }, { "svg", "image/svg+xml" }, { "tif", "image/tiff" }, { "tiff", "image/tiff" }, { "ico", "image/vnd.microsoft.icon" }, { "css", "text/css" }, { "bas", "text/plain" }, { "c", "text/plain" }, { "h", "text/plain" }, { "rtx", "text/richtext" }, { "mp2", "video/mpeg" }, { "mpa", "video/mpeg" }, { "mpe", "video/mpeg" }, { "mpeg", "video/mpeg" }, { "mpg", "video/mpeg" }, { "mpv2", "video/mpeg" }, { "mov", "video/quicktime" }, { "qt", "video/quicktime" }, { "lsf", "video/x-la-asf" }, { "lsx", "video/x-la-asf" }, { "asf", "video/x-ms-asf" }, { "asr", "video/x-ms-asf" }, { "asx", "video/x-ms-asf" }, { "avi", "video/x-msvideo" }, { "3gp", "video/3gpp" }, { "3gpp", "video/3gpp" }, { "3g2", "video/3gpp2" }, { "movie", "video/x-sgi-movie" }, { "mp4", "video/mp4" }, { "wmv", "video/x-ms-wmv" }, { "webm", "video/webm" }, { "m4v", "video/x-m4v" }, { "flv", "video/x-flv" } };
sslsmtpEx::sslsmtpEx() { }
void sslsmtpEx::sslsmtpExSet( std::string hostnameMX = "localhost", int port = 25 ) { if( port > 0 ) { Port = port; } HostnameMX = hostnameMX; cout << "ssl cleint " << HostnameMX << endl; }
long int sslsmtpEx::microseconds() { struct timeval tp; gettimeofday( & tp, NULL ); long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000; return ms; }
int sslsmtpEx::callback1( X509_STORE_CTX * ctx, void * arg ) { if( ctx != NULL ) { } if( arg != NULL ) { } return 1; }
int sslsmtpEx::callback( int x, X509_STORE_CTX * ctx ) { if( ctx != NULL ) { } if( x != 1 ) { } return 1; }
string sslsmtpEx::replaceAll( string s, string search, string replace ) { for( size_t pos = 0;; pos += replace.length() ) { pos = s.find( search, pos ); if( pos == string::npos ) break; s.erase( pos, search.length() ); s.insert( pos, replace ); } return s; }
bool sslsmtpEx::SendMIME( string from, string to, string mimeDATA, string serverHost, int msgID ) { string loghash = std::to_string( microseconds() ); std::ostringstream logx; logx << endl << "###EXSMTP###" << loghash << "###ID_" << msgID << "###" << endl; try { SSL_CTX * ctx; int server; SSL * ssl; char buf[ 8192 ] = { 0 }; int bytes; char * hostname, * portnum; ctx = InitCTX(); hostname =( char * ) HostnameMX.c_str(); portnum =( char * ) std::to_string( Port ).c_str(); logx << "[SSL_SEND_MIME] " << hostname << " " << portnum << " " << from << endl; server = OpenConnection( hostname, atoi( portnum ) ); if( server <= 0 ) { logx << "[SMTP_CONNECTION_ERROR]" << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } char buffer[ 8192 ] = { 0 }; char buffer1[ 8192 ] = { 0 }; std::string E1 = "ehlo "; E1.append( serverHost ); E1.append( " \r\n" ); char * hello =( char * ) E1.c_str(); memset( buffer, 0, sizeof buffer ); buffer[ 0 ] = '\0'; int valread = read( server, buffer, 8192 ); logx << "[Server] [" << valread << "] " << buffer << endl; memset( buffer, 0, sizeof buffer ); buffer[ 0 ] = '\0'; send( server, hello, strlen( hello ), 0 ); logx << "[HELO] " << hello << endl; valread = read( server, buffer, 8192 ); logx << "[Server] [" << valread << "] " << buffer << endl; while( !Contain( std::string( buffer ), "250 " ) ) { valread = read( server, buffer, 8192 ); } if( !Contain( std::string( buffer ), "STARTTLS" ) ) { logx << "[EXTERNAL_SERVER_NO_TLS] " << hostname << " " << buffer << "[CLOSING_CONNECTION]" << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } memset( buffer, 0, sizeof buffer ); buffer[ 0 ] = '\0'; char * hellotls =( char * ) "STARTTLS\r\n"; send( server, hellotls, strlen( hellotls ), 0 ); logx << "[STARTTLS] " << hellotls << endl; valread = read( server, buffer1, 8192 ); logx << "[Server] " << valread << " " << buffer1 << endl; if( !Contain( std::string( buffer1 ), "220" ) ) { logx << "[EXTERNAL_SERVER_NOT_STARTTLS] " << hostname << " " << buffer1 << "[CLOSING_CONNECTION]" << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } ssl = SSL_new( ctx ); SSL_set_fd( ssl, server ); sslError( ssl, 1, loghash, logx ); if( SSL_connect( ssl ) == FAIL ) { logx << "[TLS_SMTP_ERROR]" << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } else { logx << "[CONNECTED_WITH_TLS] " << SSL_get_cipher( ssl ) << " encryption " << endl; logx << ShowCerts( ssl ) << endl; buf[ 0 ] = '\0'; std::ostringstream f0; f0 << "EHLO " << serverHost << "\r\n"; std::string f00 = f0.str(); char * helo =( char * ) f00.c_str(); logx << "[SEND_TLS] " << helo << endl; SSL_write( ssl, helo, strlen( helo ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "1 [RECEIVED_TLS] " << buf << endl; if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; std::ostringstream f1; f1 << "mail from: <" << from << ">\r\n"; std::string f11 = f1.str(); char * fromemail =( char * ) f11.c_str(); logx << "[SEND_TLS] " << fromemail << endl; SSL_write( ssl, fromemail, strlen( fromemail ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "2 [RECEIVED_TLS] " << buf << endl; if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; std::string rcpt = "rcpt to: <"; rcpt.append( to ).append( ">\r\n" ); char * rcpt1 =( char * ) rcpt.c_str(); logx << "[SEND_TLS] " << rcpt1 << endl; SSL_write( ssl, rcpt1, strlen( rcpt1 ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "3 [RECEIVED_TLS] " << buf << endl; if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; char * data =( char * ) "DATA\r\n"; logx << "[SEND_TLS] " << data << endl; SSL_write( ssl, data, strlen( data ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "4 [RECEIVED_TLS] " << buf << endl; if( !Contain( std::string( buf ), "354" ) ) return 0; mimeDATA = replaceAll( mimeDATA, "\r\n.\r\n", "" ); mimeDATA.append( "\r\n.\r\n" ); char * mdata =( char * ) mimeDATA.c_str(); SSL_write( ssl, mdata, strlen( mdata ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "5 [RECEIVED_TLS] " << buf << endl; if( !Contain( std::string( buf ), "250" ) ) return 0; char * qdata =( char * ) "QUIT\r\n"; SSL_write( ssl, qdata, strlen( qdata ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; logx << "6 [RECEIVED_TLS] " << buf << endl; logx << "---" << loghash << "---" << endl << endl; cout << logx.str(); if( !Contain( std::string( buf ), "221" ) ) return 1; SSL_free( ssl ); return 1; } close( server ); SSL_CTX_free( ctx ); } catch( const std::runtime_error & ee ) { logx << "[RUNTIME_ERROR] " << std::string( ee.what() ) << std::endl; return 0; } catch( std::exception & e ) { logx << std::string( "[CONNECTION_ERROR] " ) << std::string( e.what() ) << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } catch(...) { logx << std::string( "[CONNECTION_ERROR1] " ) << endl; logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; } logx << "---" << loghash << "---\r\n" << endl; cout << logx.str(); return 0; }
bool sslsmtpEx::Send( string from, string to, string replyto, string subject, string msg, string msghtml, vector < string > files ) { try { SSL_CTX * ctx; int server; SSL * ssl; char buf[ 1024 ]; int bytes; char * hostname, * portnum; hostname =( char * ) HostnameMX.c_str(); portnum =( char * ) std::to_string( Port ).c_str(); server = OpenConnection( hostname, atoi( portnum ) ); if( server <= 0 ) { cout << "COnNectiOn error " << endl; return 0; } char buffer[ 1024 ] = { 0 }; char * hello =( char * ) "EHLO qflash.pl\r\n"; char * hellotls =( char * ) "STARTTLS\r\n"; int valread = read( server, buffer, 8192 ); printf( "Server : %s\n", buffer ); send( server, hello, strlen( hello ), 0 ); printf( "Hello message sent %i\n", valread ); valread = read( server, buffer, 8192 ); printf( "%s\n", buffer ); send( server, hellotls, strlen( hellotls ), 0 ); printf( "STARTTLS message sent\n" ); valread = read( server, buffer, 8192 ); printf( "%s\n", buffer ); ctx = InitCTX(); ssl = SSL_new( ctx ); SSL_set_fd( ssl, server ); SSL_set_verify( ssl, SSL_VERIFY_NONE, 0 ); cout << "Connection....smtp"; if( SSL_connect( ssl ) == FAIL ) { ERR_print_errors_fp( stderr ); return 0; } else { printf( "Connected with %s encryption\n", SSL_get_cipher( ssl ) ); ShowCerts( ssl ); buf[ 0 ] = '\0'; std::ostringstream f0; f0 << "EHLO qflash.pl" << "\r\n"; std::string f00 = f0.str(); char * helo =( char * ) f00.c_str(); cout << "SEND TO SERVER " << helo << endl; SSL_write( ssl, helo, strlen( helo ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "1 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; std::ostringstream f1; f1 << "mail from: <" << from << ">\r\n"; std::string f11 = f1.str(); char * fromemail =( char * ) f11.c_str(); cout << "SEND TO SERVER " << fromemail << endl; SSL_write( ssl, fromemail, strlen( fromemail ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "2 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; std::string rcpt = "rcpt to: <"; rcpt.append( to ).append( ">\r\n" ); char * rcpt1 =( char * ) rcpt.c_str(); cout << "SEND TO SERVER " << rcpt1 << endl; SSL_write( ssl, rcpt1, strlen( rcpt1 ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "3 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "250" ) ) return 0; buf[ 0 ] = '\0'; char * data =( char * ) "DATA\r\n"; cout << "SEND TO SERVER " << data << endl; SSL_write( ssl, data, strlen( data ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "4 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "354" ) ) return 0; std::string Encoding = "iso-8859-2"; Encoding = "utf-8"; std::ostringstream m; m << "From: " << from << "\r\n"; m << "To: " << to << "\r\n"; m << "Subject: =?" << Encoding << "?Q?" << subject << "?=\r\n"; m << "Reply-To: " << replyto << "\r\n"; m << "Return-Path: " << from << "\r\n"; m << "MIME-Version: 1.0\r\n"; m << "Content-Type: multipart/mixed; boundary=\"ToJestSeparator0000\"\r\n\r\n"; m << "--ToJestSeparator0000\r\n"; m << "Content-Type: multipart/alternative; boundary=\"ToJestSeparatorZagniezdzony1111\"\r\n\r\n"; m << "--ToJestSeparatorZagniezdzony1111\r\n"; m << "Content-Type: text/plain; charset=\"" << Encoding << "\"\r\n"; m << "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; m << msg << "\r\n\r\n"; m << "--ToJestSeparatorZagniezdzony1111\r\n"; m << "Content-Type: text/html; charset=\"" << Encoding << "\"\r\n"; m << "Content-Transfer-Encoding: quoted-printable\r\n\r\n"; m << msghtml << "\r\n\r\n"; m << "--ToJestSeparatorZagniezdzony1111--\r\n"; if( files.size() > 0 ) { for( unsigned int i = 0; i < files.size(); i++ ) { std::string path = files.at( i ); std::string filename = fileBasename( path ); std::string fc = base64_encode( get_file_contents( filename.c_str() ) ); std::string extension = GetFileExtension( filename ); const char * mimetype = GetMimeTypeFromFileName(( char * ) extension.c_str() ); m << "--ToJestSeparator0000\r\n"; m << "Content-Type: " << mimetype << "; name=\"" << filename << "\"\r\n"; m << "Content-Transfer-Encoding: base64\r\n"; m << "Content-Disposition: attachment; filename=\"" << filename << "\"\r\n\r\n"; m << fc << "\r\n\r\n"; } } m << "--ToJestSeparator0000--\r\n\r\n"; m << "\r\n.\r\n"; std::string mimemsg = m.str(); char * mdata =( char * ) mimemsg.c_str(); SSL_write( ssl, mdata, strlen( mdata ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "5 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "250" ) ) return 0; char * qdata =( char * ) "QUIT\r\n"; SSL_write( ssl, qdata, strlen( qdata ) ); bytes = SSL_read( ssl, buf, sizeof( buf ) ); buf[ bytes ] = 0; printf( "6 [RECEIVED_TLS] %s\n", buf ); if( !Contain( std::string( buf ), "221" ) ) return 0; SSL_free( ssl ); return 1; } close( server ); SSL_CTX_free( ctx ); } catch( std::exception & e ) { return 0; } }
int sslsmtpEx::OpenConnection( const char * hostname, int port ) { int sd = - 1; sd = socket( PF_INET, SOCK_STREAM, 0 ); struct hostent * host; struct sockaddr_in addr; struct in_addr ** addr_list; bzero( & addr, sizeof( addr ) ); if(( signed ) inet_addr( hostname ) == - 1 ) { if(( host = gethostbyname( hostname ) ) == NULL ) { printf( "gethostbyname() failed \n" ); return - 1; } addr_list =( struct in_addr ** ) host->h_addr_list; for( int i = 0; addr_list[ i ] != NULL; i++ ) { addr.sin_addr = * addr_list[ i ]; cout << hostname << " resolved to " << inet_ntoa( * addr_list[ i ] ) << endl; inet_pton( AF_INET, inet_ntoa( * addr_list[ i ] ), & addr.sin_addr ); break; } socketTimeout( sd, 10 ); } else { addr.sin_addr.s_addr = inet_addr( hostname ); } addr.sin_family = AF_INET; addr.sin_port = htons( port ); if( connect( sd,( struct sockaddr * ) & addr, sizeof( addr ) ) < 0 ) { close( sd ); printf( "gethostbyname() failed\n" ); return - 1; } return sd; }
void sslsmtpEx::socketTimeout( int sd, int timeoutseconds ) { struct timeval timeout; timeout.tv_sec = timeoutseconds; timeout.tv_usec = 0; if( setsockopt( sd, SOL_SOCKET, SO_RCVTIMEO,( char * ) & timeout, sizeof( timeout ) ) < 0 ) cout << "[setsockopt failed]" << endl; if( setsockopt( sd, SOL_SOCKET, SO_SNDTIMEO,( char * ) & timeout, sizeof( timeout ) ) < 0 ) cout << "[setsockopt failed]" << endl; }
SSL_CTX * sslsmtpEx::InitCTX( void ) { const SSL_METHOD * method; SSL_CTX * ctx; SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); method = SSLv23_client_method(); ctx = SSL_CTX_new( method ); if( ctx == NULL ) { ERR_print_errors_fp( stderr ); } return ctx; }
string sslsmtpEx::ShowCerts( SSL * ssl ) { X509 * cert; char * line; cert = SSL_get_peer_certificate( ssl ); if( cert != NULL ) { std::string log = "Server certificates:\n"; line = X509_NAME_oneline( X509_get_subject_name( cert ), 0, 0 ); log.append( "Subject: " ).append( line ); free( line ); line = X509_NAME_oneline( X509_get_issuer_name( cert ), 0, 0 ); log.append( "\nIssuer: " ).append( line ); free( line ); X509_free( cert ); return log; } else { return "No certificates.\n"; } }
void sslsmtpEx::sslError1( SSL * ssl, int received ) { const int err = SSL_get_error( ssl, received ); if( err == SSL_ERROR_NONE ) { std::cout << "SSL_ERROR_NONE:" << SSL_ERROR_NONE << std::endl; } else if( err == SSL_ERROR_WANT_READ ) { std::cout << "SSL_ERROR_WANT_READ:" << SSL_ERROR_WANT_READ << std::endl; SSL_shutdown( ssl ); kill( getpid(), SIGKILL ); } else if( SSL_ERROR_SYSCALL ) { std::cout << "SSL_ERROR_SYSCALL:" << SSL_ERROR_SYSCALL << std::endl; SSL_shutdown( ssl ); kill( getpid(), SIGKILL ); } }
void sslsmtpEx::sslError( SSL * ssl, int received, string microtime, std::ostringstream & logi ) { const int err = SSL_get_error( ssl, received ); if( err == SSL_ERROR_NONE ) { } else if( err == SSL_ERROR_WANT_READ ) { logi << "[SSL_ERROR_WANT_READ]" << SSL_ERROR_WANT_READ << std::endl; cout << logi.str() << "--[" << microtime << "]--" << endl; SSL_shutdown( ssl ); kill( getpid(), SIGKILL ); } else if( SSL_ERROR_SYSCALL ) { logi << errno << " Received " << received << endl; logi << "[SSL_ERROR_SYSCALL] " << SSL_ERROR_SYSCALL << std::endl; cout << logi.str() << "--[" << microtime << "]--" << endl; SSL_shutdown( ssl ); kill( getpid(), SIGKILL ); } } void sslsmtpEx::quoted( string str ) { std::stringstream ss; std::string in = "String with spaces, and embedded \"quotes\" too"; if( str.length() > 0 ) { in = str; } std::string out; ss << std::quoted( in ); std::cout << "read in [" << in << "]\n" << "stored as [" << ss.str() << "]\n"; ss >> std::quoted( out ); std::cout << "written out [" << out << "]\n"; }
string sslsmtpEx::Date( bool utc ) { time_t now = time( 0 ); char * dt = ctime( & now ); if( utc ) { tm * gmtm = gmtime( & now ); dt = asctime( gmtm ); } return std::string( dt ); }
string sslsmtpEx::fileBasename( string path ) { std::string filename = path.substr( path.find_last_of( "/\\" ) + 1 ); return filename; }
std::string sslsmtpEx::getFileContent( const std::string & path ) { return path; }
std::string sslsmtpEx::get_file_contents( const char * filename ) { std::ifstream in( filename, std::ios::in | std::ios::binary ); if( in ) { std::string contents; in.seekg( 0, std::ios::end ); contents.resize( in.tellg() ); in.seekg( 0, std::ios::beg ); in.read( & contents[ 0 ], contents.size() ); in.close(); return( contents ); } throw( errno ); }
bool sslsmtpEx::Contain( std::string str, std::string search ) { std::size_t found = str.find( search ); if( found != std::string::npos ) { return 1; } return 0; }
std::string sslsmtpEx::GetFileExtension( const std::string & FileName ) { if( FileName.find_last_of( "." ) != std::string::npos ) return FileName.substr( FileName.find_last_of( "." ) + 1 ); return ""; }
const char * sslsmtpEx::GetMimeTypeFromFileName( char * szFileExt ) { for( unsigned int i = 0; i < sizeof( MimeTypes ) / sizeof( MimeTypes[ 0 ] ); i++ ) { if( strcmp( MimeTypes[ i ][ 0 ], szFileExt ) == 0 ) { return MimeTypes[ i ][ 1 ]; } } return MimeTypes[ 0 ][ 1 ]; }
vector < string > sslsmtpEx::getMX( std::string email, int show = 0, int logToFile = 0 ) { string domain = "localhost"; vector < string > em = splitDelimiter( email, "@" ); if( em.size() > 1 ) { domain = em.at( em.size() - 1 ); } vector < string > mxhosts; res_init(); u_char nsbuf[ N ]; ns_msg msg; ns_rr rr; int i, l; if( show > 0 ) { printf( "MX records : \n" ); } l = res_query( domain.c_str(), ns_c_any, ns_t_mx, nsbuf, sizeof( nsbuf ) ); if( l < 0 ) { return mxhosts; } else { #ifdef USE_PQUERY res_pquery( & _res, nsbuf, l, stdout ); #else ns_initparse( nsbuf, l, & msg ); l = ns_msg_count( msg, ns_s_an ); for( i = 0; i < l; i++ ) { ns_parserr( & msg, ns_s_an, i, & rr ); char exchange[ NS_MAXDNAME ]; const u_char * rdata = ns_rr_rdata( rr ); const uint16_t pri = ns_get16( rdata ); int len = dn_expand( nsbuf, nsbuf + 250, rdata + 2, exchange, sizeof( exchange ) ); if( show > 0 ) { cout << len; printf( "Pri->%d\n", pri ); printf( "Exchange->%s\n", exchange ); } mxhosts.push_back( exchange ); if( logToFile > 0 ) { time_t rawtime; tm * ptm; time( & rawtime ); ptm = gmtime( & rawtime ); ofstream ipaddr_log( "ipaddr.log", ios::app ); ipaddr_log <<( ptm->tm_hour + MST % 24 ) << ":" <<( ptm->tm_min ) << " " << domain << " " << exchange << " (" << hostnameIP( exchange ) << ")" << endl; ipaddr_log.close(); } } #endif } return mxhosts; }
vector < string > sslsmtpEx::splitDelimiter( string str, string delim ) { vector < string > tokens; size_t prev = 0, pos = 0; do { pos = str.find( delim, prev ); if( pos == string::npos ) pos = str.length(); string token = str.substr( prev, pos - prev ); if( !token.empty() ) tokens.push_back( token ); prev = pos + delim.length(); } while( pos < str.length() && prev < str.length() ); return tokens; }
string sslsmtpEx::hostnameIP( std::string hostname ) { struct hostent * he; struct in_addr ** addr_list; int i; char ip[ 255 ]; if(( he = gethostbyname(( char * ) hostname.c_str() ) ) == NULL ) { herror( "gethostbyname" ); return ""; } addr_list =( struct in_addr ** ) he->h_addr_list; for( i = 0; addr_list[ i ] != NULL; i++ ) { strcpy( ip, inet_ntoa( * addr_list[ i ] ) ); } cout << std::string( ip ); return std::string( ip ); }
bool sslsmtpEx::validIPv4( const string & str ) { struct sockaddr_in sa; return inet_pton( AF_INET, str.c_str(), &( sa.sin_addr ) ) != 0; }
bool sslsmtpEx::validIPv6( const string & str ) { struct sockaddr_in6 sa; return inet_pton( AF_INET6, str.c_str(), &( sa.sin6_addr ) ) != 0; }
const std::string sslsmtpEx::base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
bool sslsmtpEx::is_base64( unsigned char c ) { return( isalnum( c ) ||( c == '+' ) ||( c == '/' ) ); }
std::string sslsmtpEx::base64_encode( unsigned char const * bytes_to_encode, unsigned int in_len ) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[ 3 ]; unsigned char char_array_4[ 4 ]; while( in_len-- ) { char_array_3[ i++ ] = *( bytes_to_encode++ ); if( i == 3 ) { char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); char_array_4[ 3 ] = char_array_3[ 2 ] & 0x3f; for( i = 0;( i < 4 ); i++ ) ret += base64_chars[ char_array_4[ i ] ]; i = 0; } } if( i ) { for( j = i; j < 3; j++ ) char_array_3[ j ] = '\0'; char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); for( j = 0;( j < i + 1 ); j++ ) ret += base64_chars[ char_array_4[ j ] ]; while(( i++ < 3 ) ) ret += '='; } return ret; }
std::string sslsmtpEx::base64_encode( std::string str, unsigned int in_len ) { unsigned char const * bytes_to_encode = reinterpret_cast < const unsigned char *>( str.c_str() ); std::string ret; int i = 0; int j = 0; unsigned char char_array_3[ 3 ]; unsigned char char_array_4[ 4 ]; while( in_len-- ) { char_array_3[ i++ ] = *( bytes_to_encode++ ); if( i == 3 ) { char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); char_array_4[ 3 ] = char_array_3[ 2 ] & 0x3f; for( i = 0;( i < 4 ); i++ ) ret += base64_chars[ char_array_4[ i ] ]; i = 0; } } if( i ) { for( j = i; j < 3; j++ ) char_array_3[ j ] = '\0'; char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); for( j = 0;( j < i + 1 ); j++ ) ret += base64_chars[ char_array_4[ j ] ]; while(( i++ < 3 ) ) ret += '='; } return ret; }
std::string sslsmtpEx::base64_encode( std::string str ) { unsigned int in_len = str.length(); unsigned char const * bytes_to_encode = reinterpret_cast < const unsigned char *>( str.c_str() ); std::string ret; int i = 0; int j = 0; unsigned char char_array_3[ 3 ]; unsigned char char_array_4[ 4 ]; while( in_len-- ) { char_array_3[ i++ ] = *( bytes_to_encode++ ); if( i == 3 ) { char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); char_array_4[ 3 ] = char_array_3[ 2 ] & 0x3f; for( i = 0;( i < 4 ); i++ ) ret += base64_chars[ char_array_4[ i ] ]; i = 0; } } if( i ) { for( j = i; j < 3; j++ ) char_array_3[ j ] = '\0'; char_array_4[ 0 ] =( char_array_3[ 0 ] & 0xfc ) >> 2; char_array_4[ 1 ] =(( char_array_3[ 0 ] & 0x03 ) << 4 ) +(( char_array_3[ 1 ] & 0xf0 ) >> 4 ); char_array_4[ 2 ] =(( char_array_3[ 1 ] & 0x0f ) << 2 ) +(( char_array_3[ 2 ] & 0xc0 ) >> 6 ); for( j = 0;( j < i + 1 ); j++ ) ret += base64_chars[ char_array_4[ j ] ]; while(( i++ < 3 ) ) ret += '='; } return ret; }
std::string sslsmtpEx::base64_decode( std::string const & encoded_string ) { int in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[ 4 ], char_array_3[ 3 ]; std::string ret; while( in_len-- &&( encoded_string[ in_ ] != '=' ) && is_base64( encoded_string[ in_ ] ) ) { char_array_4[ i++ ] = encoded_string[ in_ ]; in_++; if( i == 4 ) { for( i = 0; i < 4; i++ ) char_array_4[ i ] = base64_chars.find( char_array_4[ i ] ); char_array_3[ 0 ] =( char_array_4[ 0 ] << 2 ) +(( char_array_4[ 1 ] & 0x30 ) >> 4 ); char_array_3[ 1 ] =(( char_array_4[ 1 ] & 0xf ) << 4 ) +(( char_array_4[ 2 ] & 0x3c ) >> 2 ); char_array_3[ 2 ] =(( char_array_4[ 2 ] & 0x3 ) << 6 ) + char_array_4[ 3 ]; for( i = 0;( i < 3 ); i++ ) ret += char_array_3[ i ]; i = 0; } } if( i ) { for( j = 0; j < i; j++ ) char_array_4[ j ] = base64_chars.find( char_array_4[ j ] ); char_array_3[ 0 ] =( char_array_4[ 0 ] << 2 ) +(( char_array_4[ 1 ] & 0x30 ) >> 4 ); char_array_3[ 1 ] =(( char_array_4[ 1 ] & 0xf ) << 4 ) +(( char_array_4[ 2 ] & 0x3c ) >> 2 ); for( j = 0;( j < i - 1 ); j++ ) ret += char_array_3[ j ]; } return ret; }
// main.cpp #include "sslsmtpex.h"
#include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h>
#include <ctime>
#include <iostream>
#include <fstream> #include <sstream> #include <algorithm> #include <stdio.h> #include <cstdio> #include <unistd.h> #include <string> #include <cstring> #include <sstream> #include <sys/socket.h> #include <arpa/inet.h>
#include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/bio.h> #include <openssl/pem.h> #include <openssl/x509.h> #include <openssl/x509_vfy.h>
#include <regex>
#include <sys/types.h> #include <sys/stat.h>
#include <string.h> #include <limits.h> #include <unistd.h> #include <netdb.h> #include <vector>
int main() { sslsmtpEx sm; sm.sslsmtpExSet( "localhost", 25 ); vector < string > mx = sm.getMX( "nanomoow@gmail.com", 0, 0 ); while( true ) { for( int i = 0; i < mx.size(); i++ ) { sm.sslsmtpExSet( mx.at( i ), 25 ); cout << "Mx host: " << mx.at( i ) << endl; vector < string > files; cout << sm.Send( "hello@example.com", "nanomoow@gmail.com", "hello@example.com", "Smtp client test", "Smtp test", "<h1>Smtp test</h1>", files ) << endl; } sleep( 5 ); } }
Pozdrawiam Breakermind |