| 关键词: nbsp HTTP outdata server body filename SIZE char return addr |
//simple HTTP server for Windows NT //created by int3 //supports GET, HEAD, other method not support //allows access to files in certain directory //echos version back, but disconnects connection always so act like HTTP/1.0 //current version not support directory, only file, future version fix problem #include <winsock2.h> #include <windows.h> #include <stdio.h> #define HTTP_SERVER_PORT 80 #define HTTP_SERVER_OUTPUT_HEAD "HTTP/%d.%d 200 OK\n" "Date: %s" "Server: Windows\n" "Last-Modified: Tue, 15 Nov 2005 13:24:10 GM T\n"\ "Accept-Ranges: bytes\n" "Content-Length: %d\n" "Connection: close\n" "Content-Type: text/html; charset=ASCII\n\n" #define METHOD_NOT_IMPLEMENTED "<html><head><title>BAD REQUEST</title></head><body><h1>BAD REQUEST: HTTP STATUS CODE 501</h1></body></html>" #define HTTP_ERROR_404 "<html><head><title>ERROR CODE 404</title></head><body><h1>PAGE NOT FOUND: HTTP STATUS CODE 404</h1></body></html>" #define HTTP_RECV_SIZE 1024 #define HTTP_HEADER_SIZE 1024 int http_server; int ctrl_c_handler(DWORD x); int accept_loop(int g); char http_dir[256]; struct sockaddr_in my_addr; char *http_read_file(char *filename, char **body); int main(int argc, char **argv) { WSADATA wsadata; SetConsoleCtrlHandler((PROC) ctrl_c_handler, TRUE); if (argc != 2) { puts("server files_dir"); return 1; } strncpy(http_dir, argv[1], 256); http_dir[255] = 0; //insert null terminator if (WSAStartup(0x202, &wsadata) != 0) { puts("WSAStartup failed"); return 1; } http_server = socket(AF_INET, SOCK_STREAM, 0); //create socket if (http_server == -1) { puts("socket failed"); return 1; } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(HTTP_SERVER_PORT); my_addr.sin_addr.s_addr = INADDR_ANY; if (bind(http_server, &my_addr, sizeof(my_addr)) == -1) { //bind to port puts("socket failed"); return 1; } if (listen(http_server, 1) == -1) { //listen on port puts("listen failed"); return 1; } accept_loop(0); return 0; } int ctrl_c_handler(DWORD x) { puts("terminate server"); fflush(stdout); closesocket(http_server); WSACleanup(); //close winsock ExitProcess(0); } int accept_loop(int g) { struct sockaddr_in r_addr; while (1) { char filename[256]; char indata[HTTP_RECV_SIZE+1]; char *outdata; int sin_size = sizeof(r_addr); int http_client = accept(http_server, &r_addr, &sin_size); int data_read; int ver1, ver2; time_t t = time(0); //get time char *ch; char *body = 0; int body_size; CreateThread(NULL, 0, (PROC) accept_loop, 0, 0, NULL); //create new thread if (http_client == -1) { puts("accept failed"); return 1; } printf("New connection by %s\n", inet_ntoa(r_addr.sin_addr)); //display remote IP address fflush(stdout); //send to output data_read = recv(http_client, indata, HTTP_RECV_SIZE, 0); if (data_read == -1) { puts("recv failed"); return 1; } indata[data_read] = 0; //null terminator ch = strstr(indata, "HTTP/"); sscanf(ch, "HTTP/%d.%d", &ver1, &ver2); if (!strncmp(indata, "GET", 3)) { sscanf(indata, "GET %255s", filename); body = http_read_file(filename, &body); if (body != NULL) { body_size = strlen(body); outdata = malloc(body_size + HTTP_HEADER_SIZE); sprintf(outdata, HTTP_SERVER_OUTPUT_HEAD "%s", ver1, ver2, ctime(&t), body_size, body); //write head+body to buffer } else { outdata = malloc(strlen(HTTP_ERROR_404) + 1); strcpy(outdata, HTTP_ERROR_404); } } else if (!strncmp(indata, "HEAD", 4)) { sscanf(indata, "HEAD %255s", filename); body = http_read_file(filename, &body); if (body != NULL) { body_size = strlen(body); outdata = malloc(HTTP_HEADER_SIZE); sprintf(outdata, HTTP_SERVER_OUTPUT_HEAD, ver1, ver2, ctime(&t), body_size); //write head to buffer } else { outdata = malloc(strlen(HTTP_ERROR_404) + 1); strcpy(outdata, HTTP_ERROR_404); } } else if (!strncmp(indata, "OPTIONS", 7)) { //NOT IMPLEMENTED YET outdata = malloc(strlen(METHOD_NOT_IMPLEMENTED) + 1); strcpy(outdata, METHOD_NOT_IMPLEMENTED); } else { //SO FAR POST, etc. NOT IMPLEMENTED outdata = malloc(strlen(METHOD_NOT_IMPLEMENTED) + 1); strcpy(outdata, METHOD_NOT_IMPLEMENTED); } //puts(indata); //display request send(http_client, outdata, strlen(outdata), 0); //send data free(outdata); free(body); //free memory invalid: closesocket(http_client); } } //read file filename from html dir into buffer body char *http_read_file(char *filename) { FILE *f; char fname[512]; int size; char *ch = filename; char *buffer; int access_denied = 0; strcpy(fname, http_dir); while (*ch != 0) { if (*ch == '/') *ch = '\\'; if (*ch == '.') if (*(ch+1) == '/') access_denied = 1; //deny access ./ to rm ../ vuln ch++; //next char } strcat(fname, filename); if (access_denied == 1) { printf("access denied: filename %s\n", fname); return NULL; } f = fopen(fname, "rb"); //open file for read if (f == NULL) { printf("file open failed: filename %s\n", fname); return NULL; } fseek(f, 0, 2); //seek to end size = ftell(f); rewind(f); if ((buffer = malloc(size + 1)) == NULL) { puts("error: memory allocation failed"); exit(1); } if (fread(buffer, size, 1, f) == -1) {//read file printf("file read failed: filename %s\n", fname); free(buffer); return NULL; } buffer[size] = 0; //null terminator return buffer; |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|