/** * Main function for the thread that runs the client-side of the * interaction with the upgraded socket. * * @param cls the client socket */ static void * run_usock_client (void *cls) { wr_socket *sock = cls; send_all (*sock, "GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n"); recv_hdr (*sock); recv_all (*sock, "Hello"); send_all (*sock, "World"); recv_all (*sock, "Finished"); wr_close (*sock); done = 1; return NULL; }
void http1_1_handler(int clientDescriptor) { std::vector<std::string> lines = get_request_lines(clientDescriptor); std::vector<std::string> startString = split(lines[0], ' '); if (!check_request(clientDescriptor, lines, startString)) { return; } std::string requestPath = startString[1]; if (requestPath[0] == '/') { requestPath = requestPath.substr(1, requestPath.length() - 1); } for (size_t i = 1; i < requestPath.length(); ++i) { if (requestPath[i] == '.' && requestPath[i - 1] == '.') { process_error(clientDescriptor, FORBIDDEN); return; } } if (requestPath == "") { requestPath += homePageFile; } std::string mime = define_MIME(requestPath); if (mime == "none") { requestPath += ".html"; mime = "text/html"; } std::string fileBuf; FILE *file = popen(("python3 " + CGIPath + "cgi.py " + sitePath + requestPath + " " + CGIPath).c_str(), "r"); while (!feof(file)) { fileBuf += fgetc(file); } fileBuf.pop_back(); http_reply(clientDescriptor, OK, mime, fileBuf); wr_close(clientDescriptor); }
void http1_1_handler(int clientDescriptor) { std::vector<std::string> lines = get_request_lines(clientDescriptor); std::vector<std::string> startString = split(lines[0], ' '); if (!check_request(clientDescriptor, lines, startString)) { return; } std::string requestPath = startString[1]; if (requestPath[0] == '/') { requestPath = requestPath.substr(1, requestPath.length() - 1); } for (size_t i = 1; i < requestPath.length(); ++i) { if (requestPath[i] == '.' && requestPath[i - 1] == '.') { process_error(clientDescriptor, FORBIDDEN); return; } } if (requestPath == "") { requestPath += homePageFile; } std::string mime = define_MIME(requestPath); if (mime == "none") { requestPath += ".html"; mime = "text/html"; } std::string fileBuf; if (get_file(sitePath + requestPath, fileBuf) == -1) { process_error(clientDescriptor, NOT_FOUND); return; } http_reply(clientDescriptor, OK, mime, fileBuf); wr_close(clientDescriptor); }
void wr_connect(char *host, int port, char *login, char *password) { SHA_CTX c; static unsigned char hex[] = "0123456789abcdef"; unsigned char sha[SHA_DIGEST_LENGTH]; struct hostent *hp; int i, on = 1; /* disconnect active socket */ if(wr_socket >= 0) wr_close(); /* reset current working directory */ strlcpy(wr_files_cwd, "/", sizeof(wr_files_cwd)); /* copy values */ wr_port = port; if(port != 2000) snprintf(wr_host, sizeof(wr_host), "%s:%d", host, port); else strlcpy(wr_host, host, sizeof(wr_host)); strlcpy(wr_login, login, sizeof(wr_login)); strlcpy(wr_password, password, sizeof(wr_password)); /* log */ wr_printf_prefix("Connecting to %s...\n", wr_host); /* create new socket */ wr_socket = socket(AF_INET, SOCK_STREAM, 0); if(wr_socket < 0) { wr_printf_prefix("Could not create a socket: %s\n", strerror(errno)); wr_close(); return; } /* set socket options */ if(setsockopt(wr_socket, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) { wr_printf_prefix("Could not set socket options: %s\n", strerror(errno)); wr_close(); return; } /* init address */ memset(&wr_addr, 0, sizeof(wr_addr)); wr_addr.sin_family = AF_INET; wr_addr.sin_port = htons(port); if(!inet_aton(host, &wr_addr.sin_addr)) { hp = gethostbyname(host); if(!hp) { wr_printf_prefix("Could not resolve hostname %s: %s\n", host, hstrerror(h_errno)); wr_close(); return; } memcpy(&wr_addr.sin_addr, hp->h_addr, sizeof(wr_addr.sin_addr)); } /* connect TCP socket */ if(connect(wr_socket, (struct sockaddr *) &wr_addr, sizeof(wr_addr)) < 0) { wr_printf_prefix("Could not connect to %s: %s\n", host, strerror(errno)); wr_close(); return; } /* create SSL context */ wr_ssl_ctx = SSL_CTX_new(TLSv1_client_method()); if(!wr_ssl_ctx) { wr_printf_prefix("Could not create SSL context: %s\n", ERR_reason_error_string(ERR_get_error())); wr_close(); return; } if(SSL_CTX_set_cipher_list(wr_ssl_ctx, "ALL") != 1) { wr_printf_prefix("Could not set SSL cipher list: %s\n", ERR_reason_error_string(ERR_get_error())); wr_close(); return; } /* create SSL socket */ wr_ssl = SSL_new(wr_ssl_ctx); if(!wr_ssl) { wr_printf_prefix("Could not create SSL socket: %s\n", ERR_reason_error_string(ERR_get_error())); wr_close(); return; } if(SSL_set_fd(wr_ssl, wr_socket) != 1) { wr_printf_prefix("Could not set SSL file descriptor: %s\n", ERR_reason_error_string(ERR_get_error())); wr_close(); return; } if(SSL_connect(wr_ssl) != 1) { wr_printf_prefix("Could not connect to %s via SSL: %s\n", host, ERR_reason_error_string(ERR_get_error())); wr_close(); return; } /* log */ wr_printf_prefix("Connected using %s/%s/%u bits, logging in...\n", SSL_get_cipher_version(wr_ssl), SSL_get_cipher_name(wr_ssl), SSL_get_cipher_bits(wr_ssl, NULL)); /* send initial login */ wr_send_command("HELLO%s", WR_MESSAGE_SEPARATOR); /* hash the password */ memset(wr_password_sha, 0, sizeof(wr_password_sha)); if(strlen(wr_password) > 0) { SHA1_Init(&c); SHA1_Update(&c, (unsigned char *) wr_password, strlen(wr_password)); SHA1_Final(sha, &c); /* map into hexademical characters */ for(i = 0; i < SHA_DIGEST_LENGTH; i++) { wr_password_sha[i+i] = hex[sha[i] >> 4]; wr_password_sha[i+i+1] = hex[sha[i] & 0x0F]; } wr_password_sha[i+i] = '\0'; }
void process_error(int clientDescriptor, HttpResponse error) { std::string buf; get_file(std::to_string(error) + ".html", buf); http_reply(clientDescriptor, error, "text/html", buf); wr_close(clientDescriptor); }