Advertisement
pendekar_langit

tes

Jun 19th, 2016
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.00 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <signal.h>
  8. #include <pwd.h>
  9. #include <grp.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <sys/socket.h>
  13. #include <netinet/in.h>
  14. #include <arpa/inet.h>
  15.  
  16. #define BUFSIZE  4096
  17. #define ERROR      42
  18. #define LOG        44
  19. #define FORBIDDEN 403
  20. #define NOTFOUND  404
  21.  
  22. #define PORT 9090
  23. #define DOCROOT "htdocs"
  24.  
  25. #define USER "pendekar_langit"
  26.  
  27. void logger(int type, char *s1, char *s2, int socket_fd)
  28. {
  29.     int fd ;
  30.     char logbuffer[BUFSIZE*2];
  31.  
  32.     switch (type) {
  33.         case ERROR: snprintf(logbuffer, sizeof(logbuffer), "ERROR: %s:%s errno=%d exit pid=%d",s1, s2, errno,getpid()); break;
  34.         case FORBIDDEN: snprintf(logbuffer, sizeof(logbuffer),"FORBIDDEN: %s:%s",s1, s2); break;
  35.         case NOTFOUND: snprintf(logbuffer, sizeof(logbuffer),"NOT FOUND: %s:%s",s1, s2); break;
  36.         case LOG: snprintf(logbuffer, sizeof(logbuffer),"INFO: %s:%s:%d",s1, s2,socket_fd); break;
  37.     }  
  38.     if((fd = open("../apacih.log", O_CREAT| O_WRONLY | O_APPEND,0644)) >= 0) {
  39.         write(fd,logbuffer,strlen(logbuffer));
  40.         write(fd,"\n",1);      
  41.         close(fd);
  42.     }
  43.     if(type == ERROR) exit(3);
  44. }
  45.  
  46. void send_400(int socket_fd)
  47. {
  48.     write(socket_fd, "HTTP/1.1 400 Bad Request\nContent-Length: 98\nConnection: close\nContent-Type: text/html\n\n<html><head>\n<title>400 Bad Request</title>\n</head><body>\n<h1>400 Bad Request</h1>\n</body></html>\n",185);
  49.     exit(3);
  50. }
  51.  
  52. void send_403(int socket_fd)
  53. {
  54.     write(socket_fd, "HTTP/1.1 403 Forbidden\nContent-Length: 94\nConnection: close\nContent-Type: text/html\n\n<html><head>\n<title>403 Forbidden</title>\n</head><body>\n<h1>403 Forbidden</h1>\n</body></html>\n",179);
  55.     exit(3);
  56. }
  57.  
  58. void send_404(int socket_fd)
  59. {
  60.     write(socket_fd, "HTTP/1.1 404 Not Found\nContent-Length: 94\nConnection: close\nContent-Type: text/html\n\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>404 Not Found</h1>\n</body></html>\n",179);
  61.     exit(3);
  62. }
  63.  
  64. void web(int fd, int hit)
  65. {
  66.     int j, file_fd;
  67.     long i, ret, len;
  68.     static char buffer[BUFSIZE+1];
  69.  
  70.     ret = read(fd,buffer,BUFSIZE);
  71.     if(ret == 0 || ret == -1) {
  72.         logger(FORBIDDEN,"failed to read browser request","",fd);
  73.         send_400(fd);
  74.     }
  75.     if(ret > 0 && ret < BUFSIZE) buffer[ret]=0;
  76.     else buffer[0]=0;
  77.     for(i=0;i<ret;i++)  /* ganti newline */
  78.         if(buffer[i] == '\r' || buffer[i] == '\n')
  79.             buffer[i]='*';
  80.     logger(LOG,"request",buffer,hit);
  81.     if( strncmp(buffer,"GET ",4) && strncmp(buffer,"get ",4) ) {
  82.         logger(FORBIDDEN,"Only simple GET operation supported",buffer,fd);
  83.         send_403(fd);
  84.     }
  85.     for(i=4;i<BUFSIZE;i++) {
  86.         if(buffer[i] == ' ') { /* abaikan apapun setelah GET blablabla */
  87.             buffer[i] = 0;
  88.             break;
  89.         }
  90.     }
  91.     for(j=0;j<i-1;j++)  /* hindari path traversal .. */
  92.         if(buffer[j] == '.' && buffer[j+1] == '.') {
  93.             logger(FORBIDDEN,"Parent directory (..) path names not supported",buffer,fd);
  94.             send_403(fd);
  95.         }
  96.     if( !strncmp(&buffer[0],"GET /\0",6) || !strncmp(&buffer[0],"get /\0",6)) /* / berarti index.html */
  97.         strcpy(buffer,"GET /index.html");
  98.  
  99.     struct stat file_stat;
  100.     if(stat(&buffer[5], &file_stat) == 0) {
  101.         if(S_ISDIR(file_stat.st_mode)) /* kalau direktori */           
  102.             send_403(fd);
  103.     } else {
  104.         send_404(fd);
  105.     }
  106.  
  107.     if(( file_fd = open(&buffer[5],O_RDONLY)) == -1) {  /* baca file target */
  108.         logger(NOTFOUND, "failed to open file",&buffer[5],fd);
  109.         send_404(fd);
  110.     }
  111.     logger(LOG,"SEND",&buffer[5],hit);
  112.     len = (long)lseek(file_fd, (off_t)0, SEEK_END); /* ukur besar file */
  113.     lseek(file_fd, (off_t)0, SEEK_SET);
  114.     snprintf(buffer, sizeof(buffer), "HTTP/1.1 200 OK\nServer: Apacih/0.0\nContent-Length: %ld\nConnection: close\nContent-Type: text/html\n\n", len);
  115.     logger(LOG,"Header",buffer,hit);
  116.     write(fd,buffer,strlen(buffer));
  117.  
  118.     /* kirim per 4KB */
  119.     while ( (ret = read(file_fd, buffer, BUFSIZE)) > 0 ) {
  120.         write(fd,buffer,ret);
  121.     }
  122.     close(fd);
  123.     exit(1);
  124. }
  125.  
  126. int drop_privs(char *username) {
  127.     struct passwd *pw = getpwnam(username);
  128.     if (pw == NULL) {
  129.         fprintf(stderr, "User %s not found\n", username);
  130.         return 1;
  131.     }
  132.  
  133.     if (setgroups(0, NULL) != 0) {
  134.         perror("setgroups");
  135.         return 1;
  136.     }
  137.  
  138.     if (setgid(pw->pw_gid) != 0) {
  139.         perror("setgid");
  140.         return 1;
  141.     }
  142.  
  143.     if (setuid(pw->pw_uid) != 0) {
  144.         perror("setuid");
  145.         return 1;
  146.     }
  147.  
  148.     return 0;
  149. }
  150.  
  151. int main(int argc, char **argv)
  152. {
  153.     int i, port, pid, socket_desc, client_sock, hit, length;
  154.     // socklen_t length;
  155.     static struct sockaddr_in server, client;
  156.     // static struct sockaddr_in cli_addr;
  157.     // static struct sockaddr_in serv_addr;
  158.  
  159.     if(chdir(DOCROOT) == -1){
  160.         printf("ERROR: chdir %s\n", DOCROOT);
  161.         exit(4);
  162.     }
  163.  
  164.     printf("Jalan di background...\n");
  165.        
  166.     /* jadilah daemon */
  167.     if(fork() != 0)
  168.         return 0;
  169.     signal(SIGCLD, SIG_IGN);
  170.     signal(SIGHUP, SIG_IGN);
  171.     for(i=0;i<32;i++)
  172.         close(i);
  173.     setpgrp();
  174.     logger(LOG,"server starting","",getpid());
  175.        
  176.     /* setup socket */
  177.     socket_desc = socket(AF_INET, SOCK_STREAM,0);
  178.     if(socket_desc < 0)
  179.         logger(ERROR, "system call","socket",0);
  180.     puts("Socket created");
  181.     port = PORT;
  182.     server.sin_family = AF_INET;
  183.     server.sin_addr.s_addr = htonl(INADDR_ANY);
  184.     server.sin_port = htons(port);
  185.     if(bind(socket_desc, (struct sockaddr *)&server,sizeof(server)) < 0)
  186.         logger(ERROR,"system call","bind",0);  
  187.     puts("bind done"); 
  188.     if( listen(socket_desc, 64) < 0)
  189.         logger(ERROR,"system call","listen",0);
  190.     puts("Waiting for incoming connections...");
  191.     for(hit=1; ;hit++) {
  192.         length = sizeof(struct sockaddr_in);
  193.         client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&length);
  194.         printf("%d\n", client_sock);
  195.         if(client_sock < 0)
  196.             logger(ERROR,"system call","accept",0);
  197.         puts("Connection accepted");
  198.         if((pid = fork()) < 0) {
  199.             logger(ERROR,"system call","fork",0);
  200.         }else {
  201.             if(pid == 0) {  /* child */
  202.                 close(socket_desc);
  203.                 if (drop_privs(USER) == 0) {           
  204.                     web(client_sock, hit);
  205.                 }
  206.             } else {    /* parent */
  207.                 close(client_sock);
  208.             }
  209.         }
  210.     }
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement