Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <pwd.h>
- #include <grp.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #define BUFSIZE 4096
- #define ERROR 42
- #define LOG 44
- #define FORBIDDEN 403
- #define NOTFOUND 404
- #define PORT 9090
- #define DOCROOT "htdocs"
- #define USER "pendekar_langit"
- void logger(int type, char *s1, char *s2, int socket_fd)
- {
- int fd ;
- char logbuffer[BUFSIZE*2];
- switch (type) {
- case ERROR: snprintf(logbuffer, sizeof(logbuffer), "ERROR: %s:%s errno=%d exit pid=%d",s1, s2, errno,getpid()); break;
- case FORBIDDEN: snprintf(logbuffer, sizeof(logbuffer),"FORBIDDEN: %s:%s",s1, s2); break;
- case NOTFOUND: snprintf(logbuffer, sizeof(logbuffer),"NOT FOUND: %s:%s",s1, s2); break;
- case LOG: snprintf(logbuffer, sizeof(logbuffer),"INFO: %s:%s:%d",s1, s2,socket_fd); break;
- }
- if((fd = open("../apacih.log", O_CREAT| O_WRONLY | O_APPEND,0644)) >= 0) {
- write(fd,logbuffer,strlen(logbuffer));
- write(fd,"\n",1);
- close(fd);
- }
- if(type == ERROR) exit(3);
- }
- void send_400(int socket_fd)
- {
- 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);
- exit(3);
- }
- void send_403(int socket_fd)
- {
- 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);
- exit(3);
- }
- void send_404(int socket_fd)
- {
- 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);
- exit(3);
- }
- void web(int fd, int hit)
- {
- int j, file_fd;
- long i, ret, len;
- static char buffer[BUFSIZE+1];
- ret = read(fd,buffer,BUFSIZE);
- if(ret == 0 || ret == -1) {
- logger(FORBIDDEN,"failed to read browser request","",fd);
- send_400(fd);
- }
- if(ret > 0 && ret < BUFSIZE) buffer[ret]=0;
- else buffer[0]=0;
- for(i=0;i<ret;i++) /* ganti newline */
- if(buffer[i] == '\r' || buffer[i] == '\n')
- buffer[i]='*';
- logger(LOG,"request",buffer,hit);
- if( strncmp(buffer,"GET ",4) && strncmp(buffer,"get ",4) ) {
- logger(FORBIDDEN,"Only simple GET operation supported",buffer,fd);
- send_403(fd);
- }
- for(i=4;i<BUFSIZE;i++) {
- if(buffer[i] == ' ') { /* abaikan apapun setelah GET blablabla */
- buffer[i] = 0;
- break;
- }
- }
- for(j=0;j<i-1;j++) /* hindari path traversal .. */
- if(buffer[j] == '.' && buffer[j+1] == '.') {
- logger(FORBIDDEN,"Parent directory (..) path names not supported",buffer,fd);
- send_403(fd);
- }
- if( !strncmp(&buffer[0],"GET /\0",6) || !strncmp(&buffer[0],"get /\0",6)) /* / berarti index.html */
- strcpy(buffer,"GET /index.html");
- struct stat file_stat;
- if(stat(&buffer[5], &file_stat) == 0) {
- if(S_ISDIR(file_stat.st_mode)) /* kalau direktori */
- send_403(fd);
- } else {
- send_404(fd);
- }
- if(( file_fd = open(&buffer[5],O_RDONLY)) == -1) { /* baca file target */
- logger(NOTFOUND, "failed to open file",&buffer[5],fd);
- send_404(fd);
- }
- logger(LOG,"SEND",&buffer[5],hit);
- len = (long)lseek(file_fd, (off_t)0, SEEK_END); /* ukur besar file */
- lseek(file_fd, (off_t)0, SEEK_SET);
- 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);
- logger(LOG,"Header",buffer,hit);
- write(fd,buffer,strlen(buffer));
- /* kirim per 4KB */
- while ( (ret = read(file_fd, buffer, BUFSIZE)) > 0 ) {
- write(fd,buffer,ret);
- }
- close(fd);
- exit(1);
- }
- int drop_privs(char *username) {
- struct passwd *pw = getpwnam(username);
- if (pw == NULL) {
- fprintf(stderr, "User %s not found\n", username);
- return 1;
- }
- if (setgroups(0, NULL) != 0) {
- perror("setgroups");
- return 1;
- }
- if (setgid(pw->pw_gid) != 0) {
- perror("setgid");
- return 1;
- }
- if (setuid(pw->pw_uid) != 0) {
- perror("setuid");
- return 1;
- }
- return 0;
- }
- int main(int argc, char **argv)
- {
- int i, port, pid, socket_desc, client_sock, hit, length;
- // socklen_t length;
- static struct sockaddr_in server, client;
- // static struct sockaddr_in cli_addr;
- // static struct sockaddr_in serv_addr;
- if(chdir(DOCROOT) == -1){
- printf("ERROR: chdir %s\n", DOCROOT);
- exit(4);
- }
- printf("Jalan di background...\n");
- /* jadilah daemon */
- if(fork() != 0)
- return 0;
- signal(SIGCLD, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- for(i=0;i<32;i++)
- close(i);
- setpgrp();
- logger(LOG,"server starting","",getpid());
- /* setup socket */
- socket_desc = socket(AF_INET, SOCK_STREAM,0);
- if(socket_desc < 0)
- logger(ERROR, "system call","socket",0);
- puts("Socket created");
- port = PORT;
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = htonl(INADDR_ANY);
- server.sin_port = htons(port);
- if(bind(socket_desc, (struct sockaddr *)&server,sizeof(server)) < 0)
- logger(ERROR,"system call","bind",0);
- puts("bind done");
- if( listen(socket_desc, 64) < 0)
- logger(ERROR,"system call","listen",0);
- puts("Waiting for incoming connections...");
- for(hit=1; ;hit++) {
- length = sizeof(struct sockaddr_in);
- client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&length);
- printf("%d\n", client_sock);
- if(client_sock < 0)
- logger(ERROR,"system call","accept",0);
- puts("Connection accepted");
- if((pid = fork()) < 0) {
- logger(ERROR,"system call","fork",0);
- }else {
- if(pid == 0) { /* child */
- close(socket_desc);
- if (drop_privs(USER) == 0) {
- web(client_sock, hit);
- }
- } else { /* parent */
- close(client_sock);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement