void copy_writer(SshStreamNotification op, void *context) { int len; int len2; unsigned char buf[100]; if (op != SSH_STREAM_CAN_OUTPUT) return; for (;;) { len = ssh_buffer_len(testdata) - test_data_index; len2 = ssh_rand() % 100000; if (len <= 0) { if (ssh_rand() % 2 == 0) ssh_stream_output_eof(ts1); ssh_stream_destroy(ts1); ts1 = NULL; destroy_count++; return; } if (len > len2) len = len2; len = ssh_stream_write(ts1, (unsigned char *)ssh_buffer_ptr(testdata) + test_data_index, len); if (len == 0) { if (ssh_rand() % 2 == 0) ssh_stream_output_eof(ts1); ssh_stream_destroy(ts1); ts1 = NULL; destroy_count++; return; /* Eof while writing. */ } if (len < 0) return; /* Cannot write more at this time */ test_data_index += len; if (ssh_rand() % 5 == 0) { len = ssh_stream_read(ts1, buf, sizeof(buf)); if (len == 0 && !reader_sent_eof) ssh_fatal("copy_writer: read returned EOF when not sent"); if (len > 0) ssh_fatal("copy_writer: read > 0"); } } }
static Boolean authentication_handler(SshHttpServerContext ctx, SshHttpServerConnection conn, SshStream stream, void *context) { SshHttpAuthentication auth; char *name; char *password; auth = ssh_http_server_get_proxy_authentication(conn, &name, &password); switch (auth) { case SSH_HTTP_AUTHENTICATION_NONE: break; case SSH_HTTP_AUTHENTICATION_BASIC: fprintf(stderr, "%s: authentication: name=%s, password=%s\n", program, name, password); ssh_xfree(name); ssh_xfree(password); /* Allow access. */ return FALSE; break; } /* Deny access. */ ssh_http_server_error_proxy_authentication_required(conn, "WWW Proxy"); ssh_stream_destroy(stream); return TRUE; }
void tcp_connect_socks_notify(SshStreamNotification notification, void *context) { SshFSMThread thread = (SshFSMThread) context; ConnectContext c = (ConnectContext) ssh_fsm_get_gdata(thread); c->handle = NULL; switch (notification) { case SSH_STREAM_INPUT_AVAILABLE: case SSH_STREAM_CAN_OUTPUT: /* Just retry the processing for the current state. */ break; case SSH_STREAM_DISCONNECTED: SSH_DEBUG(1, ("ssh_socket_socks_notify: DISCONNECTED")); ssh_stream_destroy(c->stream); c->stream = NULL; /* Count this as a failure. */ if (tcp_connect_register_failure(thread, SSH_TCP_FAILURE)) break; if (c->socks_host) { if (c->socks_type == SSH_TCP_SOCKS5 && !c->host_addresses) { SSH_FSM_SET_NEXT(tcp_connect_socks_connect); } else if (c->socks_exceptions) { unsigned char *next; next = ssh_ustrchr(c->host_addresses, ','); if (next) *next = '\0'; if (ssh_inet_compare_netmask(c->socks_exceptions, c->host_addresses)) SSH_FSM_SET_NEXT(tcp_connect_host_connect); else SSH_FSM_SET_NEXT(tcp_connect_socks_connect); if (next) *next = ','; } else { SSH_FSM_SET_NEXT(tcp_connect_socks_connect); } } else { SSH_FSM_SET_NEXT(tcp_connect_host_connect); } break; default: ssh_fatal("ssh_socket_socks_notify: unexpected notification %d", (int)notification); } ssh_fsm_continue(thread); }
void server1_read(SshStream stream) { int ret; unsigned char buf[1024]; for (;;) { ret = ssh_stream_read(stream, buf, sizeof(buf)); if (ret < 0) return; if (ret == 0) { if (read_count != send_count) ssh_fatal("server1_read eof received, read_count %ld send_count %ld", read_count, send_count); break; } if (memcmp(buf, ssh_buffer_ptr(&expect_buffer), ret) != 0) ssh_fatal("server1_read data does not match"); ssh_buffer_consume(&expect_buffer, ret); read_count += ret; } /* All data has been received. */ ssh_stream_destroy(stream); exited1 = 1; }
void copy_reader(SshStreamNotification op, void *context) { unsigned char *buf; int len; if (op != SSH_STREAM_INPUT_AVAILABLE) return; buf = ssh_xmalloc(T_STREAMPAIR_BIG_BUF_LEN); for (;;) { len = ssh_stream_read(ts2, buf, T_STREAMPAIR_BIG_BUF_LEN); if (len == 0) { ssh_stream_destroy(ts2); ts2 = NULL; destroy_count++; ssh_xfree(buf); return; /* EOF received */ } if (len < 0) { ssh_xfree(buf); return; } ssh_buffer_append(received_data, buf, len); if (break_test && ssh_rand() % 10 == 0) { ssh_stream_destroy(ts2); ts2 = NULL; destroy_count++; ssh_xfree(buf); return; } if (!reader_sent_eof && ssh_rand() % 10 == 0) { ssh_stream_output_eof(ts2); reader_sent_eof = TRUE; } } /*NOTREACHED*/ }
void disconnect_test() { SshStream server; SshStream s1, s2; unsigned char buf[8192]; int len, i; ssh_stream_pair_create(&s1, &s2); /* Initialize server side. */ server = ssh_transport_server_wrap(s1, random_state, TEST_VERSION, NULL, hostkey, serverkey, hostkey_blob, hostkey_blob_len, NULL, NULL); ssh_event_loop_run(); if (random() % 5 == 0) len = 0; else len = random() % sizeof(buf); for (i = 0; i < len; i++) { buf[i] = random(); if (buf[i] < 32 && buf[i] != '\n' && buf[i] != '\r') buf[i] = 'X'; } ssh_stream_write(s2, buf, len); ssh_event_loop_run(); ssh_stream_destroy(s2); ssh_event_loop_run(); ssh_stream_destroy(server); ssh_event_loop_run(); }
void ssh_packet_wrapper_destroy_now(SshPacketWrapper down) { /* Close the downward stream. */ ssh_stream_destroy(down->stream); /* Uninitialize buffers. */ ssh_buffer_uninit(&down->incoming); ssh_buffer_uninit(&down->outgoing); ssh_buffer_uninit(&down->outgoing_packet); /* Fill the context with 'F' to ease debugging, and free it. */ memset(down, 'F', sizeof(*down)); ssh_xfree(down); }
void connect1_write(SshStream stream) { int len; while (ssh_buffer_len(&send_buffer) > 0) { len = ssh_buffer_len(&send_buffer); len = ssh_stream_write(stream, ssh_buffer_ptr(&send_buffer), len); if (len < 0) return; if (len == 0) ssh_fatal("connect1_write failed"); ssh_buffer_consume(&send_buffer, len); } ssh_stream_output_eof(stream); ssh_stream_destroy(stream); }
void ssh_pipe_stream_destroy(void *context) { SshPipeStream pipes = (SshPipeStream)context; ssh_debug("ssh_pipe_stream_destroy"); /* Cancel any pending input notification callbacks for this pipe. */ ssh_cancel_timeouts(ssh_pipe_sigchld_do_callback, (void *)pipes); /* Unregister the sigchld handler for the stream. */ ssh_sigchld_unregister(pipes->pid); /* Destroy the stream going to the master side. */ ssh_stream_destroy(pipes->stdio_stream); /* Free our own data structures. */ memset(pipes, 'F', sizeof(*pipes)); ssh_xfree(pipes); }
/* Destroys the connection context. */ void tcp_connect_destroy_ctx(ConnectContext c) { SSH_DEBUG(4, ("Destroying ConnectContext...")); SSH_PRECOND(c != NULL); if (c->handle) ssh_operation_abort(c->handle); ssh_cancel_timeout(&c->timeout); ssh_free(c->local_address); ssh_free(c->host_name); ssh_free(c->host_addresses); ssh_free(c->socks_host); ssh_free(c->socks_addresses); ssh_free(c->user_name); ssh_free(c->socks_exceptions); if (c->socks_buf) ssh_buffer_free(c->socks_buf); if (c->stream) ssh_stream_destroy(c->stream); if (c->upper_handle) ssh_operation_unregister(c->upper_handle); ssh_free(c); }
void t_tcpc_stream_callback(SshStreamNotification notification, void* context) { t_tcpc_context pcontext = context; char buf[4096]; int i; SSH_TRACE(SSH_D_MY, ("%s", "t_tcpc_stream_callback")); switch (notification) { case SSH_STREAM_INPUT_AVAILABLE: SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_INPUT_AVAILABLE")); while ((i = ssh_stream_read(pcontext->pstream, buf, 4096)) > 0) { buf[i] = 0; SSH_TRACE(SSH_D_MY, ("read: %s", buf)); if (pcontext->phost_name_or_address) { ssh_buffer_append(pcontext->pbuffer, buf, i); t_tcpc_stream_callback(SSH_STREAM_CAN_OUTPUT, pcontext); } else { SSH_TRACE(SSH_D_MY, ("output: %s", buf)); } } break; case SSH_STREAM_CAN_OUTPUT: SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_CAN_OUTPUT")); if (ssh_buffer_len(pcontext->pbuffer) > 0) { i = ssh_stream_write(pcontext->pstream, ssh_buffer_ptr(pcontext->pbuffer), ssh_buffer_len(pcontext->pbuffer)); if (i > 0) { ssh_buffer_consume(pcontext->pbuffer, i); } } break; case SSH_STREAM_DISCONNECTED: SSH_TRACE(SSH_D_MY, ("%s", "SSH_STREAM_DISCONNECTED")); #if 0 /* BUG BUG BUG */ ssh_stream_destroy(pcontext->pstream); #endif /* 0 */ ssh_event_loop_abort(); break; default: SSH_NOTREACHED; break; } }
static void result_callback(SshHttpClientContext ctx, SshHttpResult result, SshTcpError ip_error, SshStream stream, void *callback_context) { ProxyRequest *req = callback_context; SshBuffer error; char buf[256]; switch (result) { case SSH_HTTP_RESULT_SUCCESS: { const char *value = NULL; SshCopyStreamCopyCb copy_cb = copy_data; if ((value = ssh_http_get_header_field(ctx, "Content-Type"))) ssh_http_server_set_values(req->conn, SSH_HTTP_HDR_FIELD, "Content-Type", value, SSH_HTTP_HDR_END); req->client_stream = stream; #if SMART_UPDATE if (value && strncmp(value, "text/html", 9) == 0) copy_cb = filter_html; #endif ssh_copy_stream(req->server_stream, req->client_stream, copy_cb, req_finish, req); } break; case SSH_HTTP_RESULT_MALFORMED_URL: error = ssh_buffer_allocate(); ssh_buffer_append_cstrs(error, "<body><h1>Malformed URL</h1>n", NULL); ssh_http_server_send_buffer(req->conn, error); ssh_xfree(req); break; case SSH_HTTP_RESULT_REDIRECT_LIMIT_EXCEEDED: { const char *location = ssh_http_get_header_field(ctx, "Location"); const char *reason_phrase; SSH_DEBUG(SSH_D_HIGHSTART, ("Redirect: %s", location)); ssh_http_server_error(req->conn, ssh_http_get_status_code(ctx, &reason_phrase), SSH_HTTP_HDR_LOCATION, location, SSH_HTTP_HDR_END); ssh_stream_destroy(req->server_stream); ssh_xfree(req); } break; case SSH_HTTP_RESULT_HTTP_ERROR: { const char *reason_phrase; SshUInt32 error_code; error_code = ssh_http_get_status_code(ctx, &reason_phrase); error = ssh_buffer_allocate(); ssh_snprintf(buf, sizeof(buf), "%ld", error_code); ssh_http_server_error(req->conn, error_code, SSH_HTTP_HDR_END); ssh_buffer_append_cstrs(error, "<body><h1>HTTP Error (", buf, ")</h1>\n<pre>\n", reason_phrase, "\n", NULL); ssh_http_server_send_buffer(req->conn, error); ssh_xfree(req); } break; default: error = ssh_buffer_allocate(); ssh_snprintf(buf, sizeof(buf), "%d", result); ssh_buffer_append_cstrs(error, "<body><h1>HTTP Library Error ", buf, "</h1>\n", NULL); ssh_http_server_send_buffer(req->conn, error); ssh_xfree(req); break; } }
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream, void *context) { SshRemoteTcpForward fwd = (SshRemoteTcpForward)context; char ip[20], port[20]; SshBuffer buffer; SSH_DEBUG(5, ("connection to forwarded TCP/IP port")); /* We should only receive new connection notifications. */ if (error != SSH_IP_NEW_CONNECTION) ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error); /* Get remote ip address and port. */ if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip))) strcpy(ip, "UNKNOWN"); if (!ssh_tcp_get_remote_port(stream, port, sizeof(port))) strcpy(port, "UNKNOWN"); SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s", fwd->port, ip, port)); ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL, "Connection to forwarded port %s from %s:%s", fwd->port, fwd->common->remote_host, port); /* XXXXXXXX */ #ifdef HAVE_LIBWRAP { struct request_info req; struct servent *serv; char fwdportname[32]; void *old_handler; old_handler = signal(SIGCHLD, SIG_DFL); /* try to find port's name in /etc/services */ serv = getservbyport(atoi(fwd->port), "tcp"); if (serv == NULL) { /* not found (or faulty getservbyport) - use the number as a name */ snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port); } else { snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s", serv->s_name); } /* fill req struct with port name and fd number */ request_init(&req, RQ_DAEMON, fwdportname, RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL); fromhost(&req); if (!hosts_access(&req)) { ssh_conn_send_debug(fwd->common->conn, TRUE, "Fwd connection from %.500s to local port " \ "%s refused by tcp_wrappers.", eval_client(&req), fwdportname); ssh_stream_destroy(stream); signal(SIGCHLD, old_handler); return; } signal(SIGCHLD, old_handler); ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL, "Remote fwd connect from %.500s to local port %s", eval_client(&req), fwdportname); } #endif /* HAVE_LIBWRAP */ /* Register that we have an open channel. */ ssh_common_new_channel(fwd->common); /* Send a request to open a channel and connect it to the given port. */ ssh_buffer_init(&buffer); ssh_encode_buffer(&buffer, SSH_FORMAT_UINT32_STR, fwd->address_to_bind, strlen(fwd->address_to_bind), SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port), SSH_FORMAT_UINT32_STR, ip, strlen(ip), SSH_FORMAT_UINT32, (SshUInt32) atol(port), SSH_FORMAT_END); ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip", stream, TRUE, FALSE, SSH_TCPIP_WINDOW, SSH_TCPIP_PACKET_SIZE, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer), NULL, ssh_channel_tcp_connection_destroy, (void *)fwd->common, NULL, NULL); ssh_buffer_uninit(&buffer); }
void tcp_connect_socks_connect_done_cb(SshTcpError error, SshStream stream, void *context) { SshFSMThread thread = (SshFSMThread) context; ConnectContext c = (ConnectContext) ssh_fsm_get_gdata(thread); struct SocksInfoRec socksinfo; SocksError ret; unsigned char host_port[64], *next = NULL; c->handle = NULL; if (error != SSH_TCP_OK) { /* Get next address. */ if (ssh_ustrchr(c->socks_next_address, ',')) { c->socks_next_address = ssh_ustrchr(c->socks_next_address, ',') + 1; } else { /* At end of list; consider it as a failure. */ if (tcp_connect_register_failure(thread, error)) { SSH_FSM_CONTINUE_AFTER_CALLBACK(thread); return; } c->socks_next_address = c->socks_addresses; } /* Try connecting again. */ SSH_FSM_SET_NEXT(tcp_connect_socks_connect); SSH_FSM_CONTINUE_AFTER_CALLBACK(thread); return; } /* Save the stream. */ c->stream = stream; /* Set the callback so that we'll get any required read/write notifications. */ ssh_stream_set_callback(stream, tcp_connect_socks_notify, thread); if (c->next_address && (next = ssh_ustrchr(c->next_address, ',')) != NULL) { *next = '\0'; next++; } if (c->socks_type == SSH_TCP_SOCKS5) { socksinfo.socks_version_number = 5; socksinfo.command_code = SSH_SOCKS5_COMMAND_CODE_CONNECT; if (c->next_address) socksinfo.ip = (unsigned char *) c->next_address; else socksinfo.ip = c->host_name; } else { socksinfo.socks_version_number = 4; socksinfo.command_code = SSH_SOCKS4_COMMAND_CODE_CONNECT; socksinfo.ip = (unsigned char *) c->next_address; } ssh_snprintf(host_port, sizeof(host_port), "%d", c->host_port); socksinfo.port = host_port; socksinfo.username = c->user_name; ssh_buffer_clear(c->socks_buf); SSH_FSM_SET_NEXT(tcp_connect_socks_send); ret = ssh_socks_client_generate_methods(c->socks_buf, &socksinfo); if (ret == SSH_SOCKS_SUCCESS) ret = ssh_socks_client_generate_open(c->socks_buf, &socksinfo); if (ret != SSH_SOCKS_SUCCESS) { if (next != NULL) { c->stream = NULL; ssh_stream_destroy(stream); c->next_address = next; SSH_FSM_SET_NEXT(tcp_connect_socks_lookup); } else { if (ret == SSH_SOCKS_ERROR_INVALID_ARGUMENT) c->error = SSH_TCP_NO_ADDRESS; else c->error = SSH_TCP_FAILURE; SSH_FSM_SET_NEXT(tcp_connect_finish); } } SSH_FSM_CONTINUE_AFTER_CALLBACK(thread); }
void handler_callback(SshStreamNotification notification, void *context) { Handler c = context; SshTransportStatistics stats; Boolean cont = FALSE; #ifdef DEBUG ssh_debug("\n** %s: handler_callback %s **\n", c->side, opnames[c->script->op]); #endif do { switch (notification) { case SSH_STREAM_INPUT_AVAILABLE: cont = handler_input(c); if (cont) notification = SSH_STREAM_CAN_OUTPUT; break; case SSH_STREAM_CAN_OUTPUT: cont = handler_output(c); if (cont) notification = SSH_STREAM_INPUT_AVAILABLE; break; case SSH_STREAM_DISCONNECTED: ssh_fatal("%s: handler_callback: DISCONNECT", c->side); default: ssh_fatal("%s: handler_callback: unexpected %d", c->side, (int)notification); } if (c->script->op == OP_END) { /* End of script reached. Destroy handler. */ #ifdef DEBUG ssh_debug("%s: End of script reached", c->side); #endif cont = FALSE; ssh_transport_get_statistics(c->stream, &stats); #ifdef DEBUG ssh_debug("%s: %lu/%lu bytes in, %lu/%lu out, %lu packets in, " "%lu out\n", c->side, stats.compressed_incoming_bytes, stats.uncompressed_incoming_bytes, stats.compressed_outgoing_bytes, stats.uncompressed_outgoing_bytes, stats.incoming_packets, stats.outgoing_packets); #endif ssh_stream_destroy(c->stream); memset(c, 'F', sizeof(*c)); ssh_xfree(c); end_of_script_count++; } } while (cont); }
SshServer ssh_server_wrap(SshStream stream, SshConfig config, SshRandomState random_state, SshPrivateKey private_server_key, SshServerDisconnectProc disconnect, SshServerDebugProc debug, SshVersionCallback version_check, SshAuthPolicyProc auth_policy_proc, SshCommonAuthenticatedNotify authenticated_notify, void *context) { SshServer server; SshStream trans, auth; SshTransportParams params; /* Create parameters. */ params = ssh_transport_create_params(); if (!ssh_server_update_transport_params(config, params)) { ssh_stream_destroy(stream); ssh_transport_destroy_params(params); return NULL; } /* Check the host key. */ if (config->private_host_key == NULL || config->public_host_key_blob == NULL) ssh_fatal("ssh_server_wrap: no host key !"); /* Create the server object. */ server = ssh_xcalloc(1, sizeof(*server)); server->config = config; /* Create a transport layer protocol object. */ ssh_debug("ssh_server_wrap: creating transport protocol"); trans = ssh_transport_server_wrap(stream, random_state, SSH2_PROTOCOL_VERSION_STRING, params, config->private_host_key, private_server_key, config->public_host_key_blob, config->public_host_key_blob_len, version_check, (void *)context); ssh_transport_get_compatibility_flags(trans, &server->compat_flags); /* Create the authentication methods array for the server. */ server->methods = ssh_server_authentication_initialize(); /* XXX config data */ /* Create an authentication protocol object. */ ssh_debug("ssh_server_wrap: creating userauth protocol"); /* XXX policy_proc */ auth = ssh_auth_server_wrap(trans, auth_policy_proc, (void *)server, server->methods, (void *)server); /* Create the common part of client/server objects. */ server->common = ssh_common_wrap(stream, auth, FALSE, config, random_state, NULL, disconnect, debug, authenticated_notify, context); if (server->common == NULL) { ssh_server_authentication_uninitialize(server->methods); ssh_xfree(server); return NULL; } return server; }
/* The URI handler. */ static Boolean proxy_handler(SshHttpServerContext ctx, SshHttpServerConnection conn, SshStream stream, void *context) { const char *method = ssh_http_server_get_method(conn); const char *uri = ssh_http_server_get_uri(conn); SshHttpClientParams params; ProxyRequest *req; SshBuffer error; ProxyCensor *c; SSH_DEBUG(SSH_D_HIGHSTART, ("method=%s, uri=%s", method, uri)); for (c = censor; c; c = c->next) if (ssh_match_pattern(uri, c->pattern)) { SSH_DEBUG(SSH_D_HIGHSTART, ("censored by pattern `%s'", c->pattern)); ssh_http_server_error(conn, 301, SSH_HTTP_HDR_LOCATION, "http://people.ssh.fi/mtr/censor.jpg", SSH_HTTP_HDR_FIELD, "Content-Type", "text/html", SSH_HTTP_HDR_END); ssh_stream_destroy(stream); return TRUE; } memset(¶ms, 0, sizeof(params)); params.http_proxy_url = proxy_url; params.num_redirections = 0; req = ssh_xcalloc(1, sizeof(*req)); req->server = ctx; req->conn = conn; req->server_stream = stream; req->client = ssh_http_client_init(¶ms); if (strcmp(method, "GET") == 0) ssh_http_get(req->client, uri, result_callback, req, SSH_HTTP_HDR_END); else if (strcmp(method, "HEAD") == 0) ssh_http_head(req->client, uri, result_callback, req, SSH_HTTP_HDR_END); else if (strcmp(method, "POST") == 0 || strcmp(method, "PUT") == 0) { SSH_DEBUG(SSH_D_ERROR, ("%s not implemented yet", method)); ssh_xfree(req); error = ssh_buffer_allocate(); ssh_buffer_append_cstrs(error, "<body><h1>Method `", method, "' not implemented yet</h1>\n", NULL); ssh_http_server_send_buffer(conn, error); } else { SSH_DEBUG(SSH_D_ERROR, ("unknown method `%s'", method)); ssh_xfree(req); error = ssh_buffer_allocate(); ssh_buffer_append_cstrs(error, "<body><h1>Unknown method `", method, "'</h1>\n", NULL); ssh_http_server_send_buffer(conn, error); } return TRUE; }
void ssh_channel_dtcp_incoming_connection(SshStreamNotification op, SshStream stream, void *context) { SshLocalTcpForward fwd = (SshLocalTcpForward)context; char ip[20], port[20]; /* We should only receive new connection notifications. */ if (op != SSH_IP_NEW_CONNECTION) ssh_fatal("ssh_channel_dtcp_incoming_connection: op %d", (int)op); /* Get remote ip address and port. */ if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip))) strcpy(ip, "UNKNOWN"); if (!ssh_tcp_get_remote_port(stream, port, sizeof(port))) strcpy(port, "UNKNOWN"); #ifdef HAVE_LIBWRAP { struct request_info req; struct servent *serv; char fwdportname[32]; void *old_handler; old_handler = signal(SIGCHLD, SIG_DFL); /* try to find port's name in /etc/services */ serv = getservbyport(atoi(fwd->port), "tcp"); if (serv == NULL) { /* not found (or faulty getservbyport) - use the number as a name */ snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port); } else { snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s", serv->s_name); } /* fill req struct with port name and fd number */ request_init(&req, RQ_DAEMON, fwdportname, RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL); fromhost(&req); if (!hosts_access(&req)) { ssh_conn_send_debug(fwd->common->conn, TRUE, "Fwd connection from %.500s to local port %s " "refused by tcp_wrappers.", eval_client(&req), fwdportname); ssh_log_event(fwd->common->config->log_facility, SSH_LOG_WARNING, "Fwd connection from %.500s to local port %s " "refused by tcp_wrappers.", eval_client(&req), fwdportname); ssh_stream_destroy(stream); signal(SIGCHLD, old_handler); return; } signal(SIGCHLD, old_handler); ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL, "direct fwd connect from %.500s to local port %s", eval_client(&req), fwdportname); } #endif /* HAVE_LIBWRAP */ /* Send a request to open a channel and connect it to the given port. */ ssh_channel_dtcp_open_to_remote(fwd->common, stream, fwd->connect_to_host, fwd->connect_to_port, ip, port); }
/* This function reads complete payload from the HTTP stream described at the context argument (also the thread running this session is identified b the context's upper context), and calls the input processing thread when done. This gets called when the CA replies to the clients message or poll. */ static void pkix_http_stream_callback(SshStreamNotification not, void *context) { int i; size_t len; SshUInt8 type_or_version; unsigned char input[256], *data; PkixHttpReadContext c = (PkixHttpReadContext)context; SshFSMThread thread = (SshFSMThread) c->upper_context; SshPkiThreadData tdata = ssh_fsm_get_tdata(thread); SshPkiGlobalData gdata = ssh_fsm_get_gdata(thread); while (TRUE) { i = ssh_stream_read(c->http_stream, input, sizeof(input)); if (i == 0) { if ((len = ssh_buffer_len(c->input)) > 5) { data = ssh_buffer_ptr(c->input); len = SSH_GET_32BIT(data); type_or_version = data[4]; if (type_or_version < 10) { tdata->input_version = SSH_PKI_VERSION_0; tdata->input_flags = 0; tdata->input_type = type_or_version; tdata->input_len = len - 1; tdata->input = ssh_memdup(data + 5, tdata->input_len); } else { if (type_or_version == 10) { data += 4; /* skip to end of length */ tdata->input_version = SSH_PKI_VERSION_1; tdata->input_len = len - 3; tdata->input_flags = data[1]; tdata->input_type = data[2]; data += 3; tdata->input = ssh_memdup(data, tdata->input_len); } else { tdata->input_version = type_or_version; tdata->input_type = SSH_PKI_MSG_ERRORREP; } } if (tdata->input == NULL) tdata->input_type = SSH_PKI_MSG_ERRORREP; ssh_buffer_free(c->input); ssh_stream_destroy(c->http_stream); ssh_fsm_continue(gdata->input_thread); ssh_free(c); return; } else { error: tdata->input_type = SSH_PKI_MSG_ERRORREP; ssh_fsm_set_next(thread, pkix_aborted); ssh_fsm_continue(gdata->input_thread); ssh_stream_destroy(c->http_stream); ssh_buffer_free(c->input); ssh_free(c); return; } } else if (i < 0) { return; } else { if (ssh_buffer_append(c->input, input, i) != SSH_BUFFER_OK) { goto error; } } } }