Advertisement
Guest User

Untitled

a guest
Nov 28th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.49 KB | None | 0 0
  1. #include <iostream>
  2. #include <sstream>
  3. #include <limits>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string>
  7. #include <sqlite3.h>
  8. #include <gcrypt.h>
  9.  
  10. using namespace std;
  11.  
  12.  
  13. string int_to_str(int num) {
  14. stringstream ss;
  15.  
  16. ss << num;
  17.  
  18. return ss.str();
  19. }
  20.  
  21. // ///
  22. // ENCRYPTION / DECRYPTION ///
  23. // ///
  24.  
  25. void hash(string input, string* output){
  26. size_t txtLength = input.length();
  27. char * hash = (char*)malloc(sizeof(char) * 33);
  28. char * textBuffer = (char*)malloc(sizeof(char) * (txtLength+1));
  29. memset(hash, 0, 33);
  30.  
  31. gcry_md_hash_buffer(
  32. GCRY_MD_SHA256, // gcry_cipher_hd_t
  33. hash, // void *
  34. input.c_str(), // const void *
  35. txtLength); // size_t
  36.  
  37. *output = hash;
  38. free(hash);
  39. free(textBuffer);
  40. }
  41.  
  42. void salsa(string message, string passphrase, bool encrypt, string *output){
  43.  
  44. #define GCRY_CIPHER GCRY_CIPHER_AES128 // Pick the cipher here
  45.  
  46. gcry_error_t gcryError;
  47. gcry_cipher_hd_t gcryCipherHd;
  48. size_t index;
  49.  
  50. size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
  51. size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
  52. char * txtBuffer = (char *)message.c_str();
  53. size_t txtLength = message.length(); // string plus termination
  54. char * encBuffer = (char *)malloc(txtLength);
  55. char * outBuffer = (char *)malloc(txtLength);
  56. char * aesSymKey = (char *)passphrase.c_str(); // 16 bytes
  57. string iv = "SalsaManSalsaMan";
  58. char * iniVector = (char *)iv.c_str();
  59.  
  60. gcry_cipher_open(
  61. &gcryCipherHd, // gcry_cipher_hd_t *
  62. GCRY_CIPHER_SALSA20, // int
  63. GCRY_CIPHER_MODE_STREAM, // int
  64. 0); // unsigned int
  65.  
  66.  
  67. gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
  68.  
  69. gcry_cipher_setiv(gcryCipherHd, iniVector, 8);
  70.  
  71. if (encrypt){
  72. gcry_cipher_encrypt(
  73. gcryCipherHd, // gcry_cipher_hd_t
  74. encBuffer, // void *
  75. txtLength, // size_t
  76. txtBuffer, // const void *
  77. txtLength); // size_t
  78. }
  79.  
  80.  
  81. gcry_cipher_setiv(gcryCipherHd, iniVector, 8);
  82.  
  83.  
  84. if (!encrypt){
  85. gcry_cipher_decrypt(
  86. gcryCipherHd, // gcry_cipher_hd_t
  87. outBuffer, // void *
  88. txtLength, // size_t
  89. txtBuffer, // const void *
  90. txtLength); // size_t
  91. }
  92.  
  93.  
  94. if (encrypt){
  95. *output = encBuffer;
  96. }
  97. else {
  98. *output = outBuffer;
  99. }
  100.  
  101. // clean up after ourselves
  102. gcry_cipher_close(gcryCipherHd);
  103. free(encBuffer);
  104. free(outBuffer);
  105. }
  106.  
  107.  
  108.  
  109. // ///
  110. // SEND MESSAGES ///
  111. // ///
  112.  
  113. static int messageSendSuccessCallback(void *data, int argc, char **argv, char **azColName){
  114. bool *messageSendSuccess = reinterpret_cast<bool*>(data);
  115.  
  116. *messageSendSuccess = ((argv[0][0] - '0') > 0);
  117.  
  118. return 0;
  119. }
  120.  
  121. void sendMessage(string sender, string recipient, string message, string passphrase, sqlite3 *db){
  122. char *zErrMsg = 0;
  123. int rc;
  124. string sql;
  125. const char* data = "";
  126. bool messageSendSuccess = false;
  127.  
  128. string passphraseHash;
  129. hash(passphrase, &passphraseHash);
  130. string messageEncryption;
  131. salsa(message, passphraseHash, true, &messageEncryption);
  132.  
  133. sql = "SELECT COUNT(*) FROM USERS WHERE USERNAME=\"" + recipient + "\";";
  134. rc = sqlite3_exec(db, sql.c_str(), messageSendSuccessCallback, &messageSendSuccess, &zErrMsg);
  135.  
  136. if( rc != SQLITE_OK ) {
  137. sqlite3_free(zErrMsg);
  138. }
  139.  
  140. if (messageSendSuccess){
  141. sql = "INSERT INTO MESSAGES(SENDER, RECIPIENT, MESSAGE, PASSPHRASE) VALUES(\"" + sender + "\", \"" + recipient + "\", \"" + messageEncryption + "\", \"" + passphraseHash + "\");";
  142.  
  143. rc = sqlite3_exec(db, sql.c_str(), NULL, (void*)data, &zErrMsg);
  144.  
  145. if( rc != SQLITE_OK ) {
  146. sqlite3_free(zErrMsg);
  147. }
  148.  
  149. cout << "Message sent successfully" << endl << endl;
  150. }
  151. else {
  152. cout << "Could not send message, inputted recipient does not exist" << endl << endl;
  153. }
  154. }
  155.  
  156.  
  157. // ///
  158. // READ MESSAGES ///
  159. // ///
  160.  
  161. static int messageDisplayCallback(void *data, int argc, char **argv, char **azColName){
  162. string message = argv[2];
  163. string passphrase = argv[3];
  164.  
  165. string answer;
  166. salsa(message, passphrase, false, &answer);
  167.  
  168. cout << " _____________________________________________________________" << endl;
  169. printf(" |\n | Id: %s | From : %s\n |____________________________________________________________\n |\n | Message: %s\n", argv[0], argv[1], answer.c_str());
  170. cout << " |____________________________________________________________";
  171. printf("\n");
  172. return 0;
  173. }
  174.  
  175. static int messageDisplaySuccessCallback(void *data, int argc, char **argv, char **azColName){
  176. bool *messageDisplaySuccess = reinterpret_cast<bool*>(data);
  177.  
  178. *messageDisplaySuccess = ((argv[0][0] - '0') > 0);
  179.  
  180. return 0;
  181. }
  182.  
  183. void displayMessage(int id, string passphrase, sqlite3 *db){
  184. char *zErrMsg = 0;
  185. int rc;
  186. string sql;
  187. const char* data = "";
  188. bool messageDisplaySuccess = false;
  189.  
  190. string passphraseHash;
  191. hash(passphrase, &passphraseHash);
  192.  
  193. sql = "SELECT COUNT(*) FROM MESSAGES WHERE ID=" + int_to_str(id) + " AND PASSPHRASE=\"" + passphraseHash + "\";";
  194. rc = sqlite3_exec(db, sql.c_str(), messageDisplaySuccessCallback, &messageDisplaySuccess, &zErrMsg);
  195.  
  196. if( rc != SQLITE_OK ) {
  197. sqlite3_free(zErrMsg);
  198. }
  199.  
  200. if (messageDisplaySuccess){
  201. sql = "SELECT ID, SENDER, MESSAGE, PASSPHRASE FROM MESSAGES WHERE ID=" + int_to_str(id) + " AND PASSPHRASE=\"" + passphraseHash + "\";";
  202.  
  203. rc = sqlite3_exec(db, sql.c_str(), messageDisplayCallback, (void*)data, &zErrMsg);
  204.  
  205. if( rc != SQLITE_OK ) {
  206. sqlite3_free(zErrMsg);
  207. }
  208.  
  209. }
  210. else {
  211. cout << "Could not display message with inputted id and passphrase" << endl;
  212. }
  213. }
  214.  
  215. // ///
  216. // DISPLAY MESSAGE LIST ///
  217. // ///
  218.  
  219. static int messageListCallback(void *data, int argc, char **argv, char **azColName){
  220. printf(" Id: %s | From : %s", argv[0], argv[1]);
  221.  
  222. printf("\n");
  223. return 0;
  224. }
  225.  
  226. void displayMessageList(string username, sqlite3 *db){
  227. char *zErrMsg = 0;
  228. int rc;
  229. string sql;
  230. const char* data = "";
  231.  
  232. sql = "SELECT ID, SENDER FROM MESSAGES WHERE RECIPIENT=\"" + username + "\" ;";
  233.  
  234. rc = sqlite3_exec(db, sql.c_str(), messageListCallback, (void*)data, &zErrMsg);
  235.  
  236. if( rc != SQLITE_OK ) {
  237. sqlite3_free(zErrMsg);
  238. }
  239. }
  240.  
  241. // ///
  242. // COUNT MESSAGES ///
  243. // ///
  244.  
  245. static int messageCountCallback(void *data, int argc, char **argv, char **azColName){
  246. cout << (argv[0][0]);
  247.  
  248. return 0;
  249. }
  250.  
  251.  
  252. void countMessages(string username, sqlite3 *db){
  253. cout << "You have ";
  254.  
  255. char *zErrMsg = 0;
  256. int rc;
  257. string sql;
  258. const char* data = "";
  259.  
  260. sql = "SELECT COUNT(*) FROM MESSAGES WHERE RECIPIENT=\"" + username + "\";";
  261.  
  262. rc = sqlite3_exec(db, sql.c_str(), messageCountCallback, (void*)data, &zErrMsg);
  263.  
  264. if( rc != SQLITE_OK ) {
  265. sqlite3_free(zErrMsg);
  266. }
  267.  
  268. cout << " messages:";
  269. }
  270.  
  271. // ///
  272. // LOGIN ///
  273. // ///
  274.  
  275. static int loginCallback(void *data, int argc, char **argv, char **azColName){
  276. bool *loginSuccess = reinterpret_cast<bool*>(data);
  277.  
  278. *loginSuccess = ((argv[0][0] - '0') > 0);
  279.  
  280. return 0;
  281. }
  282.  
  283. bool loginAccount(string username, string password,sqlite3 *db){
  284. cout << "\nLogging in..." << endl;
  285.  
  286. char *zErrMsg = 0;
  287. int rc;
  288. string sql;
  289. bool loginSuccess = false;
  290.  
  291. string hashValue;
  292. hash(password, &hashValue);
  293.  
  294. sql = "SELECT COUNT(*) FROM USERS WHERE USERNAME=\"" + username + "\" AND PASSWORD=\"" + hashValue + "\";";
  295.  
  296. rc = sqlite3_exec(db, sql.c_str(), loginCallback, &loginSuccess, &zErrMsg);
  297.  
  298. if( rc != SQLITE_OK ) {
  299. sqlite3_free(zErrMsg);
  300. }
  301.  
  302.  
  303. if (loginSuccess){
  304. return true;
  305. }
  306. else {
  307. return false;
  308. }
  309. }
  310.  
  311. // ///
  312. // REGISTER ACCOUNT ///
  313. // ///
  314.  
  315. static int callback(void *data, int argc, char **argv, char **azColName){
  316. int i;
  317.  
  318. for(i = 0; i<argc; i++){
  319. printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  320. }
  321.  
  322. printf("\n");
  323. return 0;
  324. }
  325.  
  326. bool registerAccount(string username, string password,sqlite3 *db){
  327. char *zErrMsg = 0;
  328. int rc;
  329. string sql;
  330.  
  331. string hashValue;
  332. hash(password, &hashValue);
  333.  
  334. sql = "INSERT INTO USERS(USERNAME, PASSWORD) VALUES(\"" + username + "\", \"" + hashValue + "\");";
  335.  
  336. rc = sqlite3_exec(db, sql.c_str(), NULL, NULL, &zErrMsg);
  337.  
  338.  
  339. if( rc != SQLITE_OK ) {
  340. sqlite3_free(zErrMsg);
  341. return false;
  342. } else {
  343. return true;
  344. }
  345.  
  346. free(zErrMsg);
  347. }
  348.  
  349. // ///
  350. // MAIN ///
  351. // ///
  352.  
  353. int main(){
  354. sqlite3 *db;
  355. char *zErrMsg = 0;
  356. int rc;
  357. string sql;
  358.  
  359. /* Open database */
  360. rc = sqlite3_open("mail.db", &db);
  361.  
  362. if( rc ) {
  363. fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
  364. return(0);
  365. }
  366.  
  367.  
  368. // /* Create SQL statement */
  369. // sql = "SELECT USERNAME from USERS";
  370.  
  371. // /* Execute SQL statement */
  372. // rc = sqlite3_exec(db, sql.c_str(), callback, NULL, &zErrMsg);
  373.  
  374. // if( rc != SQLITE_OK ) {
  375. // fprintf(stderr, "SQL error: %s\n", zErrMsg);
  376. // sqlite3_free(zErrMsg);
  377. // }
  378.  
  379. cout << endl;
  380.  
  381. int homeChoice = -1;
  382. int registerLoginChoice = -1;
  383. int mainChoice = -1;
  384. int messageChoice = -1;
  385. string passphrase = "";
  386. string username = "";
  387. string password = "";
  388. string recipient = "";
  389. string message = "";
  390. string sharedPassphrase = "";
  391. bool loginAccountSuccess = false;
  392. bool registerAccountSuccess = false;
  393. bool readMessageSuccess = false;
  394.  
  395. cout << "Welcome to Gee-Mail!" << endl << endl;
  396. cout << "Enter (0) to sign-in or (1) to register: ";
  397. cin >> homeChoice;
  398.  
  399. if (!cin){
  400. cin.clear();
  401. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  402. }
  403.  
  404. while (!(homeChoice == 0 || homeChoice == 1)){
  405. cout << "Enter (0) to sign-in or (1) to register: ";
  406. cin >> homeChoice;
  407. if (!cin){
  408. cin.clear();
  409. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  410. }
  411. }
  412.  
  413. if (homeChoice == 0) {
  414. cout << "\nSign into your account:\n\n";
  415.  
  416. while (!loginAccountSuccess){
  417. cout << "Enter your username: ";
  418. cin >> username;
  419. if (!cin){
  420. cin.clear();
  421. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  422. }
  423. cout << "Enter your password: ";
  424. cin >> password;
  425. if (!cin){
  426. cin.clear();
  427. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  428. }
  429.  
  430. loginAccountSuccess = loginAccount(username, password, db);
  431.  
  432. if (!loginAccountSuccess){
  433. cout << "\nCannot login - username and password combination not recognized" << endl;
  434. cout << "Please try again with a different username and password combination" << endl << endl;
  435. }
  436. }
  437. }
  438. else if (homeChoice == 1){
  439. cout << "\nCreate your account:\n\n";
  440.  
  441. while (!registerAccountSuccess){
  442. cout << "Enter your username: ";
  443. cin >> username;
  444. if (!cin){
  445. cin.clear();
  446. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  447. }
  448. cout << "Enter your password: ";
  449. cin >> password;
  450. if (!cin){
  451. cin.clear();
  452. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  453. }
  454.  
  455. registerAccountSuccess = registerAccount(username, password, db);
  456.  
  457. if (!registerAccountSuccess){
  458. cout << "\nCannot create account with username: " << username << " - username is already taken!" << endl;
  459. cout << "Please try again with a different account name:" << endl << endl;
  460. }
  461. }
  462.  
  463. cout << endl << "Would you like to sign in to your new account? (0) = no, (1) = yes : ";
  464.  
  465. cin >> registerLoginChoice;
  466. if (!cin){
  467. cin.clear();
  468. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  469. }
  470.  
  471. while (!(registerLoginChoice == 0 || registerLoginChoice == 1)){
  472. cout << "Enter (0) to exit or (1) to sign in: ";
  473. cin >> registerLoginChoice;
  474. if (!cin){
  475. cin.clear();
  476. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  477. }
  478. }
  479.  
  480. if (registerLoginChoice == 1){
  481. loginAccount(username, password, db);
  482. }
  483. else {
  484. cout << endl << "Goodbye!" << endl << endl;
  485. return 0;
  486. }
  487. }
  488.  
  489. cout << endl << "Succesfully logged in" << endl << endl;
  490.  
  491. while(mainChoice != 2) {
  492. mainChoice = -1;
  493. messageChoice = -1;
  494. passphrase = "";
  495. recipient = "";
  496. message = "";
  497. sharedPassphrase = "";
  498.  
  499. countMessages(username, db);
  500.  
  501. cout << endl;
  502.  
  503. displayMessageList(username, db);
  504.  
  505. cout << endl;
  506.  
  507. cout << "Enter (0) to read a message, (1) to send a message, or (2) to quit: ";
  508. cin >> mainChoice;
  509. if (!cin){
  510. cin.clear();
  511. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  512. }
  513.  
  514. while (!(mainChoice == 0 || mainChoice == 1 || mainChoice == 2)){
  515. cout << endl << "Enter (0) to read a message, (1) to send a message, or (2) to quit: ";
  516. cin >> mainChoice;
  517. if (!cin){
  518. cin.clear();
  519. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  520. }
  521. }
  522.  
  523. cout << endl;
  524.  
  525. if (mainChoice == 0){
  526. cout << "Enter the Id of the message you'd like to read: ";
  527. cin >> messageChoice;
  528. if (!cin){
  529. cin.clear();
  530. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  531. }
  532. cout << "Enter the shared passphrase with the sender: ";
  533. cin >> passphrase;
  534. if (!cin){
  535. cin.clear();
  536. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  537. }
  538. cout << endl;
  539.  
  540. displayMessage(messageChoice, passphrase, db);
  541.  
  542. cout << endl;
  543. }
  544. else if (mainChoice == 1){
  545. string test;
  546. getline(cin, test);
  547.  
  548. cout << "Enter the username of your desired recipient: ";
  549. getline(cin, recipient);
  550. if (!cin){
  551. cin.clear();
  552. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  553. }
  554.  
  555. cout << "Enter your message: ";
  556. getline(cin, message);
  557. if (!cin){
  558. cin.clear();
  559. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  560. }
  561.  
  562. cout << "Enter your shared passphrase: ";
  563. getline(cin, sharedPassphrase);
  564. if (!cin){
  565. cin.clear();
  566. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  567. }
  568.  
  569. cout << endl;
  570.  
  571. sendMessage(username, recipient, message, sharedPassphrase, db);
  572.  
  573. }
  574. }
  575.  
  576. cout << "Goodbye!" << endl << endl;
  577.  
  578. sqlite3_close(db);
  579.  
  580. return 0;
  581. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement