int ssh_pipe_stream_write(void *context, const unsigned char *buf, size_t size) { SshPipeStream pipes = (SshPipeStream)context; return ssh_stream_write(pipes->stdio_stream, buf, size); }
Boolean handler_output_outgoing(Handler c) { int len; #ifdef DEBUG ssh_debug("handler_output_outgoing"); #endif #ifdef DUMP_PACKETS buffer_dump(&c->outgoing); #endif while (ssh_buffer_len(&c->outgoing) > 0) { len = ssh_buffer_len(&c->outgoing); len = ssh_stream_write(c->stream, ssh_buffer_ptr(&c->outgoing), len); if (len == 0) ssh_fatal("%s: handler_output: error writing to stream", c->side); if (len < 0) return FALSE; ssh_buffer_consume(&c->outgoing, len); } if (c->outgoing_eof) ssh_stream_output_eof(c->stream); return TRUE; }
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); }
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"); } } }
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 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(); }
Boolean ssh_packet_wrapper_output(SshPacketWrapper down) { int len; Boolean return_value = FALSE; /* Loop while we have data to output. When all data has been sent, we check whether we need to send EOF. */ while (ssh_buffer_len(&down->outgoing) > 0) { /* Write as much data as possible. */ len = ssh_stream_write(down->stream, ssh_buffer_ptr(&down->outgoing), ssh_buffer_len(&down->outgoing)); if (len < 0) return return_value; /* Cannot write more now. */ if (len == 0) { /* EOF on output; will not be able to write any more. */ down->outgoing_eof = TRUE; ssh_buffer_clear(&down->outgoing); return TRUE; } /* Consume written data. */ ssh_buffer_consume(&down->outgoing, len); /* We've done something, so return TRUE. */ return_value = TRUE; } /* All output has drained. There is no more buffered data. */ if (down->send_blocked) { down->cannot_destroy = TRUE; if (down->can_send) (*down->can_send)(down->context); down->cannot_destroy = FALSE; if (down->destroy_requested) { ssh_packet_wrapper_destroy(down); return FALSE; } down->send_blocked = FALSE; } /* If we should send EOF after output has drained, do it now. */ if (down->outgoing_eof) ssh_stream_output_eof(down->stream); /* If we get here and the stream is shortcircuited, that means we had output data to drain before shortcircuiting. */ if (down->shortcircuit_up_stream && !down->shortcircuited) { down->shortcircuited = TRUE; ssh_packet_impl_shortcircuit_now(down->shortcircuit_up_stream, down->stream); } /* If there's a destroy pending (that is, waiting for buffers to drain), do the destroy now. */ if (down->destroy_pending) { /* Destroy the context now. This also closes the stream. */ ssh_packet_wrapper_destroy_now(down); /* Return FALSE to ensure that the loop in ssh_packet_wrapper_callback exits without looking at the context again. */ return FALSE; } return return_value; }
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; } }
int ssh_packet_impl_write(void *context, const unsigned char *buf, size_t size) { SshPacketImpl up = (SshPacketImpl)context; size_t offset, payload_len, len; unsigned char *ucp; /* If shortcircuiting, direct the write down. */ if (up->shortcircuit_stream) { SSH_ASSERT(ssh_buffer_len(&up->incoming) == 0); return ssh_stream_write(up->shortcircuit_stream, buf, size); } offset = 0; normal: while (up->can_receive && !up->incoming_eof && offset < size && !up->shortcircuit_stream) { /* If already processing a partial packet, continue it now. */ if (ssh_buffer_len(&up->incoming) > 0) goto partial; /* If only partial packet available, do special proccessing. */ if (size - offset < 4) goto partial; /* Need partial packet processing. */ payload_len = SSH_GET_32BIT(buf + offset); if (payload_len < 1) goto partial; if (size - offset < 4 + payload_len) goto partial; /* Need partial packet processing. */ /* The entire packet is available; pass it to the callback. */ if (up->received_packet) (*up->received_packet)((SshPacketType)buf[offset + 4], buf + offset + 5, payload_len - 1, up->context); offset += 4 + payload_len; } /* We cannot take more data now. If we processed some data, return the number of bytes processed. */ if (offset > 0) return offset; /* We couldn't take any data. Remember that we have returned error to the writer and must call the callback later. */ up->up_write_blocked = TRUE; return -1; partial: /* Process partial packet. First we read its header. */ len = ssh_buffer_len(&up->incoming); if (len < 4) { len = 4 - len; if (size - offset < len) len = size - offset; if (ssh_buffer_append(&up->incoming, buf + offset, len) != SSH_BUFFER_OK) { (*up->received_eof)(up->context); return 0; } offset += len; } if (ssh_buffer_len(&up->incoming) < 4) return offset; /* Get the length of the packet. */ ucp = ssh_buffer_ptr(&up->incoming); payload_len = SSH_GET_32BIT(ucp); if (payload_len < 1) { /* Received an invalid packet with length = 0, even though we should always have at least the packet type. */ (*up->received_eof)(up->context); return 0; } /* Add remaining data in the packet to the buffer. */ len = 4 + payload_len - ssh_buffer_len(&up->incoming); if (len > size - offset) len = size - offset; if (ssh_buffer_append(&up->incoming, buf + offset, len) != SSH_BUFFER_OK) { (*up->received_eof)(up->context); return 0; } offset += len; /* If some data still not available, return. */ if (ssh_buffer_len(&up->incoming) < 4 + payload_len) return offset; /* The entire packet is now in buffer. */ ucp = ssh_buffer_ptr(&up->incoming); if (up->received_packet) (*up->received_packet)((SshPacketType)ucp[4], ucp + 5, payload_len - 1, up->context); /* Clear the incoming partial packet buffer and resume normal processing. */ ssh_buffer_clear(&up->incoming); goto normal; }