#include "stdafx.h" // Hack due to MFC project strangeness #define _WIN32_WINNT 0x0500 #include #include "interface.h" /* * This method computes the MD5 hash of the secret, text and destination * address. It should be clear how this can be extended to other hash * algorithms and arbitrary data. */ char* computeMD5Hash(const char* secret, const char* shortmessage, const char* destaddr) { // Variables used during the hashing process HCRYPTPROV cryptoProvider; HCRYPTHASH rawHash; // Get the cryptographic provider for MD5 hashing // NOTE: This call could (potentially) fail and this should be checked for CryptAcquireContext(&cryptoProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); // Create an object that will perform the hash // NOTE: This call could (potentially) fail and this should be checked for CryptCreateHash(cryptoProvider, CALG_MD5, 0, 0, &rawHash); // Feed data into the hash // NOTE: These calls could (potentially) fail and this should be checked for CryptHashData(rawHash, (unsigned char*)secret, strlen(secret), 0); CryptHashData(rawHash, (unsigned char*)shortmessage, strlen(shortmessage), 0); CryptHashData(rawHash, (unsigned char*)destaddr, strlen(destaddr), 0); // Extract the hash data // NOTE: This call could (potentially) fail and this should be checked for DWORD hashLength = 16; //(MD5 length) unsigned char* hashData = new unsigned char[hashLength]; CryptGetHashParam(rawHash, HP_HASHVAL, hashData, &hashLength, 0); // Create a hex-encoded string of the hash bytes char lut[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; char* hash = new char[33]; for(int i = 0; i < 16; i++) { hash[2 * i] = lut[(hashData[i] & 0xF0) >> 4]; hash[2 * i + 1] = lut[hashData[i] & 0x0F]; } hash[32] = '\0'; // After processing, cryptoProvider and hasher must be released. if(rawHash) { CryptDestroyHash(rawHash); } if(cryptoProvider) { CryptReleaseContext(cryptoProvider, 0); } delete[] hashData; return hash; } /* * This method performs the actual HTTP request that sends the SMS. It also * contains the information that is used to form the request. */ char* send_ems(char* destaddr) { const char* host = "194.247.82.149"; const int port = 80; const char* action = "submitsm"; const char* client_id = ""; const char* shortmessage = "7C0C7A00424547494E3A494D454C4F44590D0A5645525" \ "3494F4E3A312E320D0A464F524D41543A434C415353312E300D0A4D454C4F44593A6" \ "43323633364332363336433723264332363336433653323663365332366336733613" \ "3236733613323673361337232613323673361330D0A454E443A494D454C4F44590D0A"; const char* secret = ""; char* hash = computeMD5Hash(secret, shortmessage, destaddr); // Format the URL/request const char* pattern = "GET /%s/?client_id=%s&destaddr=%s&esm=64" \ "&shortmessage=%s&key=%s HTTP/1.0\r\n\r\n" int buffer_size = strlen(action) + strlen(client_id) + strlen(destaddr) + strlen(shortmessage) + strlen(hash) + 80; char* buffer = new char[buffer_size]; sprintf(buffer, pattern, action, client_id, destaddr, shortmessage, hash); // Clean up delete[] hash; // Create the socket CSocket socket; socket.Create(); // Try to connect to the server if(!socket.Connect( host, port )) { MessageBox( NULL, "unable to connect, check settings", "Error", MB_OK ); } // These variables are used during the request and response code int bytesToIO = strlen(buffer); int totalBytesIOd = 0; int bytesIOd = 0; // Send the request while(totalBytesIOd < bytesToIO && (bytesIOd = socket.Send(buffer + totalBytesIOd, bytesToIO - totalBytesIOd, 0)) > 0) { totalBytesIOd += bytesIOd; } // If any errors occurred in the read process, bytesIOd will be SOCKET_ERROR // and appropriate action should be taken // Re-allocate the buffer for storing the response delete[] buffer; buffer = new char[4096]; // Receive the response bytesIOd = 0; totalBytesIOd = 0; while(totalBytesIOd < 4096 && (bytesIOd = socket.Receive(buffer + totalBytesIOd, 4096 - totalBytesIOd, 0)) > 0) { totalBytesIOd += bytesIOd; } // If any errors occurred in the read process, bytesIOd will be SOCKET_ERROR // and appropriate action should be taken // NULL-terminate the response we've read buffer[totalBytesIOd] = '\0'; // Close the socket socket.Close(); // Return the result of the request return buffer; }