void decode_case_int(SshEncodingFormat fmt, unsigned int value) { SshUInt16 lv16; SshUInt32 lv32; size_t bytes; bytes = ssh_buffer_len(buffer); if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), fmt, NULL, SSH_FORMAT_END)) ssh_fatal("decode_case_int: NULL decode bad len"); if (fmt == SSH_FORMAT_UINT32) { if (bytes != ssh_decode_buffer(buffer, fmt, &lv32, SSH_FORMAT_END)) ssh_fatal("decode_case_int: bad returned len"); if (lv32 != value) ssh_fatal("decode_case_int: bad value"); } else if (fmt == SSH_FORMAT_UINT16) { if (bytes != ssh_decode_buffer(buffer, fmt, &lv16, SSH_FORMAT_END)) ssh_fatal("decode_case_int: bad returned len"); if (lv16 != value) ssh_fatal("decode_case_int: bad value"); } else ssh_fatal("Unknown fmt"); if (ssh_buffer_len(buffer) > 0) ssh_fatal("decode_case_int: data left"); }
size_t ssh_packet_encode_va(SshBuffer *buffer, SshPacketType type, va_list ap) { size_t payload_size, original_len; unsigned char *p; /* Save the original length so we can later find where the packet header starts. */ original_len = ssh_buffer_len(buffer); /* Construct the packet header with dummy length. */ ssh_encode_buffer(buffer, SSH_FORMAT_UINT32, (SshUInt32) 0, SSH_FORMAT_CHAR, (unsigned int)type, SSH_FORMAT_END); /* Encode the packet payload. */ payload_size = ssh_encode_va(buffer, ap); /* Update the packet header to contain the correct payload size. */ p = ssh_buffer_ptr(buffer); p += original_len; SSH_PUT_32BIT(p, payload_size + 1); /* Return the total number of bytes added to the buffer. */ return ssh_buffer_len(buffer) - original_len; }
void ssh_packet_wrapper_send_encode_va(SshPacketWrapper down, SshPacketType type, va_list va) { /* Format the packet in a separate buffer. */ ssh_buffer_clear(&down->outgoing_packet); ssh_packet_encode_va(&down->outgoing_packet, type, va); /* Check that we don't overflow maximum buffer size. Drop the packet if we would. */ if (ssh_buffer_len(&down->outgoing) + ssh_buffer_len(&down->outgoing_packet) >= BUFFER_MAX_SIZE) { ssh_debug("ssh_packet_wrapper_send_encode_va: flow control problems; " "outgoing packet dropped."); return; } /* Append the packet to the outgoing buffer. */ ssh_buffer_append(&down->outgoing, ssh_buffer_ptr(&down->outgoing_packet), ssh_buffer_len(&down->outgoing_packet)); /* Reset the callback to ensure that our callback gets called. */ ssh_stream_set_callback(down->stream, ssh_packet_wrapper_callback, (void *)down); }
static void ssh_eap_md5_client_recv_msg(SshEapProtocol protocol, SshEap eap, SshBuffer buf) { SshEapMd5State state; unsigned char *ucp = NULL; state = ssh_eap_protocol_get_state(protocol); if (state == NULL) { ssh_eap_discard_packet(eap, protocol, buf, "EAP MD5 state uninitialized"); return; } if (state->challenge_buffer != NULL) { ssh_free(state->challenge_buffer); state->challenge_buffer = NULL; } ucp = ssh_buffer_ptr(buf); if (ucp == NULL || (ssh_buffer_len(buf) < 6)) { ssh_eap_discard_packet(eap, protocol, buf, "packet length incorrect for EAP MD5 packet"); return; } state->challenge_length = ucp[5]; /* Note that RFC 1994 requires the challenge to be at least one octet */ if (state->challenge_length == 0 || (state->challenge_length + 6) > ssh_buffer_len(buf)) { ssh_eap_discard_packet(eap, protocol, buf, "EAP MD5 incorrect challenge length"); return; } state->challenge_buffer = ssh_malloc(state->challenge_length); if (state->challenge_buffer == NULL) { ssh_eap_fatal(eap, protocol, "Could not allocate buffer for challenge"); return; } memcpy(state->challenge_buffer, ucp + 6, state->challenge_length); state->response_id = ssh_eap_packet_get_identifier(buf); ssh_eap_protocol_request_token(eap, protocol->impl->id, SSH_EAP_TOKEN_SHARED_SECRET); }
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); }
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; }
static void ssh_eap_md5_server_recv_msg(SshEapProtocol protocol, SshEap eap, SshBuffer buf) { SshEapMd5State state; unsigned char *ucp = NULL; state = ssh_eap_protocol_get_state(protocol); if (state == NULL) { ssh_eap_discard_packet(eap, protocol, buf, "eap md5 auth state not initialized"); return; } ucp = ssh_buffer_ptr(buf); if (ucp == NULL || (ssh_buffer_len(buf) < 6)) { ssh_eap_discard_packet(eap, protocol, buf, "packet too short to be eap md5 response"); return; } state->response_length = ucp[5] & 0xFF; if (state->response_length < 1 || (state->response_length + 6) > ssh_buffer_len(buf)) { ssh_eap_discard_packet(eap, protocol, buf, "invalid ressponse value length"); return; } SSH_ASSERT(state->response_buffer == NULL); state->response_buffer = ssh_malloc(state->response_length); if (state->response_buffer == NULL) { ssh_eap_fatal(eap, protocol, "Could not cache challenge response. Out of memory"); return; } memcpy(state->response_buffer, ucp + 6, state->response_length); ssh_eap_protocol_request_token(eap, protocol->impl->id, SSH_EAP_TOKEN_SHARED_SECRET); }
/* 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; }
static int ssh_appgw_http_unmarshal_string(SshBuffer buf, unsigned char **ptr) { int len; *ptr = NULL; if (ssh_appgw_http_unmarshal_int(buf, &len) == 0) return 0; if (len == 0) return 1; if (ssh_buffer_len(buf) < len) return 0; *ptr = ssh_malloc(len+1); if (ptr == NULL) return 0; memcpy(*ptr,ssh_buffer_ptr(buf),len); (*ptr)[len] = '\0'; ssh_buffer_consume(buf,len); return 1; }
void decode_case_char(SshEncodingFormat fmt, unsigned char value) { unsigned int ch; size_t bytes; bytes = ssh_buffer_len(buffer); if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), fmt, NULL, SSH_FORMAT_END)) ssh_fatal("decode_case_char: NULL decode bad len"); if (bytes != ssh_decode_buffer(buffer, fmt, &ch, SSH_FORMAT_END)) ssh_fatal("decode_case_char: bad returned len"); if (ch != value) ssh_fatal("decode_case_char: bad value"); if (ssh_buffer_len(buffer) > 0) ssh_fatal("decode_case_char: data left"); }
void decode_case_bool(SshEncodingFormat fmt, Boolean value) { Boolean boo; size_t bytes; bytes = ssh_buffer_len(buffer); if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), fmt, NULL, SSH_FORMAT_END)) ssh_fatal("decode_case_bool: NULL decode bad len"); if (bytes != ssh_decode_buffer(buffer, fmt, &boo, SSH_FORMAT_END)) ssh_fatal("decode_case_bool: bad returned len"); if (boo != value) ssh_fatal("decode_case_bool: bad value"); if (ssh_buffer_len(buffer) > 0) ssh_fatal("decode_case_bool: data left"); }
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 encode_case(const char *name, const char *expect, size_t expect_len, ...) { size_t len, i, bytes; unsigned char ch, *cp; va_list va; ssh_buffer_clear(buffer); len = rand() % 100; ch = rand(); for (i = 0; i < len; i++) ssh_buffer_append(buffer, &ch, 1); va_start(va, expect_len); bytes = ssh_encode_buffer_va(buffer, va); if (bytes != expect_len || ssh_buffer_len(buffer) != len + expect_len) ssh_fatal("test_encode: %s: unexpected length %d vs. %d", name, bytes, len + expect_len); cp = ssh_buffer_ptr(buffer); if (memcmp(expect, cp + len, expect_len) != 0) ssh_fatal("test_encode: %s: mismatch", name); for (i = 0; i < len; i++) if (cp[i] != ch) ssh_fatal("test_encode: %s: beginning corrupted", name); ssh_buffer_consume(buffer, len); }
/* * Parse reply method. This doesn't do anything with SOCKS4. */ SocksError ssh_socks_client_parse_method(SshBuffer buffer, SocksInfo *socksinfo) { size_t ret = 0L, len; unsigned int version, method; unsigned char *data; data = ssh_buffer_ptr(buffer); len = ssh_buffer_len(buffer); if (len < 1) return SSH_SOCKS_TRY_AGAIN; version = *data; if (version == 0) version = 4; if (version == 4) return SSH_SOCKS_SUCCESS; if (len < 2) return SSH_SOCKS_TRY_AGAIN; ret = ssh_decode_buffer(buffer, SSH_DECODE_CHAR(&version), SSH_DECODE_CHAR(&method), SSH_FORMAT_END); if (ret == 0) { SSH_DEBUG(2, ("Decoding method buffer failed.")); return SSH_SOCKS_ERROR_PROTOCOL_ERROR; } if (method != SSH_SOCKS5_AUTH_METHOD_NO_AUTH_REQD) { SSH_DEBUG(2, ("Server sent method 0x%x.", method)); if (method == SSH_SOCKS5_AUTH_METHOD_NO_ACCEPTABLE) { SSH_DEBUG(2, ("Server doesn't allow use without some authentication " "(we don't implement any methods).")); } else { SSH_DEBUG(2, ("Server sent method that we don't support.")); return SSH_SOCKS_ERROR_PROTOCOL_ERROR; } return SSH_SOCKS_FAILED_AUTH; } if (socksinfo) { *socksinfo = ssh_calloc(1, sizeof(**socksinfo)); if (*socksinfo == NULL) { SSH_DEBUG(2, ("Couldn't allocate SshSocksInfo.")); return SSH_SOCKS_ERROR_INVALID_ARGUMENT; } (*socksinfo)->socks_version_number = version; } return SSH_SOCKS_SUCCESS; }
void copy_data_test(SshStream s1, SshStream s2) { ts1 = s1; ts2 = s2; create_testdata(); if (received_data) ssh_buffer_clear(received_data); else received_data = ssh_buffer_allocate(); test_data_index = 0; destroy_count = 0; reader_sent_eof = FALSE; ssh_stream_set_callback(s1, copy_writer, NULL); ssh_stream_set_callback(s2, copy_reader, NULL); ssh_event_loop_run(); if (destroy_count != 2 || ts1 != NULL || ts2 != NULL) ssh_fatal("copy_data_test: one stream not destroyed"); if (ssh_buffer_len(received_data) > ssh_buffer_len(testdata)) ssh_fatal("copy_data_test: received more data than sent"); if (break_test) ssh_buffer_consume_end(testdata, ssh_buffer_len(testdata) - ssh_buffer_len(received_data)); if (ssh_buffer_len(testdata) != ssh_buffer_len(received_data)) ssh_fatal("copy_data_test: data lens differ"); if (memcmp(ssh_buffer_ptr(testdata), ssh_buffer_ptr(received_data), ssh_buffer_len(testdata)) != 0) ssh_fatal("copy_data_test: received data differs"); }
void test_functions_parse_compound(SshBuffer buffer, ...) { va_list va; va_start(va, buffer); if (ssh_decode_array_va(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), va) != 4) ssh_fatal("test_functions_parse_compound error"); }
void decode_case_data(SshEncodingFormat fmt, const char *value, size_t valuelen) { char buf[1024]; size_t bytes; SSH_ASSERT(valuelen < sizeof(buf)); bytes = ssh_buffer_len(buffer); if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), fmt, NULL, valuelen, SSH_FORMAT_END)) ssh_fatal("decode_case_data: NULL decode bad len"); if (bytes != ssh_decode_buffer(buffer, fmt, buf, valuelen, SSH_FORMAT_END)) ssh_fatal("decode_case_data: bad returned len"); if (memcmp(buf, value, valuelen) != 0) ssh_fatal("decode_case_data: bad value"); if (ssh_buffer_len(buffer) > 0) ssh_fatal("decode_case_data: data left"); }
void decode_case_str(SshEncodingFormat fmt, const char *value, size_t valuelen) { unsigned char *cp; size_t len, bytes; bytes = ssh_buffer_len(buffer); if (bytes != ssh_decode_array(ssh_buffer_ptr(buffer), ssh_buffer_len(buffer), fmt, NULL, NULL, SSH_FORMAT_END)) ssh_fatal("decode_case_str: NULL decode bad len"); if (bytes != ssh_decode_buffer(buffer, fmt, &cp, &len, SSH_FORMAT_END)) ssh_fatal("decode_case_str: bad returned len"); if (len != valuelen || memcmp(cp, value, len) != 0) ssh_fatal("decode_case_str: bad cmp"); if (ssh_buffer_len(buffer) > 0) ssh_fatal("decode_case_str: data left"); if (cp[len] != 0) ssh_fatal("decode_case_str: not null terminated"); ssh_xfree(cp); }
void ssh_packet_impl_send_encode_va(SshStream up_stream, SshPacketType type, va_list va) { SshPacketImpl up; /* Verify that it is a SshPacketImpl stream. */ if (ssh_stream_get_methods(up_stream) != &ssh_packet_impl_methods) ssh_fatal("ssh_packet_impl_can_receive: not a SshPacketImpl stream"); /* Get the internal context. */ up = (SshPacketImpl)ssh_stream_get_context(up_stream); /* Format the packet in a separate buffer. */ ssh_buffer_clear(&up->outgoing_packet); ssh_packet_encode_va(&up->outgoing_packet, type, va); /* Check that we don't overflow maximum buffer size. Drop the packet if we would. */ if (ssh_buffer_len(&up->outgoing) + ssh_buffer_len(&up->outgoing_packet) >= BUFFER_MAX_SIZE) { ssh_debug("ssh_packet_impl_send_encode_va: " "flow control problems; outgoing packet dropped."); return; } /* Append the packet to the outgoing buffer. */ if (ssh_buffer_append(&up->outgoing, ssh_buffer_ptr(&up->outgoing_packet), ssh_buffer_len(&up->outgoing_packet)) != SSH_BUFFER_OK) { return; } /* Restart reads by upper level. */ ssh_packet_impl_restart_input(up); /* Sanity check that we didn't exceed max buffer size. */ if (ssh_buffer_len(&up->outgoing) > BUFFER_MAX_SIZE) ssh_debug("ssh_packet_impl_send: buffer max size exceeded: size %ld", (long)ssh_buffer_len(&up->outgoing)); }
void ssh_packet_wrapper_send_eof(SshPacketWrapper down) { /* If EOF already sent, return immediately. */ if (down->outgoing_eof) return; /* Otherwise, send EOF now. */ down->outgoing_eof = TRUE; if (ssh_buffer_len(&down->outgoing) == 0) ssh_stream_output_eof(down->stream); }
void ssh_packet_shortcircuit(SshStream packet_stream, SshPacketWrapper wrapper) { /* Mark that the stream is shortcircuited. */ wrapper->shortcircuited = FALSE; wrapper->shortcircuit_up_stream = packet_stream; #if 0 /* the packet is still in wrapper->incoming when we call the callback */ /* Sanity check: there must not be data in incoming buffer. */ if (ssh_buffer_len(&wrapper->incoming) != 0) ssh_fatal("ssh_packet_shortcircuit: incoming data in buffer; not set in packet callback"); #endif /* 0 */ /* If there is no data to drain, shortcircuit output now. */ if (ssh_buffer_len(&wrapper->outgoing) == 0) { wrapper->shortcircuited = TRUE; ssh_packet_impl_shortcircuit_now(wrapper->shortcircuit_up_stream, wrapper->stream); } }
static int ssh_appgw_http_unmarshal_int(SshBuffer buf, int *result) { if (ssh_buffer_len(buf) < 4) { *result = 0; return 0; } *result = (int)(SSH_GET_32BIT(ssh_buffer_ptr(buf))); ssh_buffer_consume(buf,4); return 1; }
Boolean ssh_packet_wrapper_can_send(SshPacketWrapper down) { Boolean status; status = ssh_buffer_len(&down->outgoing) < BUFFER_MAX_SIZE - ALLOW_AFTER_BUFFER_FULL; /* If no more can be sent, mark that sending is blocked. This will trigger a callback when data can again be sent. */ if (!status) down->send_blocked = TRUE; return status; }
int ssh_packet_impl_read(void *context, unsigned char *buf, size_t size) { SshPacketImpl up = (SshPacketImpl)context; size_t len; /* Compute the number of bytes we can transmit. */ len = ssh_buffer_len(&up->outgoing); if (len > size) len = size; /* Return immediately if no data available. */ if (len == 0) { /* If shortcircuiting, pass it to the shortcircuit stream. */ if (up->shortcircuit_stream) return ssh_stream_read(up->shortcircuit_stream, buf, size); /* Return EOF or "no more data available yet". */ if (up->outgoing_eof) return 0; else { up->up_read_blocked = TRUE; return -1; } } /* Move data to the caller's buffer. */ memcpy(buf, ssh_buffer_ptr(&up->outgoing), len); ssh_buffer_consume(&up->outgoing, len); /* Wake up the sender if appropriate. */ if (ssh_buffer_len(&up->outgoing) == 0) ssh_packet_impl_restart_send(up); return len; }
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"); } } }
/* * Parse methods array. This doesn't do anything with SOCKS4. */ SocksError ssh_socks_server_parse_methods(SshBuffer buffer, SocksInfo *socksinfo) { size_t ret = 0L, len; unsigned int version, num_methods; unsigned char *data; data = ssh_buffer_ptr(buffer); len = ssh_buffer_len(buffer); if (len < 1) return SSH_SOCKS_TRY_AGAIN; version = *data; if (version == 4) goto return_success; if (len < 2) return SSH_SOCKS_TRY_AGAIN; ret = ssh_decode_array(data, len, SSH_DECODE_CHAR(&version), SSH_DECODE_CHAR(&num_methods), SSH_FORMAT_END); if (ret == 0) { SSH_DEBUG(2, ("Decoding methods buffer failed.")); return SSH_SOCKS_ERROR_PROTOCOL_ERROR; } if (len < num_methods + 2) return SSH_SOCKS_TRY_AGAIN; ssh_buffer_consume(buffer, num_methods + 2); return_success: if (socksinfo) { *socksinfo = ssh_calloc(1, sizeof(**socksinfo)); if (*socksinfo == NULL) { SSH_DEBUG(2, ("Couldn't allocate SshSocksInfo.")); return SSH_SOCKS_ERROR_INVALID_ARGUMENT; } (*socksinfo)->socks_version_number = version; } return SSH_SOCKS_SUCCESS; }
void test_encode(void) { encode_case("uint32_str 0", "\0\0\0\0", 4, SSH_ENCODE_UINT32_STR(NULL, 0), SSH_FORMAT_END); decode_case_str(SSH_FORMAT_UINT32_STR, "", 0); encode_case("uint32_str 0", "\0\0\0\0", 4, SSH_ENCODE_UINT32_SSTR("ABC", 0), SSH_FORMAT_END); decode_case_str(SSH_FORMAT_UINT32_STR, "", 0); encode_case("uint32_str 5", "\0\0\0\5ABCDE", 9, SSH_ENCODE_UINT32_SSTR("ABCDEFGHIJK", 5), SSH_FORMAT_END); decode_case_str(SSH_FORMAT_UINT32_STR, "ABCDE", 5); encode_case("uint32 0x12345678", "\22\64\126\170", 4, SSH_ENCODE_UINT32(0x12345678), SSH_FORMAT_END); decode_case_int(SSH_FORMAT_UINT32, (SshUInt32) 0x12345678); encode_case("uint16 0x1234", "\22\64", 2, SSH_ENCODE_UINT16(0x1234), SSH_FORMAT_END); decode_case_int(SSH_FORMAT_UINT16, (SshUInt16) 0x1234); encode_case("boolean FALSE", "\0", 1, SSH_ENCODE_BOOLEAN(FALSE), SSH_FORMAT_END); decode_case_bool(SSH_FORMAT_BOOLEAN, FALSE); encode_case("boolean TRUE", "\1", 1, SSH_ENCODE_BOOLEAN(TRUE), SSH_FORMAT_END); decode_case_bool(SSH_FORMAT_BOOLEAN, TRUE); encode_case("boolean 0xff", "\1", 1, SSH_ENCODE_BOOLEAN(0xff), SSH_FORMAT_END); decode_case_bool(SSH_FORMAT_BOOLEAN, TRUE); encode_case("char 0x12", "\22", 1, SSH_ENCODE_CHAR(0x12), SSH_FORMAT_END); decode_case_char(SSH_FORMAT_CHAR, (unsigned int) 0x12); encode_case("char 0xee", "\356", 1, SSH_ENCODE_CHAR(0xee), SSH_FORMAT_END); decode_case_char(SSH_FORMAT_CHAR, (unsigned int) 0xee); encode_case("data foo\\0bar", "foo\0bar", 7, SSH_ENCODE_DATA("foo\0bar", 7), SSH_FORMAT_END); decode_case_data(SSH_FORMAT_DATA, "foo\0bar", 7); encode_case("nothing", "", 0, SSH_FORMAT_END); if (ssh_buffer_len(buffer) != 0) ssh_fatal("``nothing'' encoded to non-empty"); }
static int cm_debug_renderer_return(SshBuffer buffer, unsigned char *buf, int len) { int l = ssh_buffer_len(buffer); if (l > len) { ssh_ustrncpy(buf, ssh_buffer_ptr(buffer), len - 1); ssh_buffer_uninit(buffer); return len + 1; } else { ssh_ustrncpy(buf, ssh_buffer_ptr(buffer), l); ssh_buffer_uninit(buffer); return l; } }
/* * Inserts specified event into log file specified in context. * event parameter specifies the audited event. Each element after event * must start with a SshAuditformat type followed by arguments of the * appropriate type, and the list must end with SSH_AUDIT_ARGUMENT_END. */ void ssh_audit_event(SshAuditContext context, SshAuditEvent event, ...) { size_t bytes; va_list ap; SshBuffer *audit_info, *formated_str; char *audit_time; if (context == NULL) return; if ((event < 0) || (event > SSH_AUDIT_MAX_VALUE)) return; /* Check if given event is allowed */ if (!context->ssh_audit_event_allowed[(int)event]) return; /* Initialize a buffer for output string */ audit_info = ssh_buffer_allocate(); /* Start constructing string which will be inserted into audit log.*/ /* Start with inserting the name of the event.*/ /* then date and time */ audit_time = ssh_time_string(ssh_time()); ssh_buffer_append_cstrs(audit_info, ssh_find_keyword_name(ssh_audit_event_title, (int)event), ": ", audit_time, ": ", NULL); ssh_xfree(audit_time); /* Handle the variable list*/ va_start(ap, event); formated_str = ssh_format_audit_string(ap); va_end(ap); /* Insert given parameters into string*/ ssh_buffer_append(audit_info, ssh_buffer_ptr(formated_str), ssh_buffer_len(formated_str)); ssh_buffer_append(audit_info, (unsigned char *) "\0", 1); /* Output the log message*/ ssh_send_log_message(context, ssh_buffer_ptr(audit_info)); ssh_buffer_free(formated_str); ssh_buffer_free(audit_info); }