int main(int ac, char **av) { int i, j; int pass; unsigned char buf[1024]; snprintf(lpath1, sizeof (lpath1), "/tmp/lstr1.%x", (unsigned)random()); snprintf(lpath2, sizeof (lpath2), "/tmp/lstr2.%x", (unsigned)random()); printf("Doing %d iterations of localstream test:", PASSES); for (pass = 0; pass < PASSES; pass++) { printf(" %d", pass); fflush(stdout); ssh_buffer_init(&send_buffer); ssh_buffer_init(&expect_buffer); for (i = 0; i < 100; i++) { for (j = 0; j < sizeof(buf); j++) buf[j] = random(); ssh_buffer_append(&send_buffer, buf, sizeof(buf)); ssh_buffer_append(&expect_buffer, buf, sizeof(buf)); send_count += sizeof(buf); } ssh_event_loop_initialize(); remove(lpath1); listener1 = ssh_local_make_listener(lpath1, listener1_callback, (void *)4); if (!listener1) { ssh_fatal("cannot create listener1"); } ssh_local_connect(lpath1, connect1_done, (void *)3); ssh_event_loop_run(); ssh_event_loop_uninitialize(); ssh_buffer_uninit(&send_buffer); ssh_buffer_uninit(&expect_buffer); } printf("\n"); return 0; }
SshStream ssh_packet_impl_create(SshPacketReceiveProc received_packet, SshPacketEofProc received_eof, SshPacketCanSendProc can_send, SshPacketImplDestroyProc destroy, void *context) { SshPacketImpl up; SshStream stream; /* Allocate and initialize the context. */ if ((up = ssh_calloc(1, sizeof(*up))) == NULL) return NULL; ssh_buffer_init(&up->incoming); ssh_buffer_init(&up->outgoing); ssh_buffer_init(&up->outgoing_packet); up->can_receive = FALSE; up->incoming_eof = FALSE; up->outgoing_eof = FALSE; up->up_write_blocked = FALSE; up->up_read_blocked = FALSE; up->send_blocked = TRUE; /* Cause a callback immediately. */ /* Save the callback functions. */ up->received_packet = received_packet; up->received_eof = received_eof; up->can_send = can_send; up->destroy = destroy; up->context = context; up->up_callback = NULL_FNPTR; up->up_context = NULL; /* Cause the send callback to be called if non-NULL. Note that it isn't called until from the bottom of the event loop. */ ssh_packet_impl_restart_send(up); /* Wrap it into a stream. */ stream = ssh_stream_create(&ssh_packet_impl_methods, (void *)up); if (stream == NULL) ssh_fatal("Insufficient memory to create packet stream object!"); /* Enable receives. */ ssh_packet_impl_can_receive(stream, TRUE); return stream; }
SshBuffer *ssh_buffer_allocate() { SshBuffer *buffer = ssh_xmalloc(sizeof(*buffer)); ssh_buffer_init(buffer); buffer->dynamic = TRUE; return buffer; }
int ssh_cm_render_state(unsigned char *buf, int len, int precision, void *datum) { SshCMSearchState state = *(unsigned int *)((void *)&datum); int i; const char *name; SshBufferStruct buffer; ssh_buffer_init(&buffer); ssh_buffer_append_str(&buffer, "\nsearch-state = \n{\n"); if (state == 0) ssh_buffer_append_str(&buffer, " nil\n"); else { for (i = 0; i < 32; i++) { if (state & (1 << i)) { name = ssh_find_keyword_name(ssh_cm_debug_state_strs, (1 << i)); ssh_buffer_append_cstrs(&buffer, " ", name, "\n", NULL); } } } ssh_buffer_append_str(&buffer, "}\n"); return cm_debug_renderer_return(&buffer, buf, len); }
void ssh_channel_open_ssh1_agent_connected(SshStream stream, void *context) { SshAgentConnection a = (SshAgentConnection)context; SshBuffer buffer; unsigned char *cp; if (stream == NULL) { SSH_DEBUG(1, ("Connecting to the real agent failed.")); (*a->completion)(SSH_OPEN_CONNECT_FAILED, NULL, FALSE, FALSE, 0, NULL, 0, NULL, NULL, NULL, a->context); ssh_xfree(a); return; } SSH_DEBUG(5, ("connection to real agent established")); /* Increment the number of channels. */ ssh_common_new_channel(a->common); if (a->common->config->ssh_agent_compat == SSH_AGENT_COMPAT_SSH2) { /* We are required to send a FORWARDING_NOTIFY to the agent to inform it that the connection is actually forwarded. Format that packet now. */ ssh_buffer_init(&buffer); ssh_encode_buffer(&buffer, SSH_FORMAT_DATA, "1234", (size_t)4, SSH_FORMAT_CHAR, (unsigned int) SSH_AGENT_FORWARDING_NOTICE, SSH_FORMAT_UINT32_STR, a->common->server_host_name, strlen(a->common->server_host_name), SSH_FORMAT_UINT32_STR, a->common->remote_ip, strlen(a->common->remote_ip), SSH_FORMAT_UINT32, (SshUInt32) atol(a->common->remote_port), SSH_FORMAT_END); cp = ssh_buffer_ptr(&buffer); SSH_PUT_32BIT(cp, ssh_buffer_len(&buffer) - 4); /* Write the buffer to the channel. This is a kludge; this assumes that we can always write this much to the internal buffers. */ if (ssh_stream_write(stream, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)) != ssh_buffer_len(&buffer)) ssh_fatal("ssh_channel_open_agent_connected: kludge failed"); ssh_buffer_uninit(&buffer); } /* Create the channel. */ (*a->completion)(SSH_OPEN_OK, stream, TRUE, TRUE, AGENT_WINDOW_SIZE, NULL, 0, NULL, ssh_channel_ssh1_agent_connection_destroy, (void *)a->common, a->context); ssh_xfree(a); }
Boolean ssh2_key_blob_encode(unsigned long magic, const char *subject, const char *comment, const unsigned char *key, size_t keylen, unsigned char **encoded, size_t *encoded_len) { SshBufferStruct buffer; char *base64; unsigned int key_index; /* Translate to index. */ switch (magic) { case SSH_KEY_MAGIC_PUBLIC: key_index = 0; break; case SSH_KEY_MAGIC_PRIVATE: key_index = 1; break; case SSH_KEY_MAGIC_PRIVATE_ENCRYPTED: key_index = 2; break; default: return FALSE; } ssh_buffer_init(&buffer); /* Add the head for the key. */ ssh_key_blob_dump_line_str(&buffer, ssh2_pk_format_name_list[key_index].head); ssh_key_blob_dump_lf(&buffer); /* Handle key words. */ if (subject) { ssh_key_blob_dump_line_str(&buffer, "Subject: "); ssh_key_blob_dump_line_str(&buffer, subject); ssh_key_blob_dump_lf(&buffer); } if (comment) { ssh_key_blob_dump_line_str(&buffer, "Comment: "); ssh_key_blob_dump_quoted_str(&buffer, 9, comment); ssh_key_blob_dump_lf(&buffer); } /* Now add the base64 formatted stuff. */ base64 = (char *)ssh_buf_to_base64(key, keylen); ssh_key_blob_dump_str(&buffer, base64); ssh_key_blob_dump_lf(&buffer); ssh_xfree(base64); /* Add the tail for the key. */ ssh_key_blob_dump_line_str(&buffer, ssh2_pk_format_name_list[key_index].tail); ssh_key_blob_dump_lf(&buffer); *encoded_len = ssh_buffer_len(&buffer); *encoded = ssh_xmemdup(ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); ssh_buffer_uninit(&buffer); return TRUE; }
/* Initialize an already allocated file buffer */ void ssh_file_buffer_init(SshFileBuffer buf) { SSH_ASSERT(buf != NULL); buf->attached_as_fileptr = FALSE; buf->f = NULL; buf->read_callback = NULL_FNPTR; buf->read_context = NULL; ssh_buffer_init(&(buf->buf)); return; }
int ssh_cm_render_crl(unsigned char *buf, int len, int precision, void *datum) { SshX509Crl crl = datum; char *name; SshBerTimeStruct this_update, next_update; SshBufferStruct buffer; if (crl) { ssh_buffer_init(&buffer); ssh_buffer_append_str(&buffer, "\ncrl = { \n"); if (!ssh_x509_crl_get_issuer_name(crl, &name)) { ssh_buffer_append_str(&buffer, " missing-issuer-name\n"); } else { ssh_buffer_append_cstrs(&buffer, " issuer-name = <", name, ">\n", NULL); ssh_free(name); } if (!ssh_x509_crl_get_update_times(crl, &this_update, &next_update)) { ssh_buffer_append_str(&buffer, " missing-update-times\n"); } else { if (ssh_ber_time_available(&this_update)) { ssh_ber_time_to_string(&this_update, &name); ssh_buffer_append_cstrs(&buffer, " this-update = ", name, "\n", NULL); ssh_free(name); } if (ssh_ber_time_available(&next_update)) { ssh_ber_time_to_string(&next_update, &name); ssh_buffer_append_cstrs(&buffer, " next-update = ", name, "\n", NULL); ssh_free(name); } } /* Finished. */ ssh_buffer_append_str(&buffer, "}\n"); return cm_debug_renderer_return(&buffer, buf, len); } return 0; }
SshPacketWrapper ssh_packet_wrap(SshStream down_stream, SshPacketReceiveProc received_packet, SshPacketEofProc received_eof, SshPacketCanSendProc can_send, void *context) { SshPacketWrapper down; down = ssh_xcalloc(1, sizeof(*down)); down->stream = down_stream; ssh_buffer_init(&down->incoming); ssh_buffer_init(&down->outgoing); ssh_buffer_init(&down->outgoing_packet); down->incoming_eof = FALSE; down->outgoing_eof = FALSE; down->send_blocked = TRUE; down->can_receive = FALSE; down->destroy_pending = FALSE; down->cannot_destroy = FALSE; down->destroy_requested = FALSE; down->shortcircuited = FALSE; /* Save the callback functions. */ down->received_packet = received_packet; down->received_eof = received_eof; down->can_send = can_send; down->context = context; /* Set callback for the downward stream. Note that this will also cause can_send to be called from the output callback. */ ssh_stream_set_callback(down->stream, ssh_packet_wrapper_callback, (void *)down); /* Enable receives. */ ssh_packet_wrapper_can_receive(down, TRUE); return down; }
/* Handle the parsing of the single line string. */ static size_t ssh_key_blob_get_line(const unsigned char *buf, size_t len, char **string) { size_t i, step, keep; SshBufferStruct buffer; ssh_buffer_init(&buffer); for (i = 0, step = 0, keep = 0; i < len; i++) { switch (buf[i]) { case '\n': /* End. */ step = i; goto end; case ' ': case '\t': case '\r': if (ssh_buffer_len(&buffer) == 0) { keep = 0; break; } keep = 1; break; default: if (keep) { ssh_xbuffer_append(&buffer, (const unsigned char *)" ", 1); keep = 0; } ssh_xbuffer_append(&buffer, &buf[i], 1); break; } } end: /* Make a string. */ *string = ssh_xmalloc(ssh_buffer_len(&buffer) + 1); memcpy(*string, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); (*string)[ssh_buffer_len(&buffer)] = '\0'; ssh_buffer_uninit(&buffer); return step; }
int ssh_cm_render_mp(unsigned char *buf, int len, int precision, void *datum) { SshMPInteger mpint; char *tmp; SshBufferStruct buffer; mpint = datum; if ((tmp = ssh_mprz_get_str(mpint, 10)) != NULL) { ssh_buffer_init(&buffer); ssh_buffer_append_str(&buffer, tmp); ssh_free(tmp); return cm_debug_renderer_return(&buffer, buf, len); } return 0; }
SshAuditSyslogContext ssh_audit_syslog_create(SshLogFacility facility, SshLogSeverity severity, SshAuditFormatType format) { SshAuditSyslogContext ctx; ctx = ssh_calloc(1, sizeof(*ctx)); if (ctx == NULL) return NULL; ctx->facility = facility; ctx->severity = severity; ctx->format = format; ssh_buffer_init(&ctx->buffer); return ctx; }
void ssh_channel_start_remote_tcp_forward(SshCommon common, const char *address_to_bind, const char *port, const char *connect_to_host, const char *connect_to_port, void (*completion)(Boolean ok, void *context), void *context) { SshRemoteTcpForward fwd; SshBuffer buffer; SshChannelTypeTcpForward ct; SSH_DEBUG(5, ("requesting remote forwarding for port %s", port)); ct = ssh_channel_ftcp_ct(common); /* Create a context for the forwarding. */ fwd = ssh_xcalloc(1, sizeof(*fwd)); fwd->common = common; fwd->address_to_bind = ssh_xstrdup(address_to_bind); fwd->port = ssh_xstrdup(port); fwd->connect_to_host = ssh_xstrdup(connect_to_host); fwd->connect_to_port = ssh_xstrdup(connect_to_port); /* Add it to the list of remote forwardings. */ fwd->next = ct->remote_forwards; ct->remote_forwards = fwd; /* Send a forwarding request to the remote side. */ ssh_buffer_init(&buffer); ssh_encode_buffer(&buffer, SSH_FORMAT_UINT32_STR, address_to_bind, strlen(address_to_bind), SSH_FORMAT_UINT32, (SshUInt32) atol(port), SSH_FORMAT_END); ssh_conn_send_global_request(common->conn, "tcpip-forward", ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer), completion, context); ssh_buffer_uninit(&buffer); }
void ssh_channel_dtcp_open_to_remote(SshCommon common, SshStream stream, const char *connect_to_host, const char *connect_to_port, const char *originator_ip, const char *originator_port) { SshBuffer buffer; SSH_DEBUG(5, ("opening direct TCP/IP connection to %s:%s originator %s:%s", connect_to_host, connect_to_port, originator_ip, originator_port)); /* Register that we have a new channel. */ ssh_common_new_channel(common); /* Format the channel open request in a buffer. */ ssh_buffer_init(&buffer); ssh_encode_buffer(&buffer, SSH_FORMAT_UINT32_STR, connect_to_host, strlen(connect_to_host), SSH_FORMAT_UINT32, (SshUInt32) atol(connect_to_port), SSH_FORMAT_UINT32_STR, originator_ip, strlen(originator_ip), SSH_FORMAT_UINT32, (SshUInt32) atol(originator_port), SSH_FORMAT_END); /* Send the channel open request. */ ssh_conn_send_channel_open(common->conn, "direct-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 *)common, NULL, NULL); ssh_buffer_uninit(&buffer); }
/* Handle the quoted string parsing. */ size_t ssh_key_blob_get_string(const unsigned char *buf, size_t len, char **string) { unsigned int quoting, ret_quoting; SshBufferStruct buffer; size_t step, i, j; ssh_buffer_init(&buffer); for (i = 0, step = 0, quoting = 0, ret_quoting = 0; i < len; i++) { switch (quoting) { case 0: switch (buf[i]) { case ' ': case '\n': case '\r': case '\t': /* Skip! */ break; case '\"': /* " */ quoting = 2; ret_quoting = 0; break; default: /* End! */ step = i; goto end; } break; case 1: if (buf[i] == '\n') { for (j = 0; isspace(buf[i + j]) && i + j < len; j++) ; i = i + j - 1; } quoting = ret_quoting; ret_quoting = 0; break; case 2: switch (buf[i]) { case '\\': quoting = 1; ret_quoting = 2; break; case '\"': /* " */ quoting = 0; ret_quoting = 0; break; default: ssh_xbuffer_append(&buffer, &buf[i], 1); break; } } } end: /* Make a string. */ *string = ssh_xmalloc(ssh_buffer_len(&buffer) + 1); memcpy(*string, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); (*string)[ssh_buffer_len(&buffer)] = '\0'; ssh_buffer_uninit(&buffer); return step; }
int main(int ac, char **av) { unsigned int pass, i; SshBuffer buffer, buffer2; SocksInfo socksinfo, socksreturn; SocksError ret; ssh_buffer_init(&buffer); ssh_buffer_init(&buffer2); for(pass = 0; pass < 20000; pass++) { ssh_buffer_clear(&buffer); socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec)); socksinfo->socks_version_number = 4; socksinfo->command_code = (pass & 1) + 1; socksinfo->ip = ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) / sizeof(ip_numbers[0]))]); socksinfo->port = ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) / sizeof(port_numbers[0]))]); socksinfo->username = ssh_xstrdup(usernames[pass % (sizeof(usernames) / sizeof(usernames[0]))]); if (ssh_socks_client_generate_open(&buffer, socksinfo) != SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_client_generate_open fails"); if (pass & 1) { unsigned char *p; unsigned int len; ssh_buffer_clear(&buffer2); p = ssh_buffer_ptr(&buffer); len = ssh_buffer_len(&buffer); /* Give partial buffer */ for(i = 0; i + 1 < len; i++) { ssh_buffer_append(&buffer2, p + i, 1); if (ssh_socks_server_parse_open(&buffer2, &socksreturn) != SSH_SOCKS_TRY_AGAIN) ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)"); } ssh_buffer_append(&buffer2, p + i, 1); if (ssh_socks_server_parse_open(&buffer2, &socksreturn) != SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)"); if (ssh_buffer_len(&buffer2) != 0) ssh_fatal("Junk left to buffer after server_parse_open"); } else { if (ssh_socks_server_parse_open(&buffer, &socksreturn) != SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_server_parse_open fails for partial data (should return success)"); if (ssh_buffer_len(&buffer) != 0) ssh_fatal("Junk left to buffer after server_parse_open"); } if (socksinfo->socks_version_number != socksreturn->socks_version_number) ssh_fatal("socks_version_numbers differ request"); if (socksinfo->command_code != socksreturn->command_code) ssh_fatal("command_codes differ request"); if (strcmp(socksinfo->ip, socksreturn->ip) != 0) ssh_fatal("ip numbers differ request"); if (strcmp(socksinfo->port, socksreturn->port) != 0) ssh_fatal("port numbers differ request"); if (strcmp(socksinfo->username, socksreturn->username) != 0) ssh_fatal("usernames differ request"); ssh_socks_free(&socksreturn); ssh_socks_free(&socksinfo); ssh_buffer_clear(&buffer); socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec)); socksinfo->socks_version_number = 0; socksinfo->command_code = (pass % 4) + 90; socksinfo->ip = ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) / sizeof(ip_numbers[0]))]); socksinfo->port = ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) / sizeof(port_numbers[0]))]); socksinfo->username = ssh_xstrdup(usernames[pass % (sizeof(usernames) / sizeof(usernames[0]))]); if (ssh_socks_server_generate_reply(&buffer, socksinfo) != SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_server_generate_reply fails"); if (pass & 1) { unsigned char *p; unsigned int len; ssh_buffer_clear(&buffer2); p = ssh_buffer_ptr(&buffer); len = ssh_buffer_len(&buffer); /* Give partial buffer */ for(i = 0; i + 1 < len; i++) { ssh_buffer_append(&buffer2, p + i, 1); if (ssh_socks_client_parse_reply(&buffer2, &socksreturn) != SSH_SOCKS_TRY_AGAIN) ssh_fatal("ssh_socks_server_parse_open fails in partial data (should return try_again)"); } ssh_buffer_append(&buffer2, p + i, 1); ret = ssh_socks_client_parse_reply(&buffer2, &socksreturn); if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) || ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) || ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) || ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME)) ssh_fatal("ssh_socks_client_parse_reply fails for partial data"); if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer2) != 0) ssh_fatal("Junk left to buffer after server_parse_open"); } else { ret = ssh_socks_client_parse_reply(&buffer, &socksreturn); if (((pass % 4) == 0 && ret != SSH_SOCKS_SUCCESS) || ((pass % 4) == 1 && ret != SSH_SOCKS_FAILED_REQUEST) || ((pass % 4) == 2 && ret != SSH_SOCKS_FAILED_IDENTD) || ((pass % 4) == 3 && ret != SSH_SOCKS_FAILED_USERNAME)) ssh_fatal("ssh_socks_client_parse_reply fails"); if (ret == SSH_SOCKS_SUCCESS && ssh_buffer_len(&buffer) != 0) ssh_fatal("Junk left to buffer after server_parse_open"); } if (ret == SSH_SOCKS_SUCCESS) { if (socksinfo->socks_version_number != socksreturn->socks_version_number) ssh_fatal("socks_version_numbers differ reply"); if (socksinfo->command_code != socksreturn->command_code) ssh_fatal("command_codes differ reply"); if (strcmp(socksinfo->ip, socksreturn->ip) != 0) ssh_fatal("ip numbers differ reply"); if (strcmp(socksinfo->port, socksreturn->port) != 0) ssh_fatal("port numbers differ reply"); ssh_socks_free(&socksreturn); } ssh_socks_free(&socksinfo); } ssh_buffer_clear(&buffer); for(pass = 0; pass < (sizeof(ip_invalid_numbers) / sizeof(ip_invalid_numbers[0])); pass++) { socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec)); socksinfo->socks_version_number = 4; socksinfo->command_code = (pass & 1) + 1; socksinfo->ip = ssh_xstrdup(ip_invalid_numbers[pass % (sizeof(ip_invalid_numbers) / sizeof(ip_invalid_numbers[0]))]); socksinfo->port = ssh_xstrdup(port_numbers[pass % (sizeof(port_numbers) / sizeof(port_numbers[0]))]); socksinfo->username = ssh_xstrdup(usernames[pass % (sizeof(usernames) / sizeof(usernames[0]))]); if (ssh_socks_client_generate_open(&buffer, socksinfo) == SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_client_generate_open success (should fail, ip)"); socksinfo->socks_version_number = 0; socksinfo->command_code = (pass % 4) + 90; if (ssh_socks_server_generate_reply(&buffer, socksinfo) == SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_server_generate_reply success (should fail, ip)"); ssh_socks_free(&socksinfo); } for(pass = 0; pass < (sizeof(port_invalid_numbers) / sizeof(port_invalid_numbers[0])); pass++) { socksinfo = ssh_xmalloc(sizeof(struct SocksInfoRec)); socksinfo->socks_version_number = 4; socksinfo->command_code = (pass & 1) + 1; socksinfo->ip = ssh_xstrdup(ip_numbers[pass % (sizeof(ip_numbers) / sizeof(ip_numbers[0]))]); socksinfo->port = ssh_xstrdup(port_invalid_numbers[pass % (sizeof(port_invalid_numbers) / sizeof(port_invalid_numbers[0]))]); socksinfo->username = ssh_xstrdup(usernames[pass % (sizeof(usernames) / sizeof(usernames[0]))]); if (ssh_socks_client_generate_open(&buffer, socksinfo) == SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_client_generate_open success (should fail, port)"); socksinfo->command_code = (pass % 4) + 90; socksinfo->socks_version_number = 0; if (ssh_socks_server_generate_reply(&buffer, socksinfo) == SSH_SOCKS_SUCCESS) ssh_fatal("ssh_socks_server_generate_reply success (should fail, port)"); ssh_socks_free(&socksinfo); } if (ssh_buffer_len(&buffer) != 0) ssh_fatal("some of the failed ssh_socks_*_generate_* function wrote something to buffer, size != 0"); ssh_buffer_uninit(&buffer); ssh_buffer_uninit(&buffer2); return 0; }
void ssh_virtual_adapter_configure(SshInterceptor interceptor, SshInterceptorIfnum adapter_ifnum, SshVirtualAdapterState adapter_state, SshUInt32 num_addresses, SshIpAddr addresses, SshVirtualAdapterParams params, SshVirtualAdapterStatusCB callback, void *context) { SshInterceptorVirtualAdapter va; SshInterceptorVirtualAdapterOp op; SshBufferStruct ip_buffer; unsigned char *param_ptr; size_t param_len; SshUInt32 i; SshVirtualAdapterError error = SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR; SshIpAddrStruct undefined_ip; ssh_buffer_init(&ip_buffer); /* Assert that this virtual adapter exists. */ ssh_mutex_lock(interceptor->mutex); for (va = interceptor->virtual_adapters; va; va = va->next) if (va->adapter_ifnum == adapter_ifnum) break; ssh_mutex_unlock(interceptor->mutex); SSH_ASSERT(va != NULL); /* Encode "clear all addresses" as one undefined address. */ if (num_addresses == 0 && addresses != NULL) { SSH_IP_UNDEFINE(&undefined_ip); addresses = &undefined_ip; num_addresses = 1; } /* Encode IP addresses. */ for (i = 0; i < num_addresses; i++) { if (!ssh_encode_ipaddr_buffer(&ip_buffer, &addresses[i])) { error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE; goto error; } } /* Encode params. */ param_ptr = NULL; param_len = 0; if (params) { if (!ssh_virtual_adapter_param_encode(params, ¶m_ptr, ¶m_len)) { error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE; goto error; } } /* Initialize an operation handle. */ op = alloc_virtual_adapter_op(interceptor); op->status_cb = callback; op->context = context; SSH_DEBUG(SSH_D_NICETOKNOW, ("sending configure request for virtual adapter %d to forwarder.", (int) adapter_ifnum)); /* Send a message to the kernel forwarder module. */ ssh_usermode_interceptor_send_encode( interceptor, SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_CONFIGURE, SSH_FORMAT_UINT32, op->id, SSH_FORMAT_UINT32, adapter_ifnum, SSH_FORMAT_UINT32, adapter_state, SSH_FORMAT_UINT32, num_addresses, SSH_FORMAT_UINT32_STR, ssh_buffer_ptr(&ip_buffer), ssh_buffer_len(&ip_buffer), SSH_FORMAT_UINT32_STR, param_ptr, param_len, SSH_FORMAT_END); op->handle = ssh_operation_register(virtual_adapter_operation_abort, op); ssh_buffer_uninit(&ip_buffer); ssh_free(param_ptr); return; error: ssh_buffer_uninit(&ip_buffer); ssh_free(param_ptr); (*callback)(error, adapter_ifnum, NULL, SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED, NULL, context); }
Boolean ssh_pgp_read_packet(SshFileBuffer *filebuf, SshPgpPacket *packet) { unsigned char type_id; int packet_type; int i; size_t l; Boolean fr; Boolean partial_body; SshPgpPacket newpacket; SshBuffer partial_buf; Boolean partial_buf_init; partial_buf_init = FALSE; do { fr = ssh_file_buffer_expand(filebuf, 1); if (fr == FALSE) goto failed; type_id = *(ssh_buffer_ptr(&(filebuf->buf))); ssh_buffer_consume(&(filebuf->buf), 1); SSH_DEBUG(5, ("type_id = %d\n", type_id)); if (type_id & 0x40) { /* New packet header format */ SSH_DEBUG(5, ("New packet header format\n")); if (partial_buf_init == FALSE) packet_type = type_id & 0x7f; fr = ssh_file_buffer_expand(filebuf, 1); if (fr == FALSE) goto failed; l = *(ssh_buffer_ptr(&(filebuf->buf))); ssh_buffer_consume(&(filebuf->buf), 1); if ((l >= 192) && (l <= 223)) { partial_body = FALSE; fr = ssh_file_buffer_expand(filebuf, 1); if (fr == FALSE) goto failed; l = (((l - 192) << 8) + ((size_t)(*(ssh_buffer_ptr(&(filebuf->buf))))) + 192); ssh_buffer_consume(&(filebuf->buf), 1); } else if ((l >= 224) && (l <= 254)) { partial_body = TRUE; fr = ssh_file_buffer_expand(filebuf, 1); if (fr == FALSE) goto failed; l = ((size_t)1) << ((*(ssh_buffer_ptr(&(filebuf->buf)))) & 0x1f); ssh_buffer_consume(&(filebuf->buf), 1); if (partial_buf_init == FALSE) { ssh_buffer_init(&partial_buf); partial_buf_init = TRUE; } } else if (l == 255) { partial_body = FALSE; l = 0; fr = ssh_file_buffer_expand(filebuf, 4); if (fr == FALSE) goto failed; for (i = 0; i < 4; i++) { l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf)))); ssh_buffer_consume(&(filebuf->buf), 1); } } else { partial_body = FALSE; } } else { size_t ll; /* Old packet header format */ SSH_DEBUG(5, ("Old packet header format\n")); partial_body = FALSE; if (partial_buf_init == FALSE) packet_type = (type_id & 0x7c) >> 2; ll = ((int)1) << (type_id & 0x03); fr = ssh_file_buffer_expand(filebuf, (int)ll); if (fr == FALSE) goto failed; l = 0; for (i = 0; i < ll; i++) { l = (l << 8) + (*(ssh_buffer_ptr(&(filebuf->buf)))); ssh_buffer_consume(&(filebuf->buf), 1); } } if ((l < 1) || (l > 0x4000)) /* XXX */ goto failed; fr = ssh_file_buffer_expand(filebuf, l); if (fr == FALSE) goto failed; if (partial_body == FALSE) { if (packet != NULL) { newpacket = ssh_xmalloc(sizeof (struct SshPgpPacketRec)); newpacket->type = packet_type; if (partial_buf_init) { newpacket->len = l + ssh_buffer_len(&partial_buf); newpacket->data = ssh_xmalloc(newpacket->len); memcpy(newpacket->data, ssh_buffer_ptr(&partial_buf), ssh_buffer_len(&partial_buf)); memcpy(&(newpacket->data[ssh_buffer_len(&partial_buf)]), ssh_buffer_ptr(&(filebuf->buf)), l); ssh_buffer_uninit(&partial_buf); partial_buf_init = FALSE; } else { newpacket->len = l; newpacket->data = ssh_xmalloc(l); memcpy(newpacket->data, ssh_buffer_ptr(&(filebuf->buf)), l); } *packet = newpacket; ssh_buffer_consume(&(filebuf->buf), l); } } else { ssh_buffer_append(&partial_buf, ssh_buffer_ptr(&(filebuf->buf)), l); ssh_buffer_consume(&(filebuf->buf), l); } } while (partial_body == TRUE); return TRUE; failed: if (partial_buf_init == TRUE) ssh_buffer_uninit(&partial_buf); return FALSE; }
int main(int ac, char **av) { char port[100]; int i; TestCase *testcase; int pass; SshTime time_now; time_now = ssh_time(); srandom(time_now); for (pass = 0; pass < PASSES; pass++) { #ifdef DEBUG ssh_debug("pass %d", pass); #endif random_state = ssh_random_allocate(); /* randomize it a bit */ ssh_random_add_noise(random_state, &time_now, sizeof(time_now)); ssh_buffer_init(&testdata); for (i = 0; i < 100000; i++) buffer_put_char(&testdata, ssh_random_get_byte(random_state)); ssh_event_loop_initialize(); for (i = 0; tests[i].name; i++) { testcase = &tests[i]; end_of_script_count = 0; #ifdef DEBUG ssh_debug("Running test %s", testcase->name); #endif snprintf(port, sizeof(port), "%d", (int)(35000 + random() % 1000)); #ifdef DEBUG ssh_debug("Making listener, port %s...", port); #endif listener = ssh_tcp_make_listener("127.0.0.1", port, listener_callback, (void *)testcase); if (!listener) ssh_fatal("making listener failed"); #ifdef DEBUG ssh_debug("Making connect..."); #endif ssh_tcp_connect_with_socks("127.0.0.1", port, NULL, 2, connect_callback, (void *)testcase); #ifdef DEBUG ssh_debug("Event loop running..."); #endif ssh_event_loop_run(); #ifdef DEBUG ssh_debug("Event loop exited..."); #endif if (end_of_script_count != 2) ssh_fatal("end_of_script_count %d, script end not reached.", end_of_script_count); /* Listener was destroyed in callback. */ } ssh_event_loop_uninitialize(); ssh_buffer_uninit(&testdata); ssh_random_free(random_state); } #ifdef DEBUG ssh_debug("Exiting..."); #endif return 0; }
void ssh_decode_tty_flags(int fd, unsigned char *buf, size_t buf_len) { SshBuffer buffer; #ifdef USING_TERMIOS struct termios tio; #endif /* USING_TERMIOS */ #ifdef USING_SGTTY struct sgttyb tio; struct tchars tiotc; struct ltchars tioltc; int tiolm; #ifdef TIOCGSTAT struct tstatus tiots; #endif /* TIOCGSTAT */ #endif int opcode, baud; if (!isatty(fd)) { SSH_TRACE(2, ("Not a tty. (fd = %d)", fd)); return; } if (buf_len == 0) return; SSH_DEBUG_HEXDUMP(5, ("received tty-flags buffer"), buf, buf_len); ssh_buffer_init(&buffer); ssh_buffer_append(&buffer, buf, buf_len); /* Get old attributes for the terminal. We will modify these flags. I am hoping that if there are any machine-specific modes, they will initially have reasonable values. */ #ifdef USING_TERMIOS if (tcgetattr(fd, &tio) < 0) return; #endif /* USING_TERMIOS */ #ifdef USING_SGTTY if (ioctl(fd, TIOCGETP, &tio) < 0) return; if (ioctl(fd, TIOCGETC, &tiotc) < 0) return; if (ioctl(fd, TIOCLGET, &tiolm) < 0) return; if (ioctl(fd, TIOCGLTC, &tioltc) < 0) return; #ifdef TIOCGSTAT if (ioctl(fd, TIOCGSTAT, &tiots) < 0) return; #endif /* TIOCGSTAT */ #endif /* USING_SGTTY */ for (;;) { ssh_decode_buffer(&buffer, SSH_FORMAT_CHAR, &opcode, SSH_FORMAT_END); switch(opcode) { case TTY_OP_END: goto set; case TTY_OP_ISPEED: baud = GET_UINT32(); if (cfsetispeed(&tio, baud_to_speed(baud)) < 0) ssh_warning("cfsetispeed failed for %d", baud); break; case TTY_OP_OSPEED: baud = GET_UINT32(); if (cfsetospeed(&tio, baud_to_speed(baud)) < 0) ssh_warning("cfsetospeed failed for %d", baud); break; #ifdef USING_TERMIOS #define TTYCHAR(NAME, OP) \ case OP: \ tio.c_cc[NAME] = GET_UINT32(); \ break; #define TTYMODE(NAME, FIELD, OP) \ case OP: \ if (GET_UINT32()) \ tio.FIELD |= NAME; \ else \ tio.FIELD &= ~NAME; \ break; #define SGTTYCHAR(NAME, OP) #define SGTTYMODE(NAME, FIELD, OP) #define SGTTYMODEN(NAME, FIELD, OP) #endif /* USING_TERMIOS */ #ifdef USING_SGTTY #define TTYCHAR(NAME, OP) #define TTYMODE(NAME, FIELD, OP) #define SGTTYCHAR(NAME, OP) \ case OP: \ NAME = GET_UINT32(); \ break; #define SGTTYMODE(NAME, FIELD, OP) \ case OP: \ if (GET_UINT32()) \ FIELD |= NAME; \ else \ FIELD &= ~NAME; \ break; #define SGTTYMODEN(NAME, FIELD, OP) \ case OP: \ if (GET_UINT32()) \ FIELD &= ~NAME; \ else \ FIELD |= NAME; \ break; #endif /* USING_SGTTY */ #include "sshttyflagsi.h" #undef TTYCHAR #undef TTYMODE #undef SGTTYCHAR #undef SGTTYMODE #undef SGTTYMODEN default: SSH_TRACE(1, ("Ignoring unsupported tty mode opcode %d (0x%x)", opcode, opcode)); /* Opcodes 0 to 160 are defined to have a uint32 argument. */ if (opcode >= 0 && opcode < 160) { (void)GET_UINT32(); break; } /* It is a truly undefined opcode (160 to 255). We have no idea about its arguments. So we must stop parsing. Note that some data may be left in the packet; hopefully there is nothing more coming after the mode data. */ ssh_warning("ssh_decode_tty_flags: unknown opcode %d", opcode); goto set; } } set: /* Set the new modes for the terminal. */ #ifdef USING_TERMIOS if (tcsetattr(fd, TCSANOW, &tio) < 0) ssh_warning("Setting tty modes failed: %.100s", strerror(errno)); #endif /* USING_TERMIOS */ #ifdef USING_SGTTY /* termio's ECHOE is really both LCRTBS and LCRTERA - so wire them together */ if (tiolm & LCRTERA) tiolm |= LCRTBS; if (ioctl(fd, TIOCSETP, &tio) < 0 || ioctl(fd, TIOCSETC, &tiotc) < 0 || ioctl(fd, TIOCLSET, &tiolm) < 0 || ioctl(fd, TIOCSLTC, &tioltc) < 0 #ifdef TIOCSSTAT || ioctl(fd, TIOCSSTAT, &tiots) < 0 #endif /* TIOCSSTAT */ ) ssh_warning("Setting tty modes failed: %.100s", strerror(errno)); #endif /* USING_SGTTY */ }
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); }
int ssh_cm_render_certificate(unsigned char *buf, int len, int precision, void *datum) { SshX509Certificate cert = datum; char *name; unsigned char *t; SshX509Name names; SshMPIntegerStruct mp; SshBerTimeStruct not_before, not_after; SshBufferStruct buffer; SshX509OidList oid_list; const SshOidStruct *oids; Boolean critical; SshStr str; size_t l, kid_len; SshPublicKey pub; unsigned char *kid; if (cert) { ssh_buffer_init(&buffer); ssh_buffer_append_str(&buffer, "\ncertificate = { \n"); /* Add the serial number. */ ssh_mprz_init(&mp); if (ssh_x509_cert_get_serial_number(cert, &mp) == FALSE) { ssh_buffer_append_str(&buffer, " missing-serial-number\n"); } else { if ((t = (unsigned char *) ssh_mprz_get_str(&mp, 10)) != NULL) { ssh_buffer_append_cstrs(&buffer, " serial-number = ", t, "\n", NULL); ssh_mprz_clear(&mp); ssh_free(t); } else { ssh_mprz_clear(&mp); ssh_buffer_uninit(&buffer); return -1; } } /* Add suitable names. */ ssh_x509_name_reset(cert->subject_name); if (!ssh_x509_cert_get_subject_name_str(cert, &str)) { ssh_buffer_append_str(&buffer, " missing-subject-name\n"); } else { SshStr latin1 = ssh_str_charset_convert(str, SSH_CHARSET_ISO_8859_1); name = (char *)ssh_str_get(latin1, &l); ssh_buffer_append_cstrs(&buffer, " subject-name = <", name, ">\n", NULL); ssh_str_free(latin1); ssh_free(name); ssh_str_free(str); } ssh_x509_name_reset(cert->issuer_name); if (!ssh_x509_cert_get_issuer_name(cert, &name)) { ssh_buffer_append_str(&buffer, " missing-issuer-name\n"); } else { ssh_buffer_append_cstrs(&buffer, " issuer-name = <", name, ">\n", NULL); ssh_free(name); } /* Validity period. */ if (!ssh_x509_cert_get_validity(cert, ¬_before, ¬_after)) { ssh_buffer_append_str(&buffer, " missing-validity-period\n"); } else { if ((t = ssh_malloc(64)) != NULL) { if (ssh_ber_time_available(¬_before)) { ssh_snprintf(t, 64, "%@", ssh_ber_time_render, ¬_before); ssh_buffer_append_cstrs(&buffer, " not-before = ", t, "\n", NULL); } if (ssh_ber_time_available(¬_after)) { ssh_snprintf(t, 64, "%@", ssh_ber_time_render, ¬_after); ssh_buffer_append_cstrs(&buffer, " not-after = ", t, "\n", NULL); } ssh_free(t); } } if (ssh_x509_cert_get_subject_key_id(cert, &kid, &kid_len, &critical)) { unsigned char *fingerprint; if ((fingerprint = (unsigned char *) ssh_fingerprint(kid, kid_len, SSH_FINGERPRINT_HEX_UPPER)) != NULL) ssh_buffer_append_cstrs(&buffer, " subject-kid = ", fingerprint, "\n", NULL); ssh_free(fingerprint); } if (ssh_x509_cert_get_public_key(cert, &pub)) { unsigned char *key_digest; size_t digest_len; if (ssh_cm_key_kid_create(pub, FALSE, &key_digest, &digest_len)) { unsigned char *fingerprint; fingerprint = (unsigned char *)ssh_fingerprint(key_digest, digest_len, SSH_FINGERPRINT_HEX_UPPER); if (fingerprint) { ssh_buffer_append_cstrs(&buffer, " pubkey-hash = ", ssh_sstr(fingerprint), "\n", NULL); } ssh_free(fingerprint); ssh_free(key_digest); } ssh_public_key_free(pub); } /* Some alternate names. */ if (ssh_x509_cert_get_subject_alternative_names(cert, &names, &critical)) { ssh_x509_name_reset(names); ssh_buffer_append_str(&buffer, " subject-alt-names = { \n"); ssh_cm_names_dump(&buffer, names); ssh_buffer_append_str(&buffer, " }\n"); } if (ssh_x509_cert_get_issuer_alternative_names(cert, &names, &critical)) { ssh_x509_name_reset(names); ssh_buffer_append_str(&buffer, " issuer-alt-names = { \n"); ssh_cm_names_dump(&buffer, names); ssh_buffer_append_str(&buffer, " }\n"); } if (ssh_x509_cert_get_ext_key_usage(cert, &oid_list, &critical)) { ssh_buffer_append_str(&buffer, " extended-key-usage = { \n"); while (oid_list != NULL) { oids = ssh_oid_find_by_oid_of_type(ssh_custr(oid_list->oid), SSH_OID_EXT_KEY_USAGE); if (oids == NULL) ssh_buffer_append_cstrs(&buffer, " (", oid_list->oid, ")\n", NULL); else ssh_buffer_append_cstrs(&buffer, " ", oids->std_name, " (", oid_list->oid, ")\n", NULL); oid_list = oid_list->next; } ssh_buffer_append_str(&buffer, " }\n"); } ssh_buffer_append_str(&buffer, "}\n"); return cm_debug_renderer_return(&buffer, buf, len); } return 0; }
Boolean handler_output(Handler c) { SshBuffer buffer; unsigned int len; const unsigned char *cp; Boolean wake_up_input = FALSE; for (;; c->script++) { #ifdef DEBUG ssh_debug("%s: handler_output: %s", c->side, opnames[c->script->op]); #endif switch (c->script->op) { case OP_EXPECT_SERVICE_REQUEST: case OP_EXPECT_DISCONNECT: case OP_EXPECT_EOF: case OP_EXPECT_STARTUP: case OP_EXPECT_ALGORITHMS: case OP_EXPECT_PACKET: case OP_EXPECT_TEST_STREAM: wake_up_input = TRUE; goto out; case OP_SEND_SERVICE_ACCEPT: handler_send_cross(c, SSH_CROSS_SERVICE_ACCEPT, NULL, 0); break; case OP_SEND_REKEY_REQUEST: ssh_buffer_init(&buffer); store_delimited_strings(&buffer, c->script->arg); handler_send_cross(c, SSH_CROSS_REKEY_REQUEST, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); ssh_buffer_uninit(&buffer); break; case OP_SEND_PACKET: ssh_buffer_init(&buffer); buffer_put_char(&buffer, atoi(c->script->arg)); handler_send_cross(c, SSH_CROSS_PACKET, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); ssh_buffer_uninit(&buffer); break; case OP_SEND_TEST_STREAM: while (c->stream_offset < ssh_buffer_len(&testdata)) { if (ssh_buffer_len(&c->outgoing) > XMALLOC_MAX_SIZE - SSH_MAX_PAYLOAD_LENGTH - 5000 || ssh_buffer_len(&c->outgoing) > 50000 - SSH_MAX_PAYLOAD_LENGTH) if (!handler_output_outgoing(c)) goto out; len = random() % (SSH_MAX_PAYLOAD_LENGTH - 3); if (len > ssh_buffer_len(&testdata) - c->stream_offset) len = ssh_buffer_len(&testdata) - c->stream_offset; ssh_buffer_init(&buffer); buffer_put_char(&buffer, atoi(c->script->arg)); cp = ssh_buffer_ptr(&testdata); ssh_buffer_append(&buffer, cp + c->stream_offset, len); c->stream_offset += len; handler_send_cross(c, SSH_CROSS_PACKET, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); ssh_buffer_uninit(&buffer); } c->stream_offset = 0; break; case OP_SEND_DISCONNECT: ssh_buffer_init(&buffer); buffer_put_boolean(&buffer, TRUE); buffer_put_int(&buffer, SSH_DISCONNECT_BY_APPLICATION); buffer_put_uint32_string(&buffer, c->script->arg, strlen(c->script->arg)); buffer_put_uint32_string(&buffer, "", 0); handler_send_cross(c, SSH_CROSS_DISCONNECT, ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer)); ssh_buffer_uninit(&buffer); break; case OP_SEND_EOF: c->outgoing_eof = TRUE; break; case OP_END: goto out; default: ssh_fatal("%s: handler_output: unknown op %d", c->side, (int)c->script->op); } } out: c->output_blocked = handler_output_outgoing(c); return wake_up_input; }
/* Encodes terminal modes for the terminal referenced by fd in a portable manner, and appends the modes to a buffer being constructed. Stores constructed buffers len to buf_len. This call always succeeds, but if an error happens during encoding, buf will be empty and buf_len will be 0 */ void ssh_encode_tty_flags(int fd, unsigned char **buf, size_t *buf_len) /*void tty_make_modes(int fd)*/ { SshBuffer buffer; #ifdef USING_TERMIOS struct termios tio; #endif #ifdef USING_SGTTY struct sgttyb tio; struct tchars tiotc; struct ltchars tioltc; int tiolm; #ifdef TIOCGSTAT struct tstatus tiots; #endif /* TIOCGSTAT */ #endif /* USING_SGTTY */ int baud; if (!isatty(fd)) { SSH_TRACE(2, ("Not a tty. (fd = %d)", fd)); *buf = ssh_xstrdup(""); *buf_len = 0; return; } ssh_buffer_init(&buffer); /* Get the modes. */ #ifdef USING_TERMIOS if (tcgetattr(fd, &tio) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("tcgetattr: %.100s", strerror(errno)); goto error; } #endif /* USING_TERMIOS */ #ifdef USING_SGTTY if (ioctl(fd, TIOCGETP, &tio) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("ioctl(fd, TIOCGETP, ...): %.100s", strerror(errno)); goto error; } if (ioctl(fd, TIOCGETC, &tiotc) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("ioctl(fd, TIOCGETC, ...): %.100s", strerror(errno)); goto error; } if (ioctl(fd, TIOCLGET, &tiolm) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("ioctl(fd, TIOCLGET, ...): %.100s", strerror(errno)); goto error; } if (ioctl(fd, TIOCGLTC, &tioltc) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("ioctl(fd, TIOCGLTC, ...): %.100s", strerror(errno)); goto error; } #ifdef TIOCGSTAT if (ioctl(fd, TIOCGSTAT, &tiots) < 0) { PUT_CHAR(TTY_OP_END); ssh_warning("ioctl(fd, TIOCGSTAT, ...): %.100s", strerror(errno)); goto error; } #endif /* TIOCGSTAT */ /* termio's ECHOE is really both LCRTBS and LCRTERA - so wire them together */ if (tiolm & LCRTBS) tiolm |= LCRTERA; #endif /* USING_SGTTY */ /* Store input and output baud rates. */ baud = speed_to_baud(cfgetospeed(&tio)); PUT_CHAR(TTY_OP_OSPEED); PUT_UINT32(baud); baud = speed_to_baud(cfgetispeed(&tio)); PUT_CHAR(TTY_OP_ISPEED); PUT_UINT32(baud); /* Store values of mode flags. */ #ifdef USING_TERMIOS #define TTYCHAR(NAME, OP) \ PUT_CHAR(OP); PUT_UINT32(tio.c_cc[NAME]); #define TTYMODE(NAME, FIELD, OP) \ PUT_CHAR(OP); PUT_UINT32((tio.FIELD & NAME) != 0); #define SGTTYCHAR(NAME, OP) #define SGTTYMODE(NAME, FIELD, OP) #define SGTTYMODEN(NAME, FIELD, OP) #endif /* USING_TERMIOS */ #ifdef USING_SGTTY #define TTYCHAR(NAME, OP) #define TTYMODE(NAME, FIELD, OP) #define SGTTYCHAR(NAME, OP) \ PUT_CHAR(OP); PUT_UINT32(NAME); #define SGTTYMODE(NAME, FIELD, OP) \ PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) != 0); #define SGTTYMODEN(NAME, FIELD, OP) \ PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) == 0); #endif /* USING_SGTTY */ #include "sshttyflagsi.h" #undef TTYCHAR #undef TTYMODE #undef SGTTYCHAR #undef SGTTYMODE #undef SGTTYMODEN /* Mark end of mode data. */ PUT_CHAR(TTY_OP_END); *buf_len = ssh_buffer_len(&buffer); *buf = ssh_xmemdup(ssh_buffer_ptr(&buffer), *buf_len); ssh_buffer_uninit(&buffer); SSH_DEBUG_HEXDUMP(5, ("encoded tty-flags buffer"), *buf, *buf_len); return; error: ssh_buffer_uninit(&buffer); *buf = ssh_xstrdup(""); *buf_len = 0; }