static void client_round_info_from_network(packet_t *packet) { uint8_t delta; if (!packet_read08(packet, &delta)) PROTOCOL_ERROR(); next_packet_countdown += delta; }
static void client_handshake_from_network(packet_t *packet) { uint8_t serverprotocol; if (!packet_read08(packet, &serverprotocol)) PROTOCOL_ERROR(); if (serverprotocol != PROTOCOL_VERSION) { die("%s has %s protocol version %d. I have %d.\n" "visit the infon homepage for more information.", is_file_source ? "demo" : "server", serverprotocol < PROTOCOL_VERSION ? "older" : "newer", serverprotocol, PROTOCOL_VERSION); } }
static void client_start_compression() { if (compression) PROTOCOL_ERROR(); if (getenv("UNCOMPRESSED_DEMO_COMPATIBILITY") && is_file_source) return; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = NULL; if (inflateInit(&strm) != Z_OK) die("cannot initialize decompression"); compression = 1; }
static void do_service_request(struct packet_handler *c, struct ssh_connection *connection, struct lsh_string *packet) { CAST(service_handler, closure, c); struct simple_buffer buffer; unsigned msg_number; int name; simple_buffer_init(&buffer, packet->length, packet->data); if (parse_uint8(&buffer, &msg_number) && (msg_number == SSH_MSG_SERVICE_REQUEST) && parse_atom(&buffer, &name) && parse_eod(&buffer)) { if (name) { CAST_SUBTYPE(command, service, ALIST_GET(closure->services, name)); if (service) { /* Don't accept any further service requests */ connection->dispatch[SSH_MSG_SERVICE_REQUEST] = &connection_fail_handler; /* Start service */ #if DATAFELLOWS_WORKAROUNDS if (connection->peer_flags & PEER_SERVICE_ACCEPT_KLUDGE) C_WRITE(connection, format_service_accept_kludge()); else #endif /* DATAFELLOWS_WORKAROUNDS */ C_WRITE(connection, format_service_accept(name)); COMMAND_CALL(service, connection, closure->c, closure->e); return; } } EXCEPTION_RAISE(connection->e, make_protocol_exception(SSH_DISCONNECT_SERVICE_NOT_AVAILABLE, NULL)); } else PROTOCOL_ERROR(connection->e, "Invalid SERVICE_REQUEST message"); }
static void connection_handle_packet(struct ssh_connection *closure, struct lsh_string *packet) { UINT8 msg; assert(!closure->paused); if (!packet->length) { werror("connection.c: Received empty packet!\n"); PROTOCOL_ERROR(closure->e, "Received empty packet."); lsh_string_free(packet); return; } if (packet->length > closure->rec_max_packet) { werror("connection.c: Packet too large!\n"); PROTOCOL_ERROR(closure->e, "Packet too large"); lsh_string_free(packet); return; } msg = packet->data[0]; debug("handle_connection: Received packet of type %i (%z)\n", msg, packet_types[msg]); switch(closure->kex_state) { case KEX_STATE_INIT: if (msg == SSH_MSG_NEWKEYS) { werror("Unexpected NEWKEYS message!\n"); PROTOCOL_ERROR(closure->e, "Unexpected NEWKEYS message!"); lsh_string_free(packet); return; } break; case KEX_STATE_IGNORE: debug("handle_connection: Ignoring packet %i\n", msg); /* It's conceivable with key exchange methods for which one * wants to switch to the NEWKEYS state immediately. But for * now, we always switch to the IN_PROGRESS state, to wait for a * KEXDH_INIT or KEXDH_REPLY message. */ closure->kex_state = KEX_STATE_IN_PROGRESS; lsh_string_free(packet); return; case KEX_STATE_IN_PROGRESS: if ( (msg == SSH_MSG_NEWKEYS) || (msg == SSH_MSG_KEXINIT)) { werror("Unexpected KEXINIT or NEWKEYS message!\n"); PROTOCOL_ERROR(closure->e, "Unexpected KEXINIT or NEWKEYS message!"); lsh_string_free(packet); return; } break; case KEX_STATE_NEWKEYS: if (! ((msg == SSH_MSG_NEWKEYS) || (msg == SSH_MSG_DISCONNECT) || (msg == SSH_MSG_IGNORE) || (msg == SSH_MSG_DEBUG))) { werror("Expected NEWKEYS message, but received message %i!\n", msg); PROTOCOL_ERROR(closure->e, "Expected NEWKEYS message"); lsh_string_free(packet); return; } break; default: fatal("handle_connection: Internal error.\n"); } HANDLE_PACKET(closure->dispatch[msg], closure, packet); lsh_string_free(packet); }