// perform FTP USER command, take any username as valid void command_user(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int len = strlen(line); if (len < 6) { send_code(client_info->fd, 500); return; } send_code(client_info->fd, 331); }
/* Send a literal or distance tree in compressed form, using the codes in bl_tree. */ void CodeTree::send_tree (ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(curlen, bl_tree); count--; } assert(count >= 3 && count <= 6); send_code(REP_3_6, bl_tree); send_bits(count-3, 2); } else if (count <= 10) { send_code(REPZ_3_10, bl_tree); send_bits(count-3, 3); } else { send_code(REPZ_11_138, bl_tree); send_bits(count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } }
void InterpretedIC::clear() { if (is_empty()) return; if (send_type() == Bytecodes::polymorphic_send) { // recycle PIC assert(second_word()->is_objArray(), "must be a pic"); Interpreter_PICs::deallocate(objArrayOop(second_word())); } set(Bytecodes::original_send_code_for(send_code()), oop(selector()), smiOop_zero); }
void InterpretedIC::replace(nmethod* nm) { // replace entry with nm's klass by nm (if entry exists) smiOop entry_point = smiOop(nm->jump_table_entry()->entry_point()); assert(selector() == nm->key.selector(), "mismatched selector"); if (is_empty()) return; switch (send_type()) { case Bytecodes::accessor_send: // fall through case Bytecodes::primitive_send: // fall through case Bytecodes::predicted_send: // fall through case Bytecodes::interpreted_send: { // replace the monomorphic interpreted send with compiled send klassOop receiver_klass = klassOop(second_word()); assert(receiver_klass->is_klass(), "receiver klass must be a klass"); if (receiver_klass == nm->key.klass()) { set(Bytecodes::compiled_send_code_for(send_code()), entry_point, nm->key.klass()); } } break; case Bytecodes::compiled_send: // fall through case Bytecodes::megamorphic_send: // replace the monomorphic compiled send with compiled send set(send_code(), entry_point, nm->key.klass()); break; case Bytecodes::polymorphic_send: { objArrayOop pic = pic_array(); for (int index = pic->length(); index > 0; index -= 2) { klassOop receiver_klass = klassOop(pic->obj_at(index)); assert(receiver_klass->is_klass(), "receiver klass must be klass"); if (receiver_klass == nm->key.klass()) { pic->obj_at_put(index-1, entry_point); return; } } } // did not find klass break; default: fatal("unknown send type"); } LOG_EVENT3("interpreted IC at 0x%x: new nmethod 0x%x for klass 0x%x replaces old entry", this, nm, nm->key.klass()); }
void InterpretedIC::replace(LookupResult result, klassOop receiver_klass) { // IC entries before modification - used for loging only Bytecodes::Code code_before = send_code(); oop word1_before = first_word(); oop word2_before = second_word(); int transition = 0; // modify IC guarantee(word2_before == receiver_klass, "klass should be the same"); if (result.is_empty()) { clear(); transition = 1; } else if (result.is_method()) { if (send_type() == Bytecodes::megamorphic_send) { set(send_code(), result.method(), receiver_klass); transition = 2; } else { // Please Fix this Robert // implement set_monomorphic(klass, method) clear(); transition = 3; } } else { if (send_type() == Bytecodes::megamorphic_send) { set(send_code(), oop(result.entry()), receiver_klass); transition = 4; } else { assert(result.is_entry(), "must be jump table entry"); // a jump table entry of a nmethod is found so let's update the current send set(Bytecodes::compiled_send_code_for(send_code()), oop(result.entry()), receiver_klass); transition = 5; } } // IC entries after modification - used for loging only Bytecodes::Code code_after = send_code(); oop word1_after = first_word(); oop word2_after = second_word(); // log modification LOG_EVENT3("InterpretedIC::replace: IC at 0x%x: entry for klass 0x%x replaced (transition %d)", this, receiver_klass, transition); LOG_EVENT3(" from (%s, 0x%x, 0x%x)", Bytecodes::name(code_before), word1_before, word2_before); LOG_EVENT3(" to (%s, 0x%x, 0x%x)", Bytecodes::name(code_after ), word1_after , word2_after ); }
void read_games_list(int fd){ char code; gameID game_id = 0; send_code(fd, LIST_GAMES_CODE); while((code = recv_code(fd)) == SUCCESS_RESPONSE_CODE){ game_id = recv_game_id(fd); fprintf(stdout, "%d \n", game_id); } if(code != END_OF_LIST_CODE) fprintf(stdout, "Error during reading the list. \n"); }
// perform FTP PWD command, prints current directory void command_pwd(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int len = strlen(line); if (len != 3) { send_code(client_info->fd, 500); return; } send_code_param(client_info->fd, 257, client_info->dir); }
void start_new_game(int fd){ char code; gameID game_id; send_code(fd,NEW_GAME_CODE); code = recv_code(fd); switch(code){ case SUCCESS_RESPONSE_CODE: game_id = recv_game_id(fd); fprintf(stdout, "New game's id: %d\n", game_id); break; default: fprintf(stdout, "Error occured (errcode: %d)\n",code); } }
// perform FTP SYST command, identify as a standard UNIX FTP server void command_syst(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int len = strlen(line); if (len != 4) { send_code(client_info->fd, 500); return; } send_code_param(client_info->fd, 215, "UNIX Type: L8"); }
// perform FTP PORT command, prepare for active data connection void command_port(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int ip1, ip2, ip3, ip4, port1, port2; if (sscanf(line + 5, "%d,%d,%d,%d,%d,%d", &ip1, &ip2, &ip3, &ip4, &port1, &port2) != 6) { send_code(client_info->fd, 500); return; } client_info->data_connection_mode = CONN_MODE_ACTIVE; memset(&(client_info->active_addr), 0, sizeof(client_info->active_addr)); client_info->active_addr.sin_family = AF_INET; char buf_addr[32]; sprintf(buf_addr, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); inet_pton(AF_INET, buf_addr, &(client_info->active_addr.sin_addr)); client_info->active_addr.sin_port = htons((port1 << 8) + port2); send_code(client_info->fd, 200); }
// perform FTP PASV command, prepare for passive data connection void command_pasv(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int len = strlen(line); if (len != 4) { send_code(client_info->fd, 500); return; } if (client_info->passive_fd != 0) { close(client_info->passive_fd); client_info->passive_fd = 0; } struct sockaddr_in s; socklen_t l; l = sizeof(s); getsockname(client_info->fd, (struct sockaddr *)&s, &l); char * ip = inet_ntoa(s.sin_addr); if (! ip) epicfail("inet_ntoa"); client_info->data_connection_mode = CONN_MODE_PASSIVE; client_info->passive_fd = create_tcp_server_socket(ip, 0); l = sizeof(s); getsockname(client_info->passive_fd, (struct sockaddr *)&s, &l); int port = ntohs(s.sin_port); int ip1, ip2, ip3, ip4, port1, port2; if (sscanf(ip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) != 4) epicfail("command_pasv"); port1 = port >> 8; port2 = port & 0xff; char p[64]; sprintf(p, "%d,%d,%d,%d,%d,%d", ip1, ip2, ip3, ip4, port1, port2); send_code_param(client_info->fd, 227, p); }
int handle_client(int csockfd, int timeout) { uint64_t fsize; ssize_t namelen; char buf[BUF_SZ]; char path[DIRLEN + FNAME_LENGTH + 1]; char *filename = path + DIRLEN; ssize_t nbytes; bool delete_file; /* reading filesize */ nbytes = read_tout(csockfd, &fsize, sizeof(fsize), timeout, 0, false); if (nbytes != sizeof(fsize)) { log("Filesize reading error\n"); return -1; } fsize = le64toh(fsize); if (fsize > ((uint64_t)1 << 62)) { log("Filesize is too big\n"); send_code(csockfd, CODE_BAD_FILELEN, timeout); return -1; } if (send_code(csockfd, CODE_ACK, timeout)) return -1; log("Filesize %llu accepted\n", fsize); /* reading filename */ //memset(path, 0, sizeof(path)); memcpy(path, DIRNAME, DIRLEN); nbytes = read_tout(csockfd, buf, sizeof(buf), timeout, MSG_PEEK, false); if (nbytes > 0) { namelen = fname_len(buf, nbytes); if (namelen <= 0 || namelen > FNAME_LENGTH) { log("Bad filename length\n"); send_code(csockfd, CODE_BAD_FILELEN, timeout); return -1; } /* There is no lseek() for socket, so .. */ read_tout(csockfd, filename, namelen + 1, 0, 0, true); } else { log("Filename reading error"); send_code(csockfd, CODE_ERR_UNKNOWN, timeout); return -1; } if (!check_fname(filename)) { log("Bad filename (check_fname)!\n"); send_code(csockfd, CODE_BAD_FILENAME, timeout); return -1; } if (access(path, F_OK) != -1) { send_code(csockfd, CODE_FILE_EXISTS, timeout); return -1; } int fd = open(path, O_CREAT | O_WRONLY, 0600); if (fd == -1) { perror("open()"); if (errno == ENAMETOOLONG) send_code(csockfd, CODE_BAD_FILELEN, timeout); else send_code(csockfd, CODE_ERR_UNKNOWN, timeout); return -1; } if (send_code(csockfd, CODE_ACK, timeout)) return -1; log("Filename `%s` accepted and file exchange started\n", filename); /* reading file */ nbytes = 0; delete_file = false; do { fsize -= (uint64_t) nbytes; nbytes = read_tout(csockfd, buf, sizeof(buf), timeout, 0, false); if (nbytes > 0) { if (write(fd, buf, min(nbytes, fsize)) == -1) { perror("write()"); send_code(csockfd, CODE_ERR_TRANSFER, timeout); delete_file = true; break; } } } while (nbytes > 0 && nbytes < fsize); if (nbytes < 0) { log("Error while transfer\n"); send_code(csockfd, CODE_ERR_TRANSFER, timeout); delete_file = true; } close(fd); if (delete_file) { log("Deleting file\n"); unlink(path); return -1; } if (send_code(csockfd, CODE_ACK, timeout)) log("Warning: send_code was unsuccessful, but file recieved ok"); log("File `%s` recieved ok!\n", path); return 0; }
/* Serve the client that connected to the webserver */ static int serve_client(t_session *session) { int result, length, auth_result; char *qmark, chr, *header; t_host *host_record; t_access access; t_deny_body *deny_body; t_req_method request_method; t_ip_addr ip_addr; #ifdef ENABLE_XSLT char *xslt_file; #endif #ifdef ENABLE_TOOLKIT int i; t_toolkit_options toolkit_options; #endif #ifdef ENABLE_RPROXY t_rproxy *rproxy; #endif #ifdef ENABLE_DEBUG session->current_task = "fetch & parse request"; #endif if ((result = fetch_request(session)) != 200) { session->request_method = GET; return result; } else if ((result = parse_request(session, session->header_length + session->content_length)) != 200) { session->request_method = GET; return result; } #ifdef ENABLE_DEBUG session->current_task = "serve client"; #endif session->time = time(NULL); /* Hide reverse proxies */ if (in_iplist(session->config->hide_proxy, &(session->ip_address))) { if (last_forwarded_ip(session->http_headers, &ip_addr) == 0) { if (reposition_client(session, &ip_addr) != -1) { copy_ip(&(session->ip_address), &ip_addr); } } } /* SSH tunneling */ #ifdef ENABLE_RPROXY if (session->request_method == CONNECT) { if (in_iplist(session->config->tunnel_ssh, &(session->ip_address)) == false) { return 405; } #ifdef ENABLE_SSL if (session->binding->use_ssl) { return 405; } #endif if (strcmp(session->request_uri, "localhost:22") != 0) { if (strcmp(session->request_uri, "127.0.0.1:22") != 0) { if (strcmp(session->request_uri, "::1.22") != 0) { return 403; } } } log_system(session, "SSH tunnel requested"); if (tunnel_ssh_connection(session->client_socket) != 0) { log_system(session, "SSH tunnel failed"); } else { log_system(session, "SSH tunnel terminated"); } session->keep_alive = false; return 200; } #endif /* Find host record */ if (session->hostname != NULL) { if (remove_port_from_hostname(session) == -1) { log_error(session, "error removing port from hostname"); return 500; } if ((host_record = get_hostrecord(session->config->first_host, session->hostname, session->binding)) != NULL) { session->host = host_record; #ifdef ENABLE_TOMAHAWK session->last_host = host_record; #endif } } session->host->access_time = session->time; #ifdef ENABLE_SSL /* SSL client authentication */ if (session->binding->use_ssl) { if ((session->host->ca_certificate != NULL) && (ssl_has_peer_cert(&(session->ssl_context)) == false)) { log_error(session, "Missing client SSL certificate"); return 440; } } #endif /* Enforce usage of first hostname */ if (session->host->enforce_first_hostname && (session->hostname != NULL)) { if (**(session->host->hostname.item) != '*') { if (strcmp(session->hostname, *(session->host->hostname.item)) != 0) { session->cause_of_301 = enforce_first_hostname; return 301; } } } /* Enforce usage of SSL */ #ifdef ENABLE_SSL if (session->host->require_ssl && (session->binding->use_ssl == false)) { if ((qmark = strchr(session->uri, '?')) != NULL) { *qmark = '\0'; session->vars = qmark + 1; session->uri_len = strlen(session->uri); } session->cause_of_301 = require_ssl; return 301; } #endif /* Deny matching bodies */ if (session->body != NULL) { chr = *(session->body + session->content_length); *(session->body + session->content_length) = '\0'; deny_body = session->host->deny_body; while (deny_body != NULL) { if (strpcmp(session->body, &(deny_body->pattern)) == 0) { if ((session->config->ban_on_denied_body > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_denied_body, session->config->kick_on_ban); log_system(session, "Client banned because of denied body"); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } log_exploit_attempt(session, "denied body", session->body); #ifdef ENABLE_TOMAHAWK increment_counter(COUNTER_EXPLOIT); #endif #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_exploit(session); monitor_event("Request body denied for %s", session->host->hostname.item[0]); } #endif *(session->body + session->content_length) = chr; return 403; } deny_body = deny_body->next; } *(session->body + session->content_length) = chr; } /* Websocket */ if (session->request_method == GET) { if ((header = get_http_header("Connection:", session->http_headers)) != NULL) { if (strcasestr(header, "upgrade") != NULL) { if ((header = get_http_header("Upgrade:", session->http_headers)) != NULL) { if (strcasecmp(header, "websocket") == 0) { switch (access = allow_client(session)) { case deny: log_error(session, fb_accesslist); return 403; case allow: break; case pwd: case unspecified: if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) { return auth_result; } } session->keep_alive = false; if (forward_to_websocket(session) == -1) { return 500; } return 200; } } } } } #ifdef ENABLE_RPROXY /* Reverse proxy */ rproxy = session->host->rproxy; while (rproxy != NULL) { if (rproxy_match(rproxy, session->request_uri)) { if (rproxy_loop_detected(session->http_headers)) { return 508; } if ((qmark = strchr(session->uri, '?')) != NULL) { *qmark = '\0'; session->vars = qmark + 1; } if (validate_url(session) == false) { return -1; } if ((session->vars != NULL) && (session->host->secure_url)) { if (forbidden_chars_present(session->vars)) { log_error(session, "URL contains forbidden characters"); return 403; } } if (duplicate_host(session) == false) { log_error(session, "duplicate_host() error"); return 500; } if ((result = uri_to_path(session)) != 200) { return result; } if (session->host->ignore_dot_hiawatha == false) { if (load_user_config(session) == -1) { return 500; } } if ((result = copy_directory_settings(session)) != 200) { return result; } switch (access = allow_client(session)) { case deny: log_error(session, fb_accesslist); return 403; case allow: break; case pwd: case unspecified: if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) { return auth_result; } } /* Prevent SQL injection */ if (session->host->prevent_sqli) { result = prevent_sqli(session); if (result == 1) { session->error_cause = ec_SQL_INJECTION; } if (result != 0) { return -1; } } /* Prevent Cross-site Scripting */ if (session->host->prevent_xss != p_no) { if (prevent_xss(session) > 0) { if (session->host->prevent_xss == p_block) { session->error_cause = ec_XSS; return -1; } } } /* Prevent Cross-site Request Forgery */ if (session->host->prevent_csrf != p_no) { if (prevent_csrf(session) > 0) { if (session->host->prevent_csrf == p_block) { session->error_cause = ec_CSRF; return -1; } } } return proxy_request(session, rproxy); } rproxy = rproxy->next; } #endif /* Actions based on request method */ switch (session->request_method) { case TRACE: if (session->binding->enable_trace == false) { return 501; } return handle_trace_request(session); case PUT: case DELETE: if ((session->binding->enable_alter == false) && (session->host->webdav_app == false)) { return 501; } break; case unknown: return 400; case unsupported: if (session->host->webdav_app == false) { return 501; } break; default: break; } if (duplicate_host(session) == false) { log_error(session, "duplicate_host() error"); return 500; } #ifdef ENABLE_TOOLKIT if (session->host->ignore_dot_hiawatha == false) { if (load_user_root_config(session) == -1) { return 500; } } /* URL toolkit */ init_toolkit_options(&toolkit_options); toolkit_options.method = session->method; toolkit_options.website_root = session->host->website_root; toolkit_options.url_toolkit = session->config->url_toolkit; toolkit_options.allow_dot_files = session->host->allow_dot_files; toolkit_options.http_headers = session->http_headers; #ifdef ENABLE_SSL toolkit_options.use_ssl = session->binding->use_ssl; #endif if (((session->request_method != PUT) && (session->request_method != DELETE)) || session->host->webdav_app) { for (i = 0; i < session->host->toolkit_rules.size; i++) { if ((result = use_toolkit(session->uri, session->host->toolkit_rules.item[i], &toolkit_options)) == UT_ERROR) { return 500; } if ((toolkit_options.ban > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), toolkit_options.ban, session->config->kick_on_ban); log_system(session, "Client banned because of URL match in UrlToolkit rule"); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif return 403; } session->toolkit_fastcgi = toolkit_options.fastcgi_server; if (toolkit_options.new_url != NULL) { if (register_tempdata(&(session->tempdata), toolkit_options.new_url, tc_data) == -1) { free(toolkit_options.new_url); log_error(session, "error registering temporary data"); return 500; } session->uri = toolkit_options.new_url; } if (result == UT_REDIRECT) { if ((session->location = strdup(toolkit_options.new_url)) == NULL) { return -1; } session->cause_of_301 = location; return 301; } if (result == UT_DENY_ACCESS) { log_error(session, "access denied via URL toolkit rule"); return 403; } if (toolkit_options.expire > -1) { session->expires = toolkit_options.expire; session->caco_private = toolkit_options.caco_private; } } } #endif /* Find GET data */ if ((qmark = strchr(session->uri, '?')) != NULL) { *qmark = '\0'; session->vars = qmark + 1; } url_decode(session->uri); session->uri_len = strlen(session->uri); if ((session->vars != NULL) && (session->host->secure_url)) { if (forbidden_chars_present(session->vars)) { log_error(session, "URL contains forbidden characters"); return 403; } } if (validate_url(session) == false) { return -1; } if ((result = uri_to_path(session)) != 200) { return result; } /* Load configfile from directories */ if (session->host->ignore_dot_hiawatha == false) { if (load_user_config(session) == -1) { return 500; } } if ((result = copy_directory_settings(session)) != 200) { return result; } switch (access = allow_client(session)) { case deny: log_error(session, fb_accesslist); return 403; case allow: break; case pwd: case unspecified: if ((auth_result = http_authentication_result(session, access == unspecified)) != 200) { return auth_result; } } switch (is_directory(session->file_on_disk)) { case error: return 500; case yes: session->uri_is_dir = true; break; case no: if (((session->request_method != PUT) || session->host->webdav_app) && (session->host->enable_path_info)) { if ((result = get_path_info(session)) != 200) { return result; } } break; case no_access: log_error(session, fb_filesystem); return 403; case not_found: if (session->request_method == DELETE) { return 404; } } #ifdef ENABLE_TOOLKIT if ((session->toolkit_fastcgi == NULL) && session->uri_is_dir) { #else if (session->uri_is_dir) { #endif length = strlen(session->file_on_disk); if (*(session->file_on_disk + length - 1) == '/') { strcpy(session->file_on_disk + length, session->host->start_file); } else { return 301; } } if (get_target_extension(session) == -1) { log_error(session, "error getting extension"); return 500; } if (((session->request_method != PUT) && (session->request_method != DELETE)) || session->host->webdav_app) { check_target_is_cgi(session); } /* Handle request based on request method */ request_method = session->request_method; if (session->host->webdav_app) { if ((request_method == PUT) || (request_method == DELETE)) { request_method = POST; } } switch (request_method) { case GET: case HEAD: if (session->cgi_type != no_cgi) { session->body = NULL; result = execute_cgi(session); #ifdef ENABLE_XSLT } else if ((xslt_file = find_xslt_file(session)) != NULL) { result = handle_xml_file(session, xslt_file); free(xslt_file); #endif } else { result = send_file(session); } if (result == 404) { #ifdef ENABLE_XSLT if ((session->host->show_index != NULL) && (session->uri[session->uri_len - 1] == '/')) { result = show_index(session); } #endif #ifdef ENABLE_MONITOR } else if (session->config->monitor_enabled) { if ((result == 200) && (session->host->monitor_host)) { unlink(session->file_on_disk); } #endif } if ((session->request_method == GET) && (session->cgi_type == no_cgi) && (session->directory != NULL)) { if (session->directory->run_on_download != NULL) { run_program(session, session->directory->run_on_download, result); } } break; case POST: case unsupported: if (session->cgi_type != no_cgi) { result = execute_cgi(session); #ifdef ENABLE_XSLT } else if ((xslt_file = find_xslt_file(session)) != NULL) { result = handle_xml_file(session, xslt_file); free(xslt_file); #endif } else { result = 405; } break; case PUT: result = handle_put_request(session); if (((result == 201) || (result == 204)) && (session->host->run_on_alter != NULL)) { run_program(session, session->host->run_on_alter, result); } break; case DELETE: result = handle_delete_request(session); if ((result == 204) && (session->host->run_on_alter != NULL)) { run_program(session, session->host->run_on_alter, result); } break; case WHEN: send_code(session); break; default: result = 400; } return result; } /* Handle timeout upon sending request */ static void handle_timeout(t_session *session) { if ((session->config->ban_on_timeout > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_timeout, session->config->kick_on_ban); log_system(session, "Client banned because of connection timeout"); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } else { log_system(session, "Timeout while waiting for first request"); } } /* Request has been handled, handle the return code. */ static void handle_request_result(t_session *session, int result) { char *hostname; #ifdef ENABLE_DEBUG session->current_task = "handle request result"; #endif if (result == -1) switch (session->error_cause) { case ec_MAX_REQUESTSIZE: log_system(session, "Maximum request size reached"); session->return_code = 413; send_code(session); if ((session->config->ban_on_max_request_size > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_max_request_size, session->config->kick_on_ban); log_system(session, "Client banned because of sending a too large request"); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } break; case ec_TIMEOUT: if (session->kept_alive == 0) { session->return_code = 408; send_code(session); handle_timeout(session); } break; case ec_CLIENT_DISCONNECTED: if (session->kept_alive == 0) { log_system(session, "Silent client disconnected"); } break; case ec_SOCKET_READ_ERROR: if (errno != ECONNRESET) { log_system(session, "Error while reading request"); } break; case ec_SOCKET_WRITE_ERROR: log_request(session); break; case ec_FORCE_QUIT: log_system(session, "Client kicked"); break; case ec_SQL_INJECTION: if ((session->config->ban_on_sqli > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_sqli, session->config->kick_on_ban); hostname = (session->hostname != NULL) ? session->hostname : unknown_host; log_system(session, "Client banned because of SQL injection on %s", hostname); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } session->return_code = 441; send_code(session); log_request(session); break; case ec_XSS: session->return_code = 442; send_code(session); log_request(session); break; case ec_CSRF: session->return_code = 443; send_code(session); log_request(session); break; case ec_INVALID_URL: if ((session->config->ban_on_invalid_url > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_invalid_url, session->config->kick_on_ban); hostname = (session->hostname != NULL) ? session->hostname : unknown_host; log_system(session, "Client banned because of invalid URL on %s", hostname); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } send_code(session); break; default: if (session->data_sent == false) { session->return_code = 500; if (send_code(session) == -1) { session->keep_alive = false; } } } else switch (result) { case 200: break; case 201: case 204: case 304: case 412: if (session->data_sent == false) { session->return_code = result; if (send_header(session) == -1) { session->keep_alive = false; } else if (send_buffer(session, "Content-Length: 0\r\n\r\n", 21) == -1) { session->keep_alive = false; } } break; case 411: case 413: session->keep_alive = false; if (session->data_sent == false) { session->return_code = result; if (send_header(session) == -1) { session->keep_alive = false; } else if (send_buffer(session, "Content-Length: 0\r\n\r\n", 21) == -1) { session->keep_alive = false; } } break; case 400: log_garbage(session); if (session->data_sent == false) { session->return_code = 400; if (send_code(session) == -1) { session->keep_alive = false; } } if ((session->config->ban_on_garbage > 0) && (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny)) { ban_ip(&(session->ip_address), session->config->ban_on_garbage, session->config->kick_on_ban); log_system(session, "Client banned because of sending garbage"); #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_ban(session); } #endif } #ifdef ENABLE_MONITOR if (session->config->monitor_enabled) { monitor_count_bad_request(session); } #endif break; case 401: case 403: case 404: case 501: case 503: if (session->data_sent == false) { switch (handle_error(session, result)) { case -1: session->keep_alive = false; break; case 200: break; default: if (session->data_sent == false) { session->return_code = result; if (send_code(session) == -1) { session->keep_alive = false; } } } } break; case 500: session->keep_alive = false; default: if (session->data_sent == false) { session->return_code = result; send_code(session); } } if ((result > 0) && (result != 400)) { log_request(session); } else { session->keep_alive = false; } }
// perform FTP LIST command, sends a directory listing to the client void command_list(CLIENT_INFO * client_info) { char line[BUFFER_SIZE] = { 0 }; client_read_line(client_info->fd, client_info->buf, &client_info->buffer_pos); extract_line(line, client_info->buf, &client_info->buffer_pos); int len = strlen(line); char * path = NULL; if (len != 4) { char * p = line + 5; if (*p == '-') { while (*p && (*p != ' ')) p++; } while (*p && (*p == ' ')) p++; path = p; } char dirbuf[PATH_MAX + 1] = { 0 }; snprintf(dirbuf, PATH_MAX, "%s%s", basedir, client_info->dir); if (path) { if (path[0] == '/') { snprintf(dirbuf, PATH_MAX, "%s%s", basedir, path); } else { strcat(dirbuf, "/"); strcat(dirbuf, path); } } char realpathbuf[PATH_MAX + 1] = { 0 }; if (! realpath(dirbuf, realpathbuf)) { send_code(client_info->fd, 550); return; } strcpy(dirbuf, realpathbuf); if (dirbuf[strlen(dirbuf) - 1] != '/') strncat(dirbuf, "/", PATH_MAX); DIR * dirp = opendir(dirbuf); if (! dirp) { send_code(client_info->fd, 550); return; } send_code(client_info->fd, 150); open_data_connection(client_info); while (1) { struct dirent * entry = readdir(dirp); if (! entry) break; char filenamebuf[PATH_MAX + 1] = { 0 }; snprintf(filenamebuf, PATH_MAX, "%s%s", dirbuf, entry->d_name); struct stat s; if (stat(filenamebuf, &s) == -1) { // cannot stat continue; } char buf[PATH_MAX + 128 + 1] = { 0 }; strmode(s.st_mode, buf); unsigned int size = (unsigned int)s.st_size; char date[64]; struct tm * ts = localtime(&s.st_mtime); strftime(date, 64, "%b %e %Y", ts); sprintf(buf + 11, "%3d %-8d %-8d %8u %s %s\r\n", s.st_nlink, (int)s.st_uid, (int)s.st_gid, size, date, entry->d_name); data_connection_write_string(client_info, buf); } close_data_connection(client_info); send_code(client_info->fd, 226); }
static void send_tree ( z_stream& s, ct_data* tree, int max_code ) { int prevlen = -1; int curlen; int nextlen = tree[ 0 ].Len; int count = 0; int max_count = 7; int min_count = 4; if( !nextlen ) max_count = 138, min_count = 3; for( int n = 0 ; n <= max_code ; n++ ) { curlen = nextlen; nextlen = tree[ n + 1 ].Len; if( ++count < max_count && curlen == nextlen ) { continue; } else if( count < min_count ) { do { send_code( s, curlen, s.bl_tree ); } while( --count ); } else if( curlen ) { if( curlen != prevlen ) { send_code( s, curlen, s.bl_tree ); count--; } send_code( s, REP_3_6, s.bl_tree ); send_bits( s, count - 3, 2 ); } else if( count <= 10 ) { send_code( s, REPZ_3_10, s.bl_tree ); send_bits( s, count - 3, 3 ); } else { send_code( s, REPZ_11_138, s.bl_tree ); send_bits( s, count - 11, 7 ); } count = 0; prevlen = curlen; if( nextlen == 0 ) max_count = 138, min_count = 3; else if( curlen == nextlen ) max_count = 6, min_count = 3; else max_count = 7, min_count = 4; } }
int init_send(struct ir_remote *remote,struct ir_ncode *code) { int i, repeat=0; if(is_grundig(remote) || is_goldstar(remote) || is_serial(remote) || is_bo(remote)) { logprintf(LOG_ERR,"sorry, can't send this protocol yet"); return(0); } clear_send_buffer(); if(is_biphase(remote)) { send_buffer.is_biphase=1; } if(repeat_remote==NULL) { remote->repeat_countdown=remote->min_repeat; } else { repeat = 1; } init_send_loop: if(repeat && has_repeat(remote)) { if(remote->flags&REPEAT_HEADER && has_header(remote)) { send_header(remote); } send_repeat(remote); } else { if(!is_raw(remote)) { ir_code next_code; if(code->transmit_state == NULL) { next_code = code->code; } else { next_code = code->transmit_state->code; } send_code(remote, next_code, repeat); if(has_toggle_mask(remote)) { remote->toggle_mask_state++; if(remote->toggle_mask_state==4) { remote->toggle_mask_state=2; } } send_buffer.data=send_buffer._data; } else { if(code->signals==NULL) { logprintf(LOG_ERR, "no signals for raw send"); return 0; } if(send_buffer.wptr>0) { send_signals(code->signals, code->length); } else { send_buffer.data=code->signals; send_buffer.wptr=code->length; for(i=0; i<code->length; i++) { send_buffer.sum+=code->signals[i]; } } } } sync_send_buffer(); if(bad_send_buffer()) { logprintf(LOG_ERR,"buffer too small"); return(0); } if(has_repeat_gap(remote) && repeat && has_repeat(remote)) { remote->min_remaining_gap=remote->repeat_gap; remote->max_remaining_gap=remote->repeat_gap; } else if(is_const(remote)) { if(min_gap(remote)>send_buffer.sum) { remote->min_remaining_gap=min_gap(remote)-send_buffer.sum; remote->max_remaining_gap=max_gap(remote)-send_buffer.sum; } else { logprintf(LOG_ERR,"too short gap: %u",remote->gap); remote->min_remaining_gap=min_gap(remote); remote->max_remaining_gap=max_gap(remote); return(0); } } else { remote->min_remaining_gap=min_gap(remote); remote->max_remaining_gap=max_gap(remote); } /* update transmit state */ if(code->next != NULL) { if(code->transmit_state == NULL) { code->transmit_state = code->next; } else { code->transmit_state = code->transmit_state->next; } } if((remote->repeat_countdown>0 || code->transmit_state != NULL) && remote->min_remaining_gap<LIRCD_EXACT_GAP_THRESHOLD) { if(send_buffer.data!=send_buffer._data) { lirc_t *signals; int n; LOGPRINTF(1, "unrolling raw signal optimisation"); signals=send_buffer.data; n=send_buffer.wptr; send_buffer.data=send_buffer._data; send_buffer.wptr=0; send_signals(signals, n); } LOGPRINTF(1, "concatenating low gap signals"); if(code->next == NULL || code->transmit_state == NULL) { remote->repeat_countdown--; } send_space(remote->min_remaining_gap); flush_send_buffer(); send_buffer.sum=0; repeat = 1; goto init_send_loop; } LOGPRINTF(3, "transmit buffer ready"); return(1); }
Bytecodes::SendType InterpretedIC::send_type() const { return Bytecodes::send_type(send_code()); }
void InterpretedIC::clear_without_deallocation_pic() { if (is_empty()) return; set(Bytecodes::original_send_code_for(send_code()), oop(selector()), smiOop_zero); }
void InterpretedIC::cleanup() { if (is_empty()) return; // Nothing to cleanup switch (send_type()) { case Bytecodes::accessor_send: // fall through case Bytecodes::primitive_send: // fall through case Bytecodes::predicted_send: // fall through case Bytecodes::interpreted_send: { // check if the interpreted send should be replaced by a compiled send klassOop receiver_klass = klassOop(second_word()); assert(receiver_klass->is_klass(), "receiver klass must be a klass"); methodOop method = methodOop(first_word()); assert(method->is_method(), "first word in interpreter IC must be method"); if (!Bytecodes::is_super_send(send_code())) { // super sends cannot be handled since the sending method holder is unknown at this point. LookupKey key(receiver_klass, selector()); LookupResult result = lookupCache::lookup(&key); if (!result.matches(method)) { replace(result, receiver_klass); } } } break; case Bytecodes::compiled_send: { // check if the current compiled send is valid klassOop receiver_klass = klassOop(second_word()); assert(receiver_klass->is_klass(), "receiver klass must be a klass"); jumpTableEntry* entry = (jumpTableEntry*) first_word(); nmethod* nm = entry->method(); LookupResult result = lookupCache::lookup(&nm->key); if (!result.matches(nm)) { replace(result, receiver_klass); } } break; case Bytecodes::megamorphic_send: // Note that with the current definition of is_empty() // this will not be called for normal megamorphic sends // since they store only the selector. { klassOop receiver_klass = klassOop(second_word()); if (first_word()->is_smi()) { jumpTableEntry* entry = (jumpTableEntry*) first_word(); nmethod* nm = entry->method(); LookupResult result = lookupCache::lookup(&nm->key); if (!result.matches(nm)) { replace(result, receiver_klass); } } else { methodOop method = methodOop(first_word()); assert(method->is_method(), "first word in interpreter IC must be method"); if (!Bytecodes::is_super_send(send_code())) { // super sends cannot be handled since the sending method holder is unknown at this point. LookupKey key(receiver_klass, selector()); LookupResult result = lookupCache::lookup(&key); if (!result.matches(method)) { replace(result, receiver_klass); } } } } break; case Bytecodes::polymorphic_send: { // %implementation note: // when cleaning up we can always preserve the old pic since the // the only transitions are: // (compiled -> compiled) // (compiled -> interpreted) // (interpreted -> compiled) // in case of a super send we do not have to cleanup because // no nmethods are compiled for super sends. if (!Bytecodes::is_super_send(send_code())) { objArrayOop pic = pic_array(); for (int index = pic->length(); index > 0; index -= 2) { klassOop klass = klassOop(pic->obj_at(index)); assert(klass->is_klass(), "receiver klass must be klass"); oop first = pic->obj_at(index-1); if (first->is_smi()) { jumpTableEntry* entry = (jumpTableEntry*) first; nmethod* nm = entry->method(); LookupResult result = lookupCache::lookup(&nm->key); if (!result.matches(nm)) { pic->obj_at_put(index-1, result.value()); } } else { methodOop method = methodOop(first); assert(method->is_method(), "first word in interpreter IC must be method"); LookupKey key(klass, selector()); LookupResult result = lookupCache::lookup(&key); if (!result.matches(method)) { pic->obj_at_put(index-1, result.value()); } } } } } } }
Bytecodes::ArgumentSpec InterpretedIC::argument_spec() const { return Bytecodes::argument_spec(send_code()); }