Advertisement
Guest User

Untitled

a guest
Oct 2nd, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.57 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <fstream>
  4. #include <thread>
  5. #include <vector>
  6. #include <string>
  7. #include <mutex>
  8. #include <sstream>
  9. #include <ctime>
  10.  
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18.  
  19. #include <openssl/sha.h>
  20.  
  21. #include <pqxx/pqxx>
  22. using namespace pqxx;
  23. connection database("dbname = the_hole user = postgres password = the_hole hostaddr = 127.0.0.1 port = 5432");
  24. nontransaction executioner(database);
  25.  
  26. #define MAX_CONNECTIONS 128
  27.  
  28. using namespace std;
  29.  
  30.  
  31. /*message base started*/
  32. char welcome[]="Welcome to Kronbash ltd overpowered and oversecured chat-server\n\
  33. TTTTT H H EEEEE H H OOO L EEEEE\n\
  34. T H H E H H OO OO L E \n\
  35. T HHHHH EEEEE HHHHH O O L EEEEE\n\
  36. T H H E H H OO OO L E \n\
  37. T H H EEEEE H H OOO LLLLL EEEEE\n\
  38. To call help send /HELP\n\
  39. ";
  40. char help_str[]="\
  41. /CREATE <username> <nickname> <password> -- register account\n\
  42. /USER <username> -- start identifying and set account name\n\
  43. /PASS <password> -- continue identifying and set account password\n\
  44. /DROP -- delete your account\n\
  45. /MSG <user> <prwmesg>-- send private message\n\
  46. /RESTORE <public/private> -- show you your private/all public messages\n\
  47. /INFO <user>-- show info about user\n\
  48. /QUIT -- exit from server\n\
  49. /LIST -- show nicknames on server\n\
  50. ";
  51.  
  52. char help_admin_str[]="\
  53. /SETPASS <nickname> <password> -- change password anyone you want.\n";
  54. /*message base ended*/
  55.  
  56.  
  57. vector<string> split_str_by_space(string& str) {
  58. vector<string> parameters;
  59. string buffer;
  60. stringstream ss(str);
  61. while (ss >> buffer)
  62. parameters.push_back(buffer);
  63. return parameters;
  64. }
  65.  
  66.  
  67. struct user{
  68. string nickname;
  69. int socket;
  70. bool is_operator;
  71. string username;
  72. bool is_identified;
  73. char sha1_pass[SHA_DIGEST_LENGTH];
  74. };
  75. mutex users_base_lock;
  76. vector<user>users_base;
  77.  
  78. mutex clients_lock;
  79. vector<int>clients;
  80. void disconnect(int Socket,string nickname){
  81. clients_lock.lock();
  82. shutdown(Socket,SHUT_RDWR);
  83. close(Socket);
  84. for(unsigned int i=0;i<clients.size();i++){
  85. if(clients[i]==Socket){
  86. clients.erase(clients.begin()+i);
  87. break;
  88. }
  89. }
  90. clients_lock.unlock();
  91. if(nickname==""){
  92. nickname="nobody";
  93. }
  94. cout << "SYSTEM: No." << Socket << "(" << nickname << ")" <<" disconnected\n";
  95. }
  96.  
  97. int get_user_id(string name){
  98. for(unsigned int i=0;i<users_base.size();i++){
  99. if(name==users_base[i].nickname){
  100. return i;
  101. }
  102. }
  103. return -1;
  104. }
  105.  
  106. mutex message_base_lock;
  107. struct message{
  108. int id; //номер записи во внутренней бд
  109. string message;
  110. };
  111. vector<message>message_base;
  112.  
  113. mutex pmessage_base_lock;
  114. struct pmessage{
  115. string sender;
  116. string recipient;
  117. string message;
  118. };
  119. vector<pmessage>pmessage_base;
  120. bool stop_server=false;
  121. void message_sender(){
  122. char message[256];
  123. while(1){
  124. while(message_base.size()>0){
  125. memset(message,0,256);
  126. message_base_lock.lock();
  127. strcpy(message,message_base[0].message.c_str());
  128. message_base.erase(message_base.begin());
  129. message_base_lock.unlock();
  130. for(unsigned int i=0;i<clients.size();i++){
  131. if(clients[i]!=message_base[0].id){
  132. send(clients[i],message,strlen(message),MSG_NOSIGNAL);
  133. }
  134. }
  135. }
  136. while(pmessage_base.size()>0){
  137. pmessage_base_lock.lock();
  138. string pmessage=pmessage_base[0].message;
  139. string recipient=pmessage_base[0].recipient;
  140. pmessage_base.erase(pmessage_base.begin());
  141. pmessage_base_lock.unlock();
  142. for(unsigned int i=0;i<users_base.size();i++){
  143. if(users_base[i].nickname==recipient && users_base[i].is_identified){
  144. send(users_base[i].socket,pmessage.c_str(),strlen(pmessage.c_str()),MSG_NOSIGNAL);
  145. }
  146. }
  147. }
  148. if(stop_server)
  149. break;
  150. usleep(1000000);
  151. }
  152. }
  153.  
  154.  
  155. mutex pmessage_file;
  156. mutex message_file;
  157. mutex users_file;
  158. void connected(int Socket)
  159. {
  160. user temp_user;
  161. memset(&temp_user,0,sizeof(temp_user));
  162. char buf[256];
  163. string command;
  164. vector<string>args;
  165. while(1){
  166. if(stop_server){
  167. send(Socket,"Server stopped. See you later!\n",strlen("Server stopped. See you later!\n"),MSG_NOSIGNAL);
  168. break;
  169. }
  170. command="";
  171. args.clear();
  172. memset(buf,0,256);
  173. int RecvSize = recv(Socket,buf,256,MSG_NOSIGNAL);
  174. if((RecvSize==0)&&(errno!=EAGAIN)){
  175. break;
  176. }else if(RecvSize>0){
  177. command=(string)buf;
  178. args=split_str_by_space(command);
  179. if(args.size()==0){
  180. continue;
  181. }
  182. if(args[0]=="/LIST"){
  183. for(int i=0;i<users_base.size();i++){
  184. send(Socket,users_base[i].nickname.c_str(),strlen(users_base[i].nickname.c_str()),MSG_NOSIGNAL);
  185. send(Socket,"\n",1,MSG_NOSIGNAL);
  186. }
  187. }
  188. else if(args[0]=="/USER"){
  189. if(args.size()<2){
  190. send(Socket,"Error: wrong input format.\n",strlen("Error: wrong input format.\n"),MSG_NOSIGNAL);
  191. continue;
  192. }
  193. bool user_found=false;
  194. for(int i=0;i<users_base.size();i++){
  195. if(users_base[i].username==args[1]){
  196. if(users_base[i].is_identified){
  197. send(Socket,"Error: This user already entered.\n",strlen("Error: This user already entered.\n"),MSG_NOSIGNAL);
  198. continue;
  199. }
  200. send(Socket,"Success: Username found. Enter password for identifying(/PASS <pass>).\n",strlen("Success: Username found. Enter password for identifying(/PASS <pass>).\n"),MSG_NOSIGNAL);
  201. temp_user.username=users_base[i].username;
  202. user_found=true;
  203. break;
  204. }
  205. }
  206. if(!user_found){
  207. send(Socket,"Error: username not found.\n",strlen("Error: username not found.\n"),MSG_NOSIGNAL);
  208. }
  209. }
  210. else if(args[0]=="/PASS"){
  211. if(args.size()<2){
  212. send(Socket,"Error: wrong input format.\n",strlen("Error: wrong input format.\n"),MSG_NOSIGNAL);
  213. continue;
  214. }
  215. if(temp_user.username!=""){
  216. for(int i=0;i<users_base.size();i++){
  217. if(users_base[i].username==temp_user.username){
  218.  
  219. unsigned char temp[SHA_DIGEST_LENGTH];
  220. unsigned char* str=(unsigned char*)args[1].c_str();
  221. SHA1((const unsigned char*)str,strlen((const char*)str),temp);
  222.  
  223. if(strncmp(users_base[i].sha1_pass,(const char*)temp,20)==0){
  224. send(Socket,"Success: Correct password. You identifyied in system.\n",strlen("Success: Correct password. You identifyied in system.\n"),MSG_NOSIGNAL);
  225. temp_user.is_identified=true;
  226. temp_user.socket=Socket;
  227. users_base[i].socket=Socket;
  228. temp_user.nickname=users_base[i].nickname;
  229. users_base[i].is_identified=true;
  230. temp_user.is_operator=users_base[i].is_operator;
  231. }else{
  232. send(Socket,"Error: wrong password.\n",strlen("Error: wrong password.\n"),MSG_NOSIGNAL);
  233. }
  234. break;
  235. }
  236. }
  237. }else{
  238. send(Socket,"Error:you didn't set username.Try to set it before inputting password.\n",strlen("Error:you didn't set username.Try to set it before inputting password.\n"),MSG_NOSIGNAL);
  239. }
  240. }
  241. else if(args[0]=="/CREATE"){
  242. if(args.size()<4){
  243. send(Socket,"Error:wrong input format.\n",strlen("Error:wrong input format.\n"),MSG_NOSIGNAL);
  244. continue;
  245. }
  246. bool user_found=false;
  247. for(unsigned int i=0;i<users_base.size();i++){
  248. if(args[1]==users_base[i].username || args[2]==users_base[i].nickname){
  249. send(Socket,"Error: This username or nickname already registred. Try another name.\n",strlen("Error: This username or nickname already registred. Try another name.\n"),MSG_NOSIGNAL);
  250. user_found=true;
  251. break;
  252. }
  253. }
  254. if(user_found){
  255. continue;
  256. }
  257. temp_user.is_operator=false;
  258. temp_user.socket=0;
  259. temp_user.is_identified=0;
  260. temp_user.nickname=args[2];
  261. temp_user.username=args[1];
  262.  
  263.  
  264. unsigned char* str=(unsigned char*)args[3].c_str();
  265. SHA1((const unsigned char*)str,strlen((const char*)str),(unsigned char*)temp_user.sha1_pass);
  266.  
  267. temp_user.socket=Socket;
  268. cout << "SYSTEM: user " << temp_user.nickname << " created.\n";
  269. users_base_lock.lock();
  270. users_base.push_back(temp_user);
  271. users_base_lock.unlock();
  272.  
  273. users_file.lock();
  274. string isop="false";
  275. if(temp_user.is_operator)
  276. isop="true";
  277. executioner.exec("INSERT INTO users_base (nickname,is_operator,username,sha1_pass) VALUES ('"+temp_user.nickname+"','"+isop+"','"+temp_user.username+"','somesha1')");
  278.  
  279. /*
  280. ofstream ufout;
  281. ufout.open("users",ios_base::app);
  282. ufout << temp_user.username << ' ' << temp_user.nickname << ' ' << "JUNK_NOT_PASSWORD";
  283.  
  284. if(temp_user.is_operator)
  285. ufout << " 1\n";
  286. else
  287. ufout << " 0\n";
  288. ufout.close();
  289. */
  290.  
  291. users_file.unlock();
  292.  
  293. send(Socket,"Success: User successfully created.\n",strlen("Success: User successfully created.\n"),MSG_NOSIGNAL);
  294. }
  295. else if(args[0]=="/INFO"){
  296. if(args.size()<2){
  297. send(Socket,"Error: wrong input format.\n",strlen("Error: wrong input format.\n"),MSG_NOSIGNAL);
  298. continue;
  299. }
  300. int i=get_user_id(args[1]);
  301. if(i==-1){
  302. send(Socket,"Error: User not found\n",strlen("Error: User not found\n"),MSG_NOSIGNAL);
  303. continue;
  304. }
  305. send(Socket,"Username:",strlen("Username:"),MSG_NOSIGNAL);
  306. send(Socket,users_base[i].username.c_str(),strlen(users_base[i].username.c_str()),MSG_NOSIGNAL);
  307. send(Socket,"\nNickname:",strlen("\nNickname:"),MSG_NOSIGNAL);
  308. send(Socket,users_base[i].nickname.c_str(),strlen(users_base[i].nickname.c_str()),MSG_NOSIGNAL);
  309. send(Socket,"\n",strlen("\n"),MSG_NOSIGNAL);
  310. }
  311. else if(args[0]=="/QUIT"){
  312. break;
  313. }
  314. else if(args[0]=="/HELP"){
  315. send(Socket,help_str,strlen(help_str),MSG_NOSIGNAL);
  316. if(temp_user.is_operator){
  317. send(Socket,help_admin_str,strlen(help_admin_str),MSG_NOSIGNAL);
  318. }
  319. }
  320. else if(temp_user.is_identified){
  321. if(args[0]=="/MSG"){
  322. if (args.size() < 3){
  323. send(Socket,"Error:wrong input format\n",strlen("Error:wrong input format\n"),MSG_NOSIGNAL);
  324. continue;
  325. }
  326. pmessage temp_pmessage;
  327. temp_pmessage.recipient=args[1];
  328. temp_pmessage.sender=temp_user.nickname;
  329. temp_pmessage.message="From "+temp_user.nickname+" to "+temp_pmessage.recipient+":";
  330. for(int i=2;i<args.size();i++){
  331. temp_pmessage.message+=" "+args[i];
  332. }
  333. temp_pmessage.message+="\n";
  334.  
  335. pmessage_file.lock();
  336. ofstream pmfout;
  337. pmfout.open("private_messages",ios_base::app);
  338. pmfout << temp_pmessage.message;
  339. pmfout.close();
  340. executioner.exec("INSERT INTO pmessage_base (recipient,sender,message) VALUES ('"+args[1]+"','"+temp_user.nickname+"','"+temp_pmessage.message+"')");
  341. pmessage_file.unlock();
  342.  
  343. pmessage_base_lock.lock();
  344. pmessage_base.push_back(temp_pmessage);
  345. pmessage_base_lock.unlock();
  346. send(Socket,"Success: private message sended.\n",strlen("Success: private message sended.\n"),MSG_NOSIGNAL);
  347. }
  348. else if(args[0]=="/RESTORE"){
  349. if (args.size() < 2){
  350. send(Socket,"Error:wrong input format\n",strlen("Error:wrong input format\n"),MSG_NOSIGNAL);
  351. continue;
  352. }
  353. if (args[1]=="private"){
  354. pmessage_file.lock();
  355. result data(executioner.exec("SELECT * FROM pmessage_base WHERE recipient = '"+temp_user.nickname+"' OR sender = '"+temp_user.nickname+"')"));
  356. for (result::const_iterator c = data.begin(); c != data.end(); ++c) {
  357. string message=c[0].as<string>()+"\n";
  358. send(Socket,message.c_str(),strlen(message.c_str()),MSG_NOSIGNAL);
  359. }
  360. pmessage_file.unlock();
  361. }else if(args[1]=="public"){
  362. message_file.lock();
  363.  
  364. result data(executioner.exec("SELECT message FROM message_base"));
  365. for (result::const_iterator c = data.begin(); c != data.end(); ++c) {
  366. string message=c[0].as<string>()+"\n";
  367. send(Socket,message.c_str(),strlen(message.c_str()),MSG_NOSIGNAL);
  368. }
  369.  
  370. message_file.unlock();
  371. }else{
  372. send(Socket,"Error:only private\\public chat bases avaliable!",strlen("Error:only private\\public chat bases avaliable!"),MSG_NOSIGNAL);
  373. }
  374. }
  375. else if(args[0]=="/DROP"){
  376. if (temp_user.username=="admin"){
  377. send(Socket,"nope\n",strlen("nope\n"),MSG_NOSIGNAL);
  378. continue;
  379. }
  380. for(int i=0;i<users_base.size();i++){
  381. if(users_base[i].username==temp_user.username){
  382. users_base.erase(users_base.begin()+i);
  383. send(Socket,"Success: User deleted.\n",strlen("Success: User deleted.\n"),MSG_NOSIGNAL);
  384. executioner.exec("DELETE FROM users_base WHERE username = '"+temp_user.username+"';");
  385. cout << "SYSTEM: User " << temp_user.username << " dropped and disconnected.\n";
  386. break;
  387. }
  388. }
  389. break;
  390. }
  391. else if(temp_user.is_operator && args[0]=="/SETPASS"){
  392. if(args.size()<3){
  393. send(Socket,"Error: wrong input format.\n",strlen("Error: wrong input format.\n"),MSG_NOSIGNAL);
  394. continue;
  395. }
  396. int i=get_user_id(args[1]);
  397. if(i==-1){
  398. send(Socket,"Error: User not found\n",strlen("Error: User not found\n"),MSG_NOSIGNAL);
  399. continue;
  400. }
  401. users_base_lock.lock();
  402. unsigned char* str=(unsigned char*)args[2].c_str();
  403. SHA1((const unsigned char*)str,strlen((const char*)str),(unsigned char*)users_base[i].sha1_pass);
  404. users_base_lock.unlock();
  405. ///Change pass in base!!!
  406. send(Socket,"Success: User password successfully changed.\n",strlen("Success: User password successfully changed.\n"),MSG_NOSIGNAL);
  407. }
  408. else{
  409. message temp_message;
  410. temp_message.id=Socket;
  411. temp_message.message=(string)temp_user.nickname+":"+command;
  412. message_file.lock();
  413. executioner.exec("INSERT INTO message_base (sender,message) VALUES ('"+temp_user.nickname+"','"+temp_message.message+"')");
  414. message_file.unlock();
  415. message_base_lock.lock();
  416. message_base.push_back(temp_message);
  417. message_base_lock.unlock();
  418. }
  419. }
  420. else{
  421. send(Socket,"Error: unknown command or you're not identified.Try /HELP for help.\n",strlen("Error: unknown command or you're not identified.Try /HELP for help.\n"),MSG_NOSIGNAL);
  422. }
  423. cout << "Username: " << temp_user.username << endl << '\t';
  424. for(auto x: args){
  425. cout <<x << ' ';
  426. }
  427. cout << endl;
  428. }
  429. }
  430.  
  431. disconnect(Socket,temp_user.nickname);
  432. return;
  433. }
  434.  
  435. void connection_maker(int MasterSocket){
  436. while(1){
  437. if(stop_server)
  438. break;
  439. int SlaveSocket=accept(MasterSocket,0,0);
  440. cout << "SYSTEM: No." << SlaveSocket << " connected.\n";
  441. send(SlaveSocket,welcome,strlen(welcome),MSG_NOSIGNAL);
  442. thread connection(connected, SlaveSocket);
  443. clients_lock.lock();
  444. clients.push_back(SlaveSocket);
  445. clients_lock.unlock();
  446. connection.detach();
  447. }
  448. }
  449.  
  450. int main(int argc,char** argv)
  451. {
  452. unsigned short int port=5002;
  453. string password="pass";
  454. bool db_restored=false;
  455. bool db_recreated=true;
  456. for(int i=1;i<argc;i++){
  457. if((string)argv[i]=="--help"){
  458. cout << "Usage: " << argv[0] << " [PARAMETERS]" << endl;
  459. cout << "Parameters:" << endl;
  460. cout << "--password [password] - set password of admin's account on the server(1024-65000)" << endl;
  461. cout << "--recreate-database - removes old files of server, like public and private message bases,users account bases" << endl;
  462. cout << "--port [PORT] - set unique port of server(default is 5002)" << endl;
  463. return 0;
  464. }
  465. else if((string)argv[i]=="--recreate-database"){
  466. executioner.exec("DELETE FROM users_base *");
  467. executioner.exec("DELETE FROM message_base *");
  468. executioner.exec("DELETE FROM pmessage_base *");
  469. }
  470. else if((string)argv[i]=="--password"){
  471. if(argc>i+1){
  472. try{
  473. password=argv[++i];
  474. }
  475. catch(exception &e){
  476. cout << e.what() << "Something wrong happend. Aborted...\n";
  477. return 9997;
  478. }
  479. }
  480. }
  481. else if((string)argv[i]=="--port"){
  482. if(argc>i+1){
  483. try{
  484. port=atoi(argv[++i]);
  485. if(port<1024 || port>65000){
  486. cout << "Wrong value of port, 1024-65000 must be. Aborted...\n";
  487. return 9997;
  488. }
  489. }
  490. catch(exception &e){
  491. cout << e.what() << "Something wrong happend. Aborted...\n";
  492. return 9997;
  493. }
  494. }
  495. }
  496. }
  497. cout << "Call this program with --help flag to see help" << endl;
  498. user admin;
  499. admin.is_operator=true;
  500. admin.socket=0;
  501. admin.username="admin";
  502. admin.nickname="admin";
  503.  
  504. SHA1((const unsigned char*)password.c_str(), strlen(password.c_str()), (unsigned char*)admin.sha1_pass);
  505.  
  506. admin.is_identified=false;
  507.  
  508. users_base.push_back(admin);
  509.  
  510. if(!database.is_open()){
  511. cout << "Cant open database. Aborted...";
  512. }
  513. cout << "SYSTEM: Database connected.\n";
  514.  
  515.  
  516. result data( executioner.exec("SELECT * FROM users_base;"));
  517.  
  518. for (result::const_iterator c = data.begin(); c != data.end(); ++c) {
  519. user temp_user;
  520. temp_user.nickname=c[0].as<string>();
  521. temp_user.is_operator=c[1].as<bool>();
  522. temp_user.username=c[2].as<string>();
  523. strncpy(temp_user.sha1_pass,(const char*)(c[2].as<string>().c_str()),20);
  524. users_base.push_back(temp_user);
  525. db_restored=true;
  526. }
  527.  
  528. if(!db_restored){
  529. cout << "SYSTEM: Old users restored.\n";
  530. db_recreated=false;
  531. }else{
  532. cout << "SYSTEM: Warning, \'users_base\' database not found! New file will be created.\n";
  533. }
  534.  
  535.  
  536. int MasterSocket = socket(AF_INET,SOCK_STREAM,0);
  537. if(MasterSocket<0){
  538. cout << "SYSTEM: Error on socket creating.\n";
  539. return 9999;
  540. }
  541. struct sockaddr_in SockAddr;
  542. SockAddr.sin_family=AF_INET;
  543. SockAddr.sin_port=htons(port);
  544. SockAddr.sin_addr.s_addr=htonl(INADDR_ANY);
  545. if(bind(MasterSocket, (struct sockaddr*)(&SockAddr),sizeof(SockAddr))<0){
  546. cout << "SYSTEM: Error on binding. Wait a minute please.\n";
  547. return 9998;
  548. }
  549. listen(MasterSocket,MAX_CONNECTIONS);
  550. cout << "SYSTEM: Server started.\n";
  551.  
  552. thread messenger(message_sender);
  553. cout << "SYSTEM: Messenger started.\n";
  554.  
  555. cout << "Port:" << port << endl;
  556. cout << "Admin password:" << password << endl;
  557. cout << "Database restored:" << db_restored << endl;
  558. cout << "Database recreated:" << db_recreated << endl;
  559.  
  560. thread connector(connection_maker,MasterSocket);
  561. connector.detach();
  562. cout << "SYSTEM: Connection maker started.\n";
  563.  
  564. string command="";
  565. while(1){
  566. getline(cin,command);
  567. if(command=="stop"){
  568. cout << "Server will be stopped.\n";
  569. stop_server=true;
  570. break;
  571. }
  572. else if(command=="settings"){
  573. cout << "Port:" << port << endl;
  574. cout << "Admin password:" << password << endl;
  575. cout << "Clients connected:" << clients.size() << endl;
  576. }
  577. else{
  578. cout << "Unknown command: " << command << endl;
  579. cout << "Avaliable commands:" << endl;
  580. cout << "\tstop - stop server" << endl;
  581. cout << "\tsettings - show server settings" << endl;
  582. }
  583. }
  584.  
  585. messenger.join();
  586. cout << "SYSTEM: Messenger stopped.\n";
  587. database.disconnect();
  588. cout << "SYSTEM: Database disconnected.\n";
  589. while(clients.size()>0)
  590. usleep(1000000);
  591. close(MasterSocket);
  592. cout << "SYSTEM: Server stopped.\n";
  593.  
  594. return 0;
  595. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement