/** Write the string being parsed, and a marker showing where the parse error occurred * * @param[in] type the log category. * @param[in] lvl of debugging this message should be logged at. * @param[in] request The current request. * @param[in] msg string we were parsing. * @param[in] idx The position of the marker relative to the string. * @param[in] error What the parse error was. */ void log_request_marker(fr_log_type_t type, fr_log_lvl_t lvl, REQUEST *request, char const *msg, size_t idx, char const *error) { char const *prefix = ""; uint8_t unlang_indent; uint8_t module_indent; if (idx >= sizeof(spaces)) { size_t offset = (idx - (sizeof(spaces) - 1)) + (sizeof(spaces) * 0.75); idx -= offset; msg += offset; prefix = "... "; } /* * Don't want format markers being indented */ unlang_indent = request->log.unlang_indent; module_indent = request->log.module_indent; request->log.unlang_indent = 0; request->log.module_indent = 0; log_request(type, lvl, request, "%s%s", prefix, msg); log_request(type, lvl, request, "%s%.*s^ %s", prefix, (int) idx, spaces, error); request->log.unlang_indent = unlang_indent; request->log.module_indent = module_indent; }
/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */ static int acc_rad_missed1(struct sip_msg *rq, char* p1, char* p2) { int code; preparse_req(rq); if (get_int_fparam(&code, rq, (fparam_t*)p1) < 0) { code = 0; } return log_request(rq, GET_RURI(rq), rq->to, code, time(0)); }
static void log_ack(struct cell* t , struct sip_msg *ack, time_t req_time) { struct sip_msg *rq; struct hdr_field *to; rq = t->uas.request; if (ack->to) to = ack->to; else to = rq->to; log_request(ack, GET_RURI(ack), to, t->uas.status, req_time); }
/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */ static int acc_db_request1(struct sip_msg *rq, char* p1, char* p2) { int code; if (get_int_fparam(&code, rq, (fparam_t*)p1) < 0) { code = 0; } preparse_req(rq); return log_request(rq, GET_RURI(rq), rq->to, acc_table.s, code, time(0)); }
static void log_missed(struct cell* t, struct sip_msg* reply, unsigned int code, time_t req_time) { str* ouri; if (t->relayed_reply_branch >= 0) { ouri = &t->uac[t->relayed_reply_branch].uri; } else { ouri = GET_NEXT_HOP(t->uas.request); } log_request(t->uas.request, ouri, valid_to(t, reply), mc_table.s, code, req_time); }
int main(int argc, char const* argv[]) { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address, client_address; unlink("server_socket"); server_sockfd = socket(AF_INET, SOCK_STREAM, 0); if(server_sockfd < 0) { raise("Can't create socket!!!"); return -1; } server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(DEFAULT_PORT); server_len = sizeof(server_address); logger_info("Server Ready to Start"); if(bind(server_sockfd, (struct sockaddr *)&server_address, server_len) < 0) { close(server_sockfd); raise("Can't bind socket!!!"); return -1; } listen(server_sockfd, 5); logger_info("Server started"); while(1) { char request_content[BUFFER_SIZE]; char response_content[BUFFER_SIZE]; Request req; logger_info("Server waiting request..."); client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); read(client_sockfd, request_content, BUFFER_SIZE); char verb[64], path[64]; parse_request(request_content, verb, path); req.http_verb = verb; req.path = path; log_request(&req); dispatcher(&req, response_content); write(client_sockfd, response_content, strlen(response_content)); close(client_sockfd); logger_info("Process the request successfully\n"); } return 0; }
void log_request_hex(fr_log_type_t type, fr_log_lvl_t lvl, REQUEST *request, uint8_t const *data, size_t data_len) { size_t i, j, len; char *p; char buffer[(0x10 * 3) + 1]; for (i = 0; i < data_len; i += 0x10) { len = 0x10; if ((i + len) > data_len) len = data_len - i; for (p = buffer, j = 0; j < len; j++, p += 3) sprintf(p, "%02x ", data[i + j]); log_request(type, lvl, request, "%04x: %s", (int)i, buffer); } }
void do_request(int clientsd, struct sockaddr_in * client, char* logfile) { char* response; request_t req; int req_len; int written; req = parse_request(clientsd); response = get_response(&req, &req_len); req.content_length = req_len; send_headers(clientsd, &req); written = send_response(clientsd, response); free(response); req.sockaddr = client; if (req.response_code == 200) { sprintf(req.resp_string, "200 OK %d/%d", written, req.content_length); } log_request(&req, logfile); }
void close_connection(struct connection *cn) { if (cn->connection_state == HC_FREE) abort(); if (cn->nread || cn->nwritten || cn->logged == 0) { ++stats.nrequests; log_request(cn->r); } --stats.nconnections; if (debug) log_d("close_connection: %d", cn->fd); close(cn->fd); if (cn->rfd != -1) { close(cn->rfd); cn->rfd = -1; } set_connection_state(cn, HC_FREE); }
int reinit_connection(struct connection *cn) { char *s; ++stats.nrequests; log_request(cn->r); cn->logged = 1; if (cn->rfd != -1) { close(cn->rfd); cn->rfd = -1; } init_connection(cn); set_connection_state(cn, HC_WAITING); s = cn->header_input.middle; if (s == cn->header_input.end) { cn->header_input.start = cn->header_input.middle = cn->header_input.end = cn->header_input.floor; return 0; } ++stats.pipelined_requests; cn->header_input.start = s; return scan_request(cn); }
/* * Figure out what kind of data we've got and do something about it. */ void got_packet(struct tcp_stream *ts, void **data) { int todiscard=0; struct http_param *param=NULL; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; ts->client.collect = 1; param=calloc(sizeof(struct http_param), 1); assert(param); param->host=strdup(my_ntoa(ts->addr.saddr)); *data=param; break; case NIDS_DATA: if(ts->server.count_new!=0) { todiscard=process(ts, SERVER_STREAM, ts->server, data); } if(ts->client.count_new!=0) { todiscard=process(ts, CLIENT_STREAM, ts->client, data); } break; case NIDS_CLOSE: case NIDS_RESET: case NIDS_TIMED_OUT: param=*data; if(param) { /* Log automatically frees all the internal state */ log_request(param); free_param(param); free(param); } break; } nids_discard(ts, todiscard); }
void process_request(char* code_sign_key) { PLATFORM* platform; int retval; double last_rpc_time, x; struct tm *rpc_time_tm; bool ok_to_send_work = !config.dont_send_jobs; bool have_no_work = false; char buf[256]; HOST initial_host; unsigned int i; time_t t; memset(&g_reply->wreq, 0, sizeof(g_reply->wreq)); // if client has sticky files we don't need any more, tell it // do_file_delete_regex(); // if different major version of BOINC, just send a message // if (wrong_core_client_version() || unacceptable_os() || unacceptable_cpu() ) { ok_to_send_work = false; } // if no jobs reported and none to send, return without accessing DB // if (!ok_to_send_work && !g_request->results.size()) { return; } warn_user_if_core_client_upgrade_scheduled(); if (requesting_work()) { if (config.locality_scheduling || config.locality_scheduler_fraction || config.enable_assignment) { have_no_work = false; } else { lock_sema(); have_no_work = ssp->no_work(g_pid); if (have_no_work) { g_wreq->no_jobs_available = true; } unlock_sema(); } } // If: // - there's no work, // - a config flag is set, // - client isn't returning results, // - this isn't an initial RPC, // - client is requesting work // then return without accessing the DB. // This is an efficiency hack for when servers are overloaded // if ( have_no_work && config.nowork_skip && requesting_work() && (g_request->results.size() == 0) && (g_request->hostid != 0) ) { g_reply->insert_message("No work available", "low"); g_reply->set_delay(DELAY_NO_WORK_SKIP); if (!config.msg_to_host && !config.enable_vda) { log_messages.printf(MSG_NORMAL, "No work - skipping DB access\n"); return; } } // FROM HERE ON DON'T RETURN; "goto leave" instead // (because ssp->no_work() may have tagged an entry in the work array // with our process ID) retval = open_database(); if (retval) { send_error_message("Server can't open database", 3600); g_reply->project_is_down = true; goto leave; } retval = authenticate_user(); if (retval) goto leave; if (g_reply->user.id == 0) { log_messages.printf(MSG_CRITICAL, "No user ID!\n"); } initial_host = g_reply->host; g_reply->host.rpc_seqno = g_request->rpc_seqno; g_reply->nucleus_only = false; log_request(); // is host blacklisted? // if (g_reply->host._max_results_day == -1) { send_error_message("Not accepting requests from this host", 86400); goto leave; } if (strlen(config.sched_lockfile_dir)) { int pid_with_lock = lock_sched(); if (pid_with_lock > 0) { log_messages.printf(MSG_CRITICAL, "Another scheduler instance [PID=%d] is running for this host\n", pid_with_lock ); } else if (pid_with_lock) { log_messages.printf(MSG_CRITICAL, "Error acquiring lock for [HOST#%d]\n", g_reply->host.id ); } if (pid_with_lock) { send_error_message( "Another scheduler instance is running for this host", 60 ); goto leave; } } // in deciding whether it's a new day, // add a random factor (based on host ID) // to smooth out network traffic over the day // retval = rand(); srand(g_reply->host.id); x = drand()*86400; srand(retval); last_rpc_time = g_reply->host.rpc_time; t = (time_t)(g_reply->host.rpc_time + x); rpc_time_tm = localtime(&t); g_request->last_rpc_dayofyear = rpc_time_tm->tm_yday; t = time(0); g_reply->host.rpc_time = t; t += (time_t)x; rpc_time_tm = localtime(&t); g_request->current_rpc_dayofyear = rpc_time_tm->tm_yday; retval = modify_host_struct(g_reply->host); // write time stats to disk if present // if (g_request->have_time_stats_log) { write_time_stats_log(); } // look up the client's platform(s) in the DB // platform = ssp->lookup_platform(g_request->platform.name); if (platform) g_request->platforms.list.push_back(platform); // if primary platform is anonymous, ignore alternate platforms // if (strcmp(g_request->platform.name, "anonymous")) { for (i=0; i<g_request->alt_platforms.size(); i++) { platform = ssp->lookup_platform(g_request->alt_platforms[i].name); if (platform) g_request->platforms.list.push_back(platform); } } if (g_request->platforms.list.size() == 0) { sprintf(buf, "%s %s", _("This project doesn't support computers of type"), g_request->platform.name ); g_reply->insert_message(buf, "notice"); log_messages.printf(MSG_CRITICAL, "[HOST#%d] platform '%s' not found\n", g_reply->host.id, g_request->platform.name ); g_reply->set_delay(DELAY_PLATFORM_UNSUPPORTED); goto leave; } handle_global_prefs(); read_host_app_versions(); update_n_jobs_today(); handle_results(); handle_file_xfer_results(); if (config.enable_vda) { handle_vda(); } // Do this before resending lost jobs // if (bad_install_type()) { ok_to_send_work = false; } if (!requesting_work()) { ok_to_send_work = false; } send_work_setup(); if (g_request->have_other_results_list) { if (ok_to_send_work && (config.resend_lost_results || g_wreq->resend_lost_results) && !g_request->results_truncated ) { if (resend_lost_work()) { ok_to_send_work = false; } } if (config.send_result_abort) { send_result_abort(); } } if (requesting_work()) { if (!send_code_sign_key(code_sign_key)) { ok_to_send_work = false; } if (have_no_work) { if (config.debug_send) { log_messages.printf(MSG_NORMAL, "[send] No jobs in shmem cache\n" ); } } // if last RPC was within config.min_sendwork_interval, don't send work // if (!have_no_work && ok_to_send_work) { if (config.min_sendwork_interval) { double diff = dtime() - last_rpc_time; if (diff < config.min_sendwork_interval) { ok_to_send_work = false; log_messages.printf(MSG_NORMAL, "Not sending work - last request too recent: %f\n", diff ); sprintf(buf, "Not sending work - last request too recent: %d sec", (int)diff ); g_reply->insert_message(buf, "low"); // the 1.01 is in case client's clock // is slightly faster than ours // g_reply->set_delay(1.01*config.min_sendwork_interval); } } if (ok_to_send_work) { send_work(); } } if (g_wreq->no_jobs_available) { g_reply->insert_message("Project has no tasks available", "low"); } } handle_msgs_from_host(); if (config.msg_to_host) { handle_msgs_to_host(); } update_host_record(initial_host, g_reply->host, g_reply->user); write_host_app_versions(); leave: if (!have_no_work) { ssp->restore_work(g_pid); } }
static int answer_to_connection (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { struct agent_core_t *core = (struct agent_core_t *)cls; struct http_priv_t *http; struct agent_plugin_t *plug; struct http_request request; struct connection_info_struct *con_info = NULL; int ret; (void)version; plug = plugin_find(core,"http"); http = (struct http_priv_t *) plug->data; assert(plug); assert(http); if (NULL == *con_cls) { con_info = malloc (sizeof (struct connection_info_struct)); assert(con_info); con_info->answerstring[0] = '\0'; con_info->progress = 0; con_info->authed = 0; *con_cls = con_info; return MHD_YES; } con_info = *con_cls; assert(core->config->userpass); log_request(connection, http, method, url); if (0 == strcmp (method, "GET") || !strcmp(method, "HEAD") || !strcmp(method,"DELETE")) { ret = check_auth(connection, core, con_info); if (ret == 1) return MHD_YES; if (!strcmp(method,"DELETE")) { request.method = M_DELETE; } else { request.method = M_GET; } request.connection = connection; request.url = url; request.ndata = 0; if (find_listener(&request, http)) return MHD_YES; } if (!strcmp(method, "POST") || !strcmp(method, "PUT")) { if (*upload_data_size != 0) { if (*upload_data_size + con_info->progress >= RCV_BUFFER) { warnlog(http->logger, "Client input exceeded buffer size of %u bytes. Dropping client.", RCV_BUFFER); return MHD_NO; } memcpy(con_info->answerstring + con_info->progress, upload_data, *upload_data_size); con_info->progress += *upload_data_size; *upload_data_size = 0; return MHD_YES; } else if (NULL != con_info->answerstring){ ret = check_auth(connection, core, con_info); if (ret == 1) return MHD_YES; if (!strcmp(method,"POST")) { request.method = M_POST; } else { request.method = M_PUT; } request.connection = connection; request.url = url; request.ndata = con_info->progress; request.data = con_info->answerstring; /* * FIXME */ ((char *)request.data)[con_info->progress] = '\0'; if (find_listener(&request, http)) return MHD_YES; } } if (request.method == M_GET && !strcmp(url, "/")) { if (http->help_page == NULL) http->help_page = make_help(http); assert (http->help_page); return send_response_ok(connection, http->help_page); } return send_response_fail (connection, "Failed\n"); }
void process_request(char* code_sign_key) { PLATFORM* platform; int retval; double last_rpc_time, x; struct tm *rpc_time_tm; bool ok_to_send_work = !config.dont_send_jobs; bool have_no_work = false; char buf[256]; HOST initial_host; unsigned int i; time_t t; memset(&g_reply->wreq, 0, sizeof(g_reply->wreq)); // if client has sticky files we don't need any more, tell it // do_file_delete_regex(); // if different major version of BOINC, just send a message // if (wrong_core_client_version() || unacceptable_os() || unacceptable_cpu() ) { ok_to_send_work = false; } // if no jobs reported and none to send, return without accessing DB // if (!ok_to_send_work && !g_request->results.size()) { return; } warn_user_if_core_client_upgrade_scheduled(); if (requesting_work()) { if (config.locality_scheduling || config.locality_scheduler_fraction || config.enable_assignment) { have_no_work = false; } else { lock_sema(); have_no_work = ssp->no_work(g_pid); if (have_no_work) { g_wreq->no_jobs_available = true; } unlock_sema(); } } // If: // - there's no work, // - a config flag is set, // - client isn't returning results, // - this isn't an initial RPC, // - client is requesting work // then return without accessing the DB. // This is an efficiency hack for when servers are overloaded // if ( have_no_work && config.nowork_skip && requesting_work() && (g_request->results.size() == 0) && (g_request->hostid != 0) ) { g_reply->insert_message("No work available", "low"); g_reply->set_delay(DELAY_NO_WORK_SKIP); if (!config.msg_to_host && !config.enable_vda) { log_messages.printf(MSG_NORMAL, "No work - skipping DB access\n"); return; } } // FROM HERE ON DON'T RETURN; "goto leave" instead // (because ssp->no_work() may have tagged an entry in the work array // with our process ID) retval = open_database(); if (retval) { send_error_message("Server can't open database", 3600); g_reply->project_is_down = true; goto leave; } retval = authenticate_user(); if (retval) goto leave; if (g_reply->user.id == 0) { log_messages.printf(MSG_CRITICAL, "No user ID!\n"); } initial_host = g_reply->host; g_reply->host.rpc_seqno = g_request->rpc_seqno; g_reply->nucleus_only = false; log_request(); #if 0 // if you need to debug a problem w/ a particular host or user, // edit the following // if (g_reply->user.id == XX || g_reply.host.id == YY) { config.sched_debug_level = 3; config.debug_send = true; ... }
static void uwsgi_ssi_log(struct wsgi_request *wsgi_req) { log_request(wsgi_req); }
int tdi_connect(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion) { PTDI_REQUEST_KERNEL_CONNECT param = (PTDI_REQUEST_KERNEL_CONNECT)(&irps->Parameters); TA_ADDRESS *remote_addr = ((TRANSPORT_ADDRESS *)(param->RequestConnectionInformation->RemoteAddress))->Address; PFILE_OBJECT addrobj; NTSTATUS status; TA_ADDRESS *local_addr; int result = FILTER_DENY, ipproto; struct ot_entry *ote_conn = NULL, *ote_addr; KIRQL irql; struct flt_request request; struct flt_rule rule; memset(&request, 0, sizeof(request)); KdPrint(("[tdi_fw] tdi_connect: connobj 0x%x, to address %x:%u\n", irps->FileObject, ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port))); // check device object: TCP or UDP if (irps->DeviceObject != g_tcpfltobj && irps->DeviceObject != g_udpfltobj) { KdPrint(("[tdi_fw] tdi_connect: unknown DeviceObject 0x%x!\n", irps->DeviceObject)); goto done; } ote_conn = ot_find_fileobj(irps->FileObject, &irql); if (ote_conn == NULL) { KdPrint(("[tdi_fw] tdi_connect: ot_find_fileobj(0x%x)!\n", irps->FileObject)); goto done; } if (get_original_devobj(irps->DeviceObject, &ipproto) == NULL || (ipproto != IPPROTO_TCP && ipproto != IPPROTO_UDP)) { // invalid device object! KdPrint(("[tdi_fw] tdi_connect: invalid device object 0x%x!\n", irps->DeviceObject)); goto done; } if (ipproto == IPPROTO_TCP) { /* * For TCP: get addrobj by connobj and get local address by it */ addrobj = ote_conn->associated_fileobj; if (addrobj == NULL) { KdPrint(("[tdi_fw] tdi_connect: empty addrobj!\n")); goto done; } ote_addr = ot_find_fileobj(addrobj, NULL); // we're already in spinlock if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_connect: ot_find_fileobj(0x%x)!\n", addrobj)); goto done; } } else { /* * For UDP: connobj and addrobj are the same */ KdPrint(("[tdi_fw] tdi_connect: connected UDP socket detected\n")); // for connected UDP sockets connobj and addrobj are the same addrobj= irps->FileObject; ote_addr = ote_conn; } local_addr = (TA_ADDRESS *)(ote_addr->local_addr); // sanity check if (local_addr->AddressLength != remote_addr->AddressLength) { KdPrint(("[tdi_fw] tdi_connect: different addr lengths! (%u != %u)\n", local_addr->AddressLength, remote_addr->AddressLength)); goto done; } // set remote address with connobj if (remote_addr->AddressLength > sizeof(ote_conn->remote_addr)) { KdPrint(("[tdi_fw] tdi_connect: address too long! (%u)\n", remote_addr->AddressLength)); goto done; } memcpy(ote_conn->remote_addr, remote_addr, remote_addr->AddressLength); // set local address with connobj if (local_addr->AddressLength > sizeof(ote_conn->local_addr)) { KdPrint(("[tdi_fw] tdi_connect: address to long! (%u)\n", local_addr->AddressLength)); goto done; } memcpy(ote_conn->local_addr, local_addr, local_addr->AddressLength); KdPrint(("[tdi_fw] tdi_connect(pid:%u/%u): %x:%u -> %x:%u (ipproto = %d)\n", ote_conn->pid, PsGetCurrentProcessId(), ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(local_addr->Address))->sin_port), ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port), ipproto)); /* * Call quick_filter */ request.struct_size = sizeof(request); request.type = TYPE_CONNECT; request.direction = DIRECTION_OUT; request.proto = ipproto; // don't use ote_conn->pid because one process can create connection object // but another one can connect request.pid = (ULONG)PsGetCurrentProcessId(); if (request.pid == 0) { // avoid idle process pid (XXX do we need this?) request.pid = ote_addr->pid; } // get user SID & attributes (can't call get_current_sid_a at DISPATCH_LEVEL) if ((request.sid_a = copy_sid_a(ote_addr->sid_a, ote_addr->sid_a_size)) != NULL) request.sid_a_size = ote_addr->sid_a_size; memcpy(&request.addr.from, &local_addr->AddressType, sizeof(struct sockaddr)); memcpy(&request.addr.to, &remote_addr->AddressType, sizeof(struct sockaddr)); request.addr.len = sizeof(struct sockaddr_in); memset(&rule, 0, sizeof(rule)); result = quick_filter(&request, &rule); memcpy(request.log_rule_id, rule.rule_id, RULE_ID_SIZE); if (result == FILTER_ALLOW && ipproto == IPPROTO_TCP) { struct flt_request *context_req = NULL; // add connection with state "SYN_SENT" status = add_tcp_conn(ote_conn, TCP_STATE_SYN_SENT); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_connect: add_conn: 0x%x!\n", status)); result = FILTER_DENY; goto done; // don't log this failure } if (rule.log >= RULE_LOG_LOG) { // set ote_conn->log_disconnect ote_conn->log_disconnect = (rule.log >= RULE_LOG_COUNT); // copy request for completion (LOG success or not) context_req = (struct flt_request *)malloc_np(sizeof(*context_req)); if (context_req != NULL) { memcpy(context_req, &request, sizeof(*context_req)); // don't free SID request.sid_a = NULL; // don't log request in this time rule.log = RULE_LOG_NOLOG; } } // set completion to add connection info to connection table completion->routine = tdi_connect_complete; completion->context = context_req; } // if logging is needed log request if (rule.log >= RULE_LOG_LOG) log_request(&request); done: // cleanup if (ote_conn != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); if (request.sid_a != NULL) free(request.sid_a); if (result != FILTER_ALLOW) { irp->IoStatus.Status = STATUS_REMOTE_NOT_LISTENING; // set fake status } return result; }
NTSTATUS tdi_event_receive_datagram( IN PVOID TdiEventContext, IN LONG SourceAddressLength, IN PVOID SourceAddress, IN LONG OptionsLength, IN PVOID Options, IN ULONG ReceiveDatagramFlags, IN ULONG BytesIndicated, IN ULONG BytesAvailable, OUT ULONG *BytesTaken, IN PVOID Tsdu, OUT PIRP *IoRequestPacket) { TDI_EVENT_CONTEXT *ctx = (TDI_EVENT_CONTEXT *)TdiEventContext; struct ot_entry *ote_addr = NULL; KIRQL irql; TA_ADDRESS *remote_addr, *local_addr; NTSTATUS status; int ipproto, result = FILTER_DENY; struct flt_request request; struct flt_rule rule; // get local address of address object memset(&request, 0, sizeof(request)); ote_addr = ot_find_fileobj(ctx->fileobj, &irql); if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_receive_datagram: ot_find_fileobj(0x%x)!\n", ctx->fileobj)); goto done; } KdPrint(("[tdi_fw] tdi_event_receive_datagram: addrobj 0x%x\n", ctx->fileobj)); // check device object: UDP or RawIP if (get_original_devobj(ote_addr->devobj, &ipproto) == NULL || (ipproto != IPPROTO_UDP && ipproto != IPPROTO_IP)) { // unknown device object! KdPrint(("[tdi_fw] tdi_event_receive_datagram: unknown DeviceObject 0x%x!\n", ote_addr)); goto done; } local_addr = (TA_ADDRESS *)(ote_addr->local_addr); remote_addr = ((TRANSPORT_ADDRESS *)SourceAddress)->Address; KdPrint(("[tdi_fw] tdi_event_receive_datagram(pid:%u): %x:%u -> %x:%u\n", ote_addr->pid, ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port), ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(local_addr->Address))->sin_port))); // call quick filter for datagram request.struct_size = sizeof(request); request.type = TYPE_DATAGRAM; request.direction = DIRECTION_IN; request.proto = ipproto; request.pid = ote_addr->pid; // get user SID & attributes (can't call get_current_sid_a at DISPATCH_LEVEL) if ((request.sid_a = copy_sid_a(ote_addr->sid_a, ote_addr->sid_a_size)) != NULL) request.sid_a_size = ote_addr->sid_a_size; memcpy(&request.addr.from, &remote_addr->AddressType, sizeof(struct sockaddr)); memcpy(&request.addr.to, &local_addr->AddressType, sizeof(struct sockaddr)); request.addr.len = sizeof(struct sockaddr_in); memset(&rule, 0, sizeof(rule)); result = quick_filter(&request, &rule); memcpy(request.log_rule_id, rule.rule_id, RULE_ID_SIZE); if (rule.log >= RULE_LOG_LOG) { ULONG bytes = BytesAvailable; // traffic stats KeAcquireSpinLockAtDpcLevel(&g_traffic_guard); g_traffic[TRAFFIC_TOTAL_IN] += bytes; if (rule.log >= RULE_LOG_COUNT) { request.log_bytes_in = bytes; g_traffic[TRAFFIC_COUNTED_IN] += bytes; } else request.log_bytes_in = (ULONG)-1; KeReleaseSpinLockFromDpcLevel(&g_traffic_guard); log_request(&request); } done: // cleanup if (ote_addr != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); if (request.sid_a != NULL) free(request.sid_a); if (result == FILTER_ALLOW) { return ((PTDI_IND_RECEIVE_DATAGRAM)(ctx->old_handler)) (ctx->old_context, SourceAddressLength, SourceAddress, OptionsLength, Options, ReceiveDatagramFlags, BytesIndicated, BytesAvailable, BytesTaken, Tsdu, IoRequestPacket); } else return STATUS_DATA_NOT_ACCEPTED; }
/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */ static int acc_rad_missed0(struct sip_msg *rq, char* p1, char* p2) { preparse_req(rq); return log_request(rq, GET_RURI(rq), rq->to, 0, time(0)); }
/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */ static int acc_db_request0(struct sip_msg *rq, char* s1, char* s2) { preparse_req(rq); return log_request(rq, GET_RURI(rq), rq->to, write_acc, 0, time(0)); }
int tdi_set_event_handler(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion) { PTDI_REQUEST_KERNEL_SET_EVENT r = (PTDI_REQUEST_KERNEL_SET_EVENT)&irps->Parameters; NTSTATUS status; struct ot_entry *ote_addr = NULL; KIRQL irql; int result = FILTER_DENY; TDI_EVENT_CONTEXT *ctx; KdPrint(("[tdi_fw] tdi_set_event_handler: [%s] devobj 0x%x; addrobj 0x%x; EventType: %d\n", r->EventHandler ? "(+)ADD" : "(-)REMOVE", irps->DeviceObject, irps->FileObject, r->EventType)); ote_addr = ot_find_fileobj(irps->FileObject, &irql); if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_set_event_handler: ot_find_fileobj(0x%x)\n", irps->FileObject)); if (r->EventHandler == NULL) { // for fileobjects loaded earlier than our driver allow removing result = FILTER_ALLOW; } goto done; } if (r->EventType < 0 || r->EventType >= MAX_EVENT) { KdPrint(("[tdi_fw] tdi_set_event_handler: unknown EventType %d!\n", r->EventType)); result = FILTER_ALLOW; goto done; } ctx = &ote_addr->ctx[r->EventType]; if (r->EventHandler != NULL) { /* add EventHandler */ int i; for (i = 0; g_tdi_event_handlers[i].event != (ULONG)-1; i++) if (g_tdi_event_handlers[i].event == r->EventType) break; if (g_tdi_event_handlers[i].event == (ULONG)-1) { KdPrint(("[tdi_fw] tdi_set_event_handler: unknown EventType %d!\n", r->EventType)); result = FILTER_ALLOW; goto done; } ctx->old_handler = r->EventHandler; ctx->old_context = r->EventContext; if (g_tdi_event_handlers[i].handler != NULL) { r->EventHandler = g_tdi_event_handlers[i].handler; r->EventContext = ctx; } else { r->EventHandler = NULL; r->EventContext = NULL; } KdPrint(("[tdi_fw] tdi_set_event_handler: old_handler 0x%x; old_context 0x%x\n", r->EventHandler, r->EventContext)); } else { /* remove EventHandler */ ctx->old_handler = NULL; ctx->old_context = NULL; } // change LISTEN state if (r->EventType == TDI_EVENT_CONNECT) { TA_ADDRESS *local_addr; if (r->EventHandler != NULL) { // add "LISTEN" info status = add_listen(ote_addr); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_set_event_handler: add_listen: 0x%x!\n", status)); goto done; } } else if (ote_addr->listen_entry != NULL) { // remove "LISTEN" info del_listen_obj(ote_addr->listen_entry, FALSE); ote_addr->listen_entry = NULL; } // log it if address is not 127.0.0.1 local_addr = (TA_ADDRESS *)(ote_addr->local_addr); if (ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr) != 0x7f000001) { struct flt_request request; memset(&request, 0, sizeof(request)); request.struct_size = sizeof(request); request.type = (r->EventHandler != NULL) ? TYPE_LISTEN : TYPE_NOT_LISTEN; request.proto = IPPROTO_TCP; // correct? if (r->EventHandler != NULL) { // for removing event handler ProcessNotifyProc can be already called request.pid = (ULONG)PsGetCurrentProcessId(); if (request.pid == 0) { // avoid idle process pid (XXX do we need this?) request.pid = ote_addr->pid; } } else request.pid = (ULONG)-1; // get user SID & attributes (can't call get_current_sid_a at DISPATCH_LEVEL) if ((request.sid_a = copy_sid_a(ote_addr->sid_a, ote_addr->sid_a_size)) != NULL) request.sid_a_size = ote_addr->sid_a_size; memcpy(&request.addr.from, &local_addr->AddressType, sizeof(struct sockaddr)); request.addr.len = sizeof(struct sockaddr_in); log_request(&request); if (request.sid_a != NULL) free(request.sid_a); } } result = FILTER_ALLOW; done: // cleanup if (ote_addr != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); return result; }
NTSTATUS tdi_connect_complete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { NTSTATUS status; struct flt_request *request = (struct flt_request *)Context; PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(Irp); KdPrint(("[tdi_fw] tdi_connect_complete: status 0x%x\n", Irp->IoStatus.Status)); if (Irp->IoStatus.Status == STATUS_SUCCESS) { if (request != NULL) log_request(request); // log successful connection // very good! set connection state to "ESTABLISHED" status = set_tcp_conn_state(irps->FileObject, TCP_STATE_ESTABLISHED_OUT); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_connect_complete: set_tcp_conn_state: 0x%x!\n", status)); // set fake status Irp->IoStatus.Status = STATUS_REMOTE_NOT_LISTENING; // TDI client will close connection object and connection will not "hang" (maybe) goto done; } // and update local address for this connection in state table update_conn_info(DeviceObject, irps->FileObject); } else { if (request != NULL) { switch (Irp->IoStatus.Status) { // are status codes correct? case STATUS_CONNECTION_REFUSED: case STATUS_CONNECTION_RESET: request->type = TYPE_CONNECT_RESET; break; case STATUS_CONNECTION_ABORTED: case STATUS_CANCELLED: request->type = TYPE_CONNECT_CANCELED; break; case STATUS_IO_TIMEOUT: request->type = TYPE_CONNECT_TIMEOUT; break; case STATUS_NETWORK_UNREACHABLE: case STATUS_HOST_UNREACHABLE: case STATUS_PROTOCOL_UNREACHABLE: case STATUS_PORT_UNREACHABLE: request->type = TYPE_CONNECT_UNREACH; break; default: request->type = TYPE_CONNECT_ERROR; } // anyway save status request->status = Irp->IoStatus.Status; log_request(request); } del_tcp_conn(irps->FileObject, FALSE); } done: if (request != NULL) { if (request->sid_a != NULL) free(request->sid_a); free(request); } return tdi_generic_complete(DeviceObject, Irp, Context); }
static void uwsgi_webdav_after_request(struct wsgi_request *wsgi_req) { if (!udav.mountpoints) return; log_request(wsgi_req); }
/* 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; } }
int tdi_create(PIRP irp, PIO_STACK_LOCATION irps, struct completion *completion) { NTSTATUS status; FILE_FULL_EA_INFORMATION *ea = (FILE_FULL_EA_INFORMATION *)irp->AssociatedIrp.SystemBuffer; /* pid resolving stuff: a good place for it (PASSIVE level, begin of working with TDI-objects) */ ULONG pid = (ULONG)PsGetCurrentProcessId(); // if process name is unknown try to resolve it if (!pid_pname_resolve(pid, NULL, 0)) { KEVENT event; struct flt_request request; KeInitializeEvent(&event, NotificationEvent, FALSE); pid_pname_set_event(pid, &event); memset(&request, 0, sizeof(request)); request.struct_size = sizeof(request); request.type = TYPE_RESOLVE_PID; request.pid = pid; // get user SID & attributes! request.sid_a = get_current_sid_a(&request.sid_a_size); if (log_request(&request)) { // wait a little for reply from user-mode application LARGE_INTEGER li; li.QuadPart = 5000 * -10000; // 5 sec status = KeWaitForSingleObject(&event, UserRequest, KernelMode, FALSE, &li); } else { // check all rulesets: we've got the only _default_ ruleset active status = default_chain_only() ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } if (request.sid_a != NULL) free(request.sid_a); // reset wait event pid_pname_set_event(pid, NULL); if (status != STATUS_SUCCESS) return FILTER_DENY; // deny it! } /* TDI_CREATE related stuff */ if (ea != NULL) { /* * We have FILE_FULL_EA_INFORMATION */ PDEVICE_OBJECT devobj; int ipproto; devobj = get_original_devobj(irps->DeviceObject, &ipproto); if (devobj == NULL) { KdPrint(("[tdi_fw] tdi_create: unknown device object 0x%x!\n", irps->DeviceObject)); return FILTER_DENY; } // NOTE: for RawIp you can extract protocol number from irps->FileObject->FileName if (ea->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH && memcmp(ea->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) == 0) { PIRP query_irp; /* * This is creation of address object */ KdPrint(("[tdi_fw] tdi_create: devobj 0x%x; addrobj 0x%x\n", irps->DeviceObject, irps->FileObject)); status = ot_add_fileobj(irps->DeviceObject, irps->FileObject, FILEOBJ_ADDROBJ, ipproto, NULL); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_create: ot_add_fileobj: 0x%x\n", status)); return FILTER_DENY; } // while we're on PASSIVE_LEVEL build control IRP for completion query_irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION, devobj, irps->FileObject, NULL, NULL); if (query_irp == NULL) { KdPrint(("[tdi_fw] tdi_create: TdiBuildInternalDeviceControlIrp\n")); return FILTER_DENY; } /* set IRP completion & context for completion */ completion->routine = tdi_create_addrobj_complete; completion->context = query_irp; } else if (ea->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH && memcmp(ea->EaName, TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH) == 0) { /* * This is creation of connection object */ CONNECTION_CONTEXT conn_ctx = *(CONNECTION_CONTEXT *) (ea->EaName + ea->EaNameLength + 1); KdPrint(("[tdi_fw] tdi_create: devobj 0x%x; connobj 0x%x; conn_ctx 0x%x\n", irps->DeviceObject, irps->FileObject, conn_ctx)); status = ot_add_fileobj(irps->DeviceObject, irps->FileObject, FILEOBJ_CONNOBJ, ipproto, conn_ctx); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_create: ot_add_fileobj: 0x%x\n", status)); return FILTER_DENY; } } } else { /* * This is creation of control object */ KdPrint(("[tdi_fw] tdi_create(pid:%u): devobj 0x%x; Control Object: 0x%x\n", pid, irps->DeviceObject, irps->FileObject)); } return FILTER_ALLOW; }
static void uwsgi_jvm_after_request(struct wsgi_request *wsgi_req) { log_request(wsgi_req); }
/* * Process the response data. */ int processResponse(char *data, int length, struct http_param *param) { int processed=0; char *p=NULL; processed=length; /* Find out how far it is to the end of the headers */ if(param->response.header_len==0) { /* Just go ahead and keep adding here */ param->response.length+=length; p=strstr(data, "\r\n\r\n"); if(p==NULL) { /* We don't have the end of the headers, ask for more data */ processed=0; } else { /* Figure out how far in the headers stop */ param->response.header_len=(p-data)+4; param->response.length-=param->response.header_len; /* Actually process the headers, see what we're dealing with. */ p=strtok(data, "\r\n"); param->response.status_str=strdup(p); /* Find the status */ p=strchr(p, ' '); if(p!=NULL) { param->response.status=atoi(p); } /* Look through the headers and see what kind of stuff we've got */ while( (p=strtok(NULL, "\r\n"))!=NULL) { if(strncasecmp(p, "Connection: ", 16) == 0) { if(strncasecmp(p+16, "close", 5)) { param->response.connection=CONNECTION_CLOSE; } else if(strncasecmp(p+16, "keepalive", 9)) { param->response.connection=CONNECTION_KEEPALIVE; } } else if(strncasecmp(p, "Transfer-Encoding: ", 19) == 0) { if(strncasecmp(p+19, "chunked", 7) == 0) { param->response.trans_enc=ENCODING_CHUNKED; } } else if(strncasecmp(p, "Content-Length: ", 16) == 0) { param->response.body_len=atoi(p+16); } } } /* If we're doing chunked encoding, let's get set up for that */ if(param->response.trans_enc==ENCODING_CHUNKED) { char *start=data+param->response.header_len; char *end=data+param->response.header_len; int old_remaining=0; /* Find the last hex digit */ while(*end && isxdigit(*end)) { end++; } /* Figure out what the value of that hex string is */ param->response.remaining=strtoul(start, &end, 16); fprintf(stderr, "*** Chunk size is %d\n", param->response.remaining); /* Skip to the newline */ while(*end!='\r' && *end!='\n') { end++; } /* and then past it */ while(*end=='\r' || *end=='\n') { end++; } /* Adjust the length */ param->response.length-=(end-start); /* Adjust the remaining length */ old_remaining=param->response.remaining; /* The length minus the length of the length */ param->response.remaining-=(length-(end-data)); assert(param->response.remaining>=0); assert(param->response.remaining < old_remaining); fprintf(stderr, "*** Remaining size is %d, current length is %d\n", param->response.remaining, param->response.length); } } else { /* This is not the first packet */ /* Special processing for chunked encoding */ if(param->response.trans_enc==ENCODING_CHUNKED) { /* Find out how much of the current chunk we've got */ if(length>param->response.remaining) { /* We've got the entire chunk here */ char *start=NULL, *end=NULL; param->response.length+=param->response.remaining; start=data+param->response.remaining; end=start; while(*end && isxdigit(*end)) { end++; } param->response.remaining=strtoul(start, &end, 16); /* Skip past the newline */ while(*end!='\r' && *end!='\n') { end++; } while(*end=='\r' || *end=='\n') { end++; } fprintf(stderr, "*** New remaining is %d\n", param->response.remaining); if(param->response.remaining>0) { param->response.length-=(end-start); param->response.remaining-=(length-(end-data)); assert(param->response.remaining>=0); } else { /* Log here, we're done for a while */ log_request(param); /* OK, let's drop off some of the ``processed'' data. */ processed=(end-data); /* If this was a keepalive connection, see if we have * another request in there. */ if(param->response.connection!=CONNECTION_CLOSE) { next_request(param); } } } else { /* This is part of our current chunk */ param->response.remaining-=length; param->response.length+=length; fprintf(stderr, "%d bytes of the same chunk.\n", length); } } else { param->response.length+=length; } } return(processed); }
static int answer_to_connection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t * upload_data_size, void **con_cls) { struct agent_core_t *core = (struct agent_core_t *)cls; struct http_priv_t *http; struct http_request request; struct connection_info_struct *con_info; (void)version; GET_PRIV(core, http); if (*con_cls == NULL) { ALLOC_OBJ(con_info); *con_cls = con_info; return (MHD_YES); } con_info = *con_cls; assert(core->config->userpass); log_request(connection, http, method, url); if (!strcmp(method, "OPTIONS")) { /* We need this for preflight requests (CORS). */ return (http_reply(connection, 200, NULL)); } else if (!strcmp(method, "GET") || !strcmp(method, "HEAD") || !strcmp(method, "DELETE")) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "DELETE")) request.method = M_DELETE; else request.method = M_GET; request.connection = connection; request.url = url; request.ndata = 0; if (find_listener(&request, http)) return (MHD_YES); } else if (!strcmp(method, "POST") || !strcmp(method, "PUT")) { if (*upload_data_size != 0) { if (*upload_data_size + con_info->progress >= RCV_BUFFER) { warnlog(http->logger, "Client input exceeded buffer size " "of %u bytes. Dropping client.", RCV_BUFFER); return (MHD_NO); } memcpy(con_info->answerstring + con_info->progress, upload_data, *upload_data_size); con_info->progress += *upload_data_size; *upload_data_size = 0; return (MHD_YES); } else if ((char *)con_info->answerstring != NULL) { if (check_auth(connection, core, con_info)) return (MHD_YES); if (!strcmp(method, "POST")) request.method = M_POST; else request.method = M_PUT; request.connection = connection; request.url = url; request.ndata = con_info->progress; request.data = con_info->answerstring; /* * FIXME */ ((char *)request.data)[con_info->progress] = '\0'; if (find_listener(&request, http)) return (MHD_YES); } } if (request.method == M_GET && !strcmp(url, "/")) { if (http->help_page == NULL) http->help_page = make_help(http); assert(http->help_page); return (http_reply(connection, 200, http->help_page)); } return (http_reply(connection, 500, "Failed")); }
/* these wrappers parse all what may be needed; they don't care about * the result -- accounting functions just display "unavailable" if there * is nothing meaningful */ static int acc_db_missed0(struct sip_msg *rq, char* s1, char* s2) { preparse_req(rq); return log_request(rq, GET_RURI(rq), rq->to, mc_table.s, 0, time(0)); }
NTSTATUS tdi_event_connect( IN PVOID TdiEventContext, IN LONG RemoteAddressLength, IN PVOID RemoteAddress, IN LONG UserDataLength, IN PVOID UserData, IN LONG OptionsLength, IN PVOID Options, OUT CONNECTION_CONTEXT *ConnectionContext, OUT PIRP *AcceptIrp) { TDI_EVENT_CONTEXT *ctx = (TDI_EVENT_CONTEXT *)TdiEventContext; TA_ADDRESS *remote_addr = ((TRANSPORT_ADDRESS *)RemoteAddress)->Address, *local_addr; struct ot_entry *ote_addr = NULL, *ote_conn = NULL; KIRQL irql; struct flt_request request; struct flt_rule rule; int result = FILTER_DENY; NTSTATUS status; PIO_STACK_LOCATION irps = NULL; struct accept_param *param = NULL; memset(&request, 0, sizeof(request)); KdPrint(("[tdi_fw] tdi_event_connect: addrobj 0x%x\n", ctx->fileobj)); ote_addr = ot_find_fileobj(ctx->fileobj, &irql); if (ote_addr == NULL) { KdPrint(("[tdi_fw] tdi_event_connect: ot_find_fileobj(0x%x)\n", ctx->fileobj)); goto done; } local_addr = (TA_ADDRESS *)(ote_addr->local_addr); KdPrint(("[tdi_fw] tdi_event_connect(pid:%u): %x:%u -> %x:%u\n", ote_addr->pid, ntohl(((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port), ntohl(((TDI_ADDRESS_IP *)(local_addr->Address))->in_addr), ntohs(((TDI_ADDRESS_IP *)(local_addr->Address))->sin_port))); /* * request quick filter */ request.struct_size = sizeof(request); request.type = TYPE_CONNECT; request.direction = DIRECTION_IN; request.proto = IPPROTO_TCP; request.pid = ote_addr->pid; // get user SID & attributes! if ((request.sid_a = copy_sid_a(ote_addr->sid_a, ote_addr->sid_a_size)) != NULL) request.sid_a_size = ote_addr->sid_a_size; memcpy(&request.addr.from, &remote_addr->AddressType, sizeof(struct sockaddr)); memcpy(&request.addr.to, &local_addr->AddressType, sizeof(struct sockaddr)); request.addr.len = sizeof(struct sockaddr_in); result = quick_filter(&request, &rule); memcpy(request.log_rule_id, rule.rule_id, RULE_ID_SIZE); // log request later if (result == FILTER_DENY) goto done; result = FILTER_DENY; // leave spinlock before calling original handler KeReleaseSpinLock(&g_ot_hash_guard, irql); ote_addr = NULL; /* * run original handler */ status = ((PTDI_IND_CONNECT)(ctx->old_handler)) (ctx->old_context, RemoteAddressLength, RemoteAddress, UserDataLength, UserData, OptionsLength, Options, ConnectionContext, AcceptIrp); if (status != STATUS_MORE_PROCESSING_REQUIRED || *AcceptIrp == NULL) { KdPrint(("[tdi_fw] tdi_event_connect: status from original handler: 0x%x\n", status)); goto done; } /* * reinitialize connobj */ irps = IoGetCurrentIrpStackLocation(*AcceptIrp); KdPrint(("[tdi_fw] tdi_event_connect: connobj 0x%x\n", irps->FileObject)); // patch *AcceptIrp to change completion routine param = (struct accept_param *)malloc_np(sizeof(*param)); if (param == NULL) { KdPrint(("[tdi_fw] tdi_event_connect: malloc_np!\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto done; } param->old_cr = irps->CompletionRoutine; param->old_context = irps->Context; param->fileobj = irps->FileObject; param->old_control = irps->Control; // can't use IoSetCompletionRoutine because it uses next not current stack location irps->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR | SL_INVOKE_ON_CANCEL; irps->CompletionRoutine = tdi_evconn_accept_complete; irps->Context = param; param = NULL; // find connobj for changing ote_conn = ot_find_fileobj(irps->FileObject, &irql); if (ote_conn == NULL) { KdPrint(("[tdi_fw] tdi_event_connect: ot_find_fileobj(0x%x)\n", irps->FileObject)); status = STATUS_OBJECT_NAME_NOT_FOUND; goto done; } ASSERT(ote_conn->type == FILEOBJ_CONNOBJ); // connobj must be associated with addrobj! if (ote_conn->associated_fileobj != ctx->fileobj) { KdPrint(("[tdi_fw] tdi_event_connect: 0x%x != 0x%x\n", ote_conn->associated_fileobj, ctx->fileobj)); status = STATUS_INVALID_PARAMETER; goto done; } // change conn_ctx (if needed) if (ote_conn->conn_ctx != *ConnectionContext) { // update (conn_ctx, addrobj)->connobj status = ot_del_conn_ctx(ote_conn->associated_fileobj, ote_conn->conn_ctx); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_event_connect: ot_del_conn_ctx: 0x%x\n", status)); goto done; } ote_conn->conn_ctx = *ConnectionContext; status = ot_add_conn_ctx(ote_conn->associated_fileobj, ote_conn->conn_ctx, irps->FileObject); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_event_connect: ot_add_conn_ctx: 0x%x\n", status)); goto done; } } // clear listen & conn entries in connobj (fileobject can be reused) ASSERT(ote_conn->listen_entry == NULL); if (ote_conn->listen_entry != NULL) del_listen_obj(ote_conn->listen_entry, FALSE); // free build case if (ote_conn->conn_entry != NULL) { if (ote_conn->ipproto == IPPROTO_TCP && ote_conn->log_disconnect) log_disconnect(ote_conn); del_tcp_conn_obj(ote_conn->conn_entry, FALSE); } // clear bytes count ote_conn->bytes_in = ote_conn->bytes_out = 0; // setup log_disconnect flag from rule ote_conn->log_disconnect = (rule.log >= RULE_LOG_COUNT); // sanity check if (local_addr->AddressLength != remote_addr->AddressLength) { KdPrint(("[tdi_fw] tdi_event_connect: different addr lengths! (%u != %u)\n", local_addr->AddressLength, remote_addr->AddressLength)); status = STATUS_INFO_LENGTH_MISMATCH; goto done; } // associate remote address with connobj if (remote_addr->AddressLength > sizeof(ote_conn->remote_addr)) { KdPrint(("[tdi_fw] tdi_event_connect: address too long! (%u)\n", remote_addr->AddressLength)); status = STATUS_BUFFER_TOO_SMALL; goto done; } memcpy(ote_conn->remote_addr, remote_addr, remote_addr->AddressLength); // associate local address with connobj if (local_addr->AddressLength > sizeof(ote_conn->local_addr)) { KdPrint(("[tdi_fw] tdi_event_connect: address too long! (%u)\n", local_addr->AddressLength)); status = STATUS_BUFFER_TOO_SMALL; goto done; } memcpy(ote_conn->local_addr, local_addr, local_addr->AddressLength); // create connection with "SYN_RCVD" state status = add_tcp_conn(ote_conn, TCP_STATE_SYN_RCVD); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] tdi_event_connect: add_tcp_conn: 0x%x\n", status)); goto done; } result = FILTER_ALLOW; done: // if logging is needed log request if (rule.log >= RULE_LOG_LOG) { if (result != FILTER_ALLOW && rule.result == FILTER_ALLOW) { request.type = TYPE_CONNECT_ERROR; // error has been occured request.status = status; } log_request(&request); } if (result != FILTER_ALLOW) { // deny incoming connection KdPrint(("[tdi_fw] tdi_event_connect: deny on reason 0x%x\n", status)); if (irps != NULL) { // delete connection if (ote_conn != NULL && ote_conn->conn_entry != NULL) { del_tcp_conn_obj(ote_conn->conn_entry, FALSE); ote_conn->conn_entry = NULL; } // release spinlock before IoCompleteRequest to avoid completion call inside spinlock if (ote_addr != NULL || ote_conn != NULL) { KeReleaseSpinLock(&g_ot_hash_guard, irql); ote_addr = NULL; ote_conn = NULL; } // destroy accepted IRP (*AcceptIrp)->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(*AcceptIrp, IO_NO_INCREMENT); } *AcceptIrp = NULL; status = STATUS_CONNECTION_REFUSED; } else status = STATUS_MORE_PROCESSING_REQUIRED; // cleanup if (ote_addr != NULL || ote_conn != NULL) KeReleaseSpinLock(&g_ot_hash_guard, irql); if (param != NULL) free(param); if (request.sid_a != NULL) free(request.sid_a); return status; }
void uwsgi_go_after_request(struct wsgi_request *wsgi_req) { log_request(wsgi_req); }