예제 #1
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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);
}
예제 #2
0
/* 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;
	  }
   }
}
예제 #3
0
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);
}
예제 #4
0
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());
}
예제 #5
0
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");		
}
예제 #7
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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);
	}	
}
예제 #9
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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");
}
예제 #10
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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);
}
예제 #11
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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);
}
예제 #12
0
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;
}
예제 #13
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;
	}
}
예제 #14
0
파일: adoftp.c 프로젝트: backalor/adoftp
// 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);
}
예제 #15
0
파일: trees.cpp 프로젝트: lesteriv/libcrest
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;
    }
}
예제 #16
0
파일: transmit.c 프로젝트: philsmd/sharpfin
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);
}
예제 #17
0
Bytecodes::SendType InterpretedIC::send_type() const {
  return Bytecodes::send_type(send_code());
}
예제 #18
0
void InterpretedIC::clear_without_deallocation_pic() {
  if (is_empty()) return;
  set(Bytecodes::original_send_code_for(send_code()), oop(selector()), smiOop_zero);
}
예제 #19
0
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());
              }
            }
          }
        }
      }
  }
}
예제 #20
0
Bytecodes::ArgumentSpec InterpretedIC::argument_spec() const {
  return Bytecodes::argument_spec(send_code());
}