enum SCP_SERVER_STATES_E scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason) { tui8 sz; tui32 version; tui32 size; tui16 cmdset; tui16 cmd; int rlen; char buf[257]; init_stream(c->in_s, c->in_s->size); init_stream(c->out_s, c->out_s->size); /* forcing message not to exceed 64k */ rlen = g_strlen(reason); if (rlen > 65535) { rlen = 65535; } /* send password request */ version=1; cmd=3; out_uint32_be(c->out_s, version); /* version */ out_uint32_be(c->out_s, 14+rlen); /* size */ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ out_uint16_be(c->out_s, cmd); /* cmd */ out_uint16_be(c->out_s, rlen); out_uint8p(c->out_s, reason, rlen); if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } /* receive password & username */ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version!=1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size<12) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmdset); if (cmdset != SCP_COMMAND_SET_DEFAULT) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != 4) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } buf[256] = '\0'; /* reading username */ in_uint8(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_username(s, buf)) { scp_session_destroy(s); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint8(c->in_s, sz); buf[sz]='\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_password(s, buf)) { scp_session_destroy(s); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } return SCP_SERVER_STATE_OK; }
/* server API */ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) { struct SCP_SESSION* session; tui32 version; tui32 size; tui16 cmdset; tui16 cmd; tui8 sz; char buf[257]; if (!skipVchk) { if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { in_uint32_be(c->in_s, version); if (version != 1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } } else { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } in_uint32_be(c->in_s, size); if (size < 12) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8))) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } /* reading command set */ in_uint16_be(c->in_s, cmdset); /* if we are starting a management session */ if (cmdset == SCP_COMMAND_SET_MANAGE) { log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); /* should return SCP_SERVER_STATE_START_MANAGE */ return scp_v1s_mng_accept(c, s); } /* if we started with resource sharing... */ if (cmdset == SCP_COMMAND_SET_RSR) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } /* reading command */ in_uint16_be(c->in_s, cmd); if (cmd != 1) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } session = scp_session_create(); if (0 == session) { log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } scp_session_set_version(session, 1); in_uint8(c->in_s, sz); if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); return SCP_SERVER_STATE_SESSION_TYPE_ERR; } scp_session_set_type(session, sz); in_uint16_be(c->in_s, cmd); scp_session_set_height(session, cmd); in_uint16_be(c->in_s, cmd); scp_session_set_height(session, cmd); in_uint8(c->in_s, sz); scp_session_set_bpp(session, sz); in_uint8(c->in_s, sz); scp_session_set_rsr(session, sz); in_uint8a(c->in_s, buf, 17); buf[17]='\0'; scp_session_set_locale(session, buf); in_uint8(c->in_s, sz); if (sz == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->in_s, size); scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &size); } else if (sz == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->in_s, buf, 16); scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); } buf[256] = '\0'; /* reading hostname */ in_uint8(c->in_s, sz); buf[sz]='\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_hostname(session, buf)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading username */ in_uint8(c->in_s, sz); buf[sz]='\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_username(session, buf)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint8(c->in_s, sz); buf[sz]='\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_password(session, buf)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* returning the struct */ (*s)=session; return SCP_SERVER_STATE_OK; }
static void rdpdr_process_irp(STREAM s) { uint32 result = 0, length = 0, desired_access = 0, request, file, info_level, buffer_len, id, major, minor, device, offset, bytes_in, bytes_out, error_mode, share_mode, disposition, total_timeout, interval_timeout, flags_and_attributes = 0; char filename[PATH_MAX]; uint8 *buffer, *pst_buf; struct stream out; DEVICE_FNS *fns; BOOL rw_blocking = True; NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; in_uint32_le(s, device); in_uint32_le(s, file); in_uint32_le(s, id); in_uint32_le(s, major); in_uint32_le(s, minor); buffer_len = 0; buffer = (uint8 *) xmalloc(1024); buffer[0] = 0; switch (g_rdpdr_device[device].device_type) { case DEVICE_TYPE_SERIAL: fns = &serial_fns; rw_blocking = False; break; case DEVICE_TYPE_PARALLEL: fns = ¶llel_fns; rw_blocking = False; break; case DEVICE_TYPE_PRINTER: fns = &printer_fns; break; case DEVICE_TYPE_DISK: fns = &disk_fns; rw_blocking = False; break; case DEVICE_TYPE_SCARD: default: error("IRP for bad device %ld\n", device); return; } switch (major) { case IRP_MJ_CREATE: in_uint32_be(s, desired_access); in_uint8s(s, 0x08); /* unknown */ in_uint32_le(s, error_mode); in_uint32_le(s, share_mode); in_uint32_le(s, disposition); in_uint32_le(s, flags_and_attributes); in_uint32_le(s, length); if (length && (length / 2) < 256) { rdp_in_unistr(s, filename, length); convert_to_unix_filename(filename); } else { filename[0] = 0; } if (!fns->create) { status = STATUS_NOT_SUPPORTED; break; } status = fns->create(device, desired_access, share_mode, disposition, flags_and_attributes, filename, &result); buffer_len = 1; break; case IRP_MJ_CLOSE: if (!fns->close) { status = STATUS_NOT_SUPPORTED; break; } status = fns->close(file); break; case IRP_MJ_READ: if (!fns->read) { status = STATUS_NOT_SUPPORTED; break; } in_uint32_le(s, length); in_uint32_le(s, offset); #if WITH_DEBUG_RDP5 DEBUG(("RDPDR IRP Read (length: %d, offset: %d)\n", length, offset)); #endif if (!rdpdr_handle_ok(device, file)) { status = STATUS_INVALID_HANDLE; break; } if (rw_blocking) /* Complete read immediately */ { buffer = (uint8 *) xrealloc((void *) buffer, length); if (!buffer) { status = STATUS_CANCELLED; break; } status = fns->read(file, buffer, length, offset, &result); buffer_len = result; break; } /* Add request to table */ pst_buf = (uint8 *) xmalloc(length); if (!pst_buf) { status = STATUS_CANCELLED; break; } serial_get_timeout(file, length, &total_timeout, &interval_timeout); if (add_async_iorequest (device, file, id, major, length, fns, total_timeout, interval_timeout, pst_buf, offset)) { status = STATUS_PENDING; break; } status = STATUS_CANCELLED; break; case IRP_MJ_WRITE: buffer_len = 1; if (!fns->write) { status = STATUS_NOT_SUPPORTED; break; } in_uint32_le(s, length); in_uint32_le(s, offset); in_uint8s(s, 0x18); #if WITH_DEBUG_RDP5 DEBUG(("RDPDR IRP Write (length: %d)\n", result)); #endif if (!rdpdr_handle_ok(device, file)) { status = STATUS_INVALID_HANDLE; break; } if (rw_blocking) /* Complete immediately */ { status = fns->write(file, s->p, length, offset, &result); break; } /* Add to table */ pst_buf = (uint8 *) xmalloc(length); if (!pst_buf) { status = STATUS_CANCELLED; break; } in_uint8a(s, pst_buf, length); if (add_async_iorequest (device, file, id, major, length, fns, 0, 0, pst_buf, offset)) { status = STATUS_PENDING; break; } status = STATUS_CANCELLED; break; case IRP_MJ_QUERY_INFORMATION: if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK) { status = STATUS_INVALID_HANDLE; break; } in_uint32_le(s, info_level); out.data = out.p = buffer; out.size = sizeof(buffer); status = disk_query_information(file, info_level, &out); result = buffer_len = out.p - out.data; break; case IRP_MJ_SET_INFORMATION: if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK) { status = STATUS_INVALID_HANDLE; break; } in_uint32_le(s, info_level); out.data = out.p = buffer; out.size = sizeof(buffer); status = disk_set_information(file, info_level, s, &out); result = buffer_len = out.p - out.data; break; case IRP_MJ_QUERY_VOLUME_INFORMATION: if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK) { status = STATUS_INVALID_HANDLE; break; } in_uint32_le(s, info_level); out.data = out.p = buffer; out.size = sizeof(buffer); status = disk_query_volume_information(file, info_level, &out); result = buffer_len = out.p - out.data; break; case IRP_MJ_DIRECTORY_CONTROL: if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK) { status = STATUS_INVALID_HANDLE; break; } switch (minor) { case IRP_MN_QUERY_DIRECTORY: in_uint32_le(s, info_level); in_uint8s(s, 1); in_uint32_le(s, length); in_uint8s(s, 0x17); if (length && length < 2 * 255) { rdp_in_unistr(s, filename, length); convert_to_unix_filename(filename); } else { filename[0] = 0; } out.data = out.p = buffer; out.size = sizeof(buffer); status = disk_query_directory(file, info_level, filename, &out); result = buffer_len = out.p - out.data; if (!buffer_len) buffer_len++; break; case IRP_MN_NOTIFY_CHANGE_DIRECTORY: /* JIF unimpl("IRP major=0x%x minor=0x%x: IRP_MN_NOTIFY_CHANGE_DIRECTORY\n", major, minor); */ in_uint32_le(s, info_level); /* notify mask */ g_notify_stamp = True; status = disk_create_notify(file, info_level); result = 0; if (status == STATUS_PENDING) add_async_iorequest(device, file, id, major, length, fns, 0, 0, NULL, 0); break; default: status = STATUS_INVALID_PARAMETER; /* JIF */ unimpl("IRP major=0x%x minor=0x%x\n", major, minor); } break; case IRP_MJ_DEVICE_CONTROL: if (!fns->device_control) { status = STATUS_NOT_SUPPORTED; break; } in_uint32_le(s, bytes_out); in_uint32_le(s, bytes_in); in_uint32_le(s, request); in_uint8s(s, 0x14); buffer = (uint8 *) xrealloc((void *) buffer, bytes_out + 0x14); if (!buffer) { status = STATUS_CANCELLED; break; } out.data = out.p = buffer; out.size = sizeof(buffer); status = fns->device_control(file, request, s, &out); result = buffer_len = out.p - out.data; /* Serial SERIAL_WAIT_ON_MASK */ if (status == STATUS_PENDING) { if (add_async_iorequest (device, file, id, major, length, fns, 0, 0, NULL, 0)) { status = STATUS_PENDING; break; } } break; case IRP_MJ_LOCK_CONTROL: if (g_rdpdr_device[device].device_type != DEVICE_TYPE_DISK) { status = STATUS_INVALID_HANDLE; break; } in_uint32_le(s, info_level); out.data = out.p = buffer; out.size = sizeof(buffer); /* FIXME: Perhaps consider actually *do* something here :-) */ status = STATUS_SUCCESS; result = buffer_len = out.p - out.data; break; default: unimpl("IRP major=0x%x minor=0x%x\n", major, minor); break; } if (status != STATUS_PENDING) { rdpdr_send_completion(device, id, status, result, buffer, buffer_len); } if (buffer) xfree(buffer); buffer = NULL; }
int DEFAULT_CC main(int argc, char** argv) { int sck; int code; int i; int size; int version; int width; int height; int bpp; int keylayout; int display; struct stream* in_s; struct stream* out_s; char* username; char* password; char* exec; long data; if (0 != config_read(&g_cfg)) { g_printf("sesrun: error reading config. quitting.\n"); return 1; } g_pid = g_getpid(); if (argc == 1) { g_printf("xrdp session starter v0.2\n"); g_printf("\nusage:\n"); g_printf("sesrun <server> <username> <password> <exec> <width> <height> <bpp> <keylayout>\n"); } else if (argc == 9) { username = argv[2]; password = argv[3]; exec = argv[4]; width = g_atoi(argv[5]); height = g_atoi(argv[6]); bpp = g_atoi(argv[7]); keylayout = g_atoi(argv[8]); make_stream(in_s); init_stream(in_s, 8192); make_stream(out_s); init_stream(out_s, 8192); sck = g_tcp_socket(); if (g_tcp_connect(sck, argv[1], "3350") == 0) { s_push_layer(out_s, channel_hdr, 8); out_uint16_be(out_s, 20); /* code */ i = g_strlen(username); out_uint16_be(out_s, i); out_uint8a(out_s, username, i); i = g_strlen(password); out_uint16_be(out_s, i); out_uint8a(out_s, password, i); i = g_strlen(exec); out_uint16_be(out_s, i); out_uint8a(out_s, exec, i); out_uint16_be(out_s, width); out_uint16_be(out_s, height); out_uint16_be(out_s, bpp); out_uint16_be(out_s, keylayout); s_mark_end(out_s); s_pop_layer(out_s, channel_hdr); out_uint32_be(out_s, 0); /* version */ out_uint32_be(out_s, out_s->end - out_s->data); /* size */ tcp_force_send(sck, out_s->data, out_s->end - out_s->data); if (tcp_force_recv(sck, in_s->data, 8) == 0) { in_uint32_be(in_s, version); in_uint32_be(in_s, size); init_stream(in_s, 8192); if (tcp_force_recv(sck, in_s->data, size - 8) == 0) { if (version == 0) { in_uint16_be(in_s, code); if (code == 3) { in_uint16_be(in_s, data); in_uint16_be(in_s, display); g_printf("ok %d display %d\n", data, display); } } } } } else { g_printf("connect error\n"); } g_tcp_close(sck); free_stream(in_s); free_stream(out_s); } return 0; }
enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { tui32 version; tui32 size; tui16 sz; init_stream(c->in_s, c->in_s->size); init_stream(c->out_s, c->in_s->size); LOG_DBG("[v0:%d] starting connection", __LINE__); g_tcp_set_non_blocking(c->in_sck); g_tcp_set_no_delay(c->in_sck); s_push_layer(c->out_s, channel_hdr, 8); /* code */ if (s->type == SCP_SESSION_TYPE_XVNC) { out_uint16_be(c->out_s, 0); } else if (s->type == SCP_SESSION_TYPE_XRDP) { out_uint16_be(c->out_s, 10); } else if (s->type == SCP_SESSION_TYPE_XORG) { out_uint16_be(c->out_s, 20); } else { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_INTERNAL_ERR; } sz = g_strlen(s->username); out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->username, sz); sz = g_strlen(s->password); out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->password, sz); out_uint16_be(c->out_s, s->width); out_uint16_be(c->out_s, s->height); out_uint16_be(c->out_s, s->bpp); s_mark_end(c->out_s); s_pop_layer(c->out_s, channel_hdr); /* version */ out_uint32_be(c->out_s, 0); /* size */ out_uint32_be(c->out_s, c->out_s->end - c->out_s->data); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (0 != version) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); return SCP_CLIENT_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); if (size < 14) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); return SCP_CLIENT_STATE_SIZE_ERR; } /* getting payload */ init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } /* check code */ in_uint16_be(c->in_s, sz); if (3 != sz) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } /* message payload */ in_uint16_be(c->in_s, sz); if (1 != sz) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__); return SCP_CLIENT_STATE_CONNECTION_DENIED; } in_uint16_be(c->in_s, sz); s->display = sz; LOG_DBG("[v0:%d] connection terminated", __LINE__); return SCP_CLIENT_STATE_END; }
enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) { tui32 version = 0; tui32 size; struct SCP_SESSION *session = 0; tui16 sz; tui32 code = 0; char buf[257]; if (!skipVchk) { LOG_DBG("[v0:%d] starting connection", __LINE__); if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { c->in_s->end = c->in_s->data + 8; in_uint32_be(c->in_s, version); if (version != 0) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } } else { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } in_uint32_be(c->in_s, size); init_stream(c->in_s, 8196); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } c->in_s->end = c->in_s->data + (size - 8); in_uint16_be(c->in_s, code); if (code == 0 || code == 10 || code == 20) { session = scp_session_create(); if (0 == session) { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } scp_session_set_version(session, version); if (code == 0) { scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); } else if (code == 10) { scp_session_set_type(session, SCP_SESSION_TYPE_XRDP); } else if (code == 20) { scp_session_set_type(session, SCP_SESSION_TYPE_XORG); } /* reading username */ in_uint16_be(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_username(session, buf)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint16_be(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_password(session, buf)) { scp_session_destroy(session); log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* width */ in_uint16_be(c->in_s, sz); scp_session_set_width(session, sz); /* height */ in_uint16_be(c->in_s, sz); scp_session_set_height(session, sz); /* bpp */ in_uint16_be(c->in_s, sz); scp_session_set_bpp(session, (tui8)sz); if (s_check_rem(c->in_s, 2)) { /* reading domain */ in_uint16_be(c->in_s, sz); if (sz > 0) { in_uint8a(c->in_s, buf, sz); buf[sz] = '\0'; scp_session_set_domain(session, buf); } } if (s_check_rem(c->in_s, 2)) { /* reading program */ in_uint16_be(c->in_s, sz); if (sz > 0) { in_uint8a(c->in_s, buf, sz); buf[sz] = '\0'; scp_session_set_program(session, buf); } } if (s_check_rem(c->in_s, 2)) { /* reading directory */ in_uint16_be(c->in_s, sz); if (sz > 0) { in_uint8a(c->in_s, buf, sz); buf[sz] = '\0'; scp_session_set_directory(session, buf); } } if (s_check_rem(c->in_s, 2)) { /* reading client IP address */ in_uint16_be(c->in_s, sz); if (sz > 0) { in_uint8a(c->in_s, buf, sz); buf[sz] = '\0'; scp_session_set_client_ip(session, buf); } } } else if (code == SCP_GW_AUTHENTICATION) { /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ session = scp_session_create(); if (0 == session) { /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ return SCP_SERVER_STATE_INTERNAL_ERR; } scp_session_set_version(session, version); scp_session_set_type(session, SCP_GW_AUTHENTICATION); /* reading username */ in_uint16_be(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); /* g_writeln("Received user name: %s",buf); */ if (0 != scp_session_set_username(session, buf)) { scp_session_destroy(session); /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint16_be(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); /* g_writeln("Received password: %s",buf); */ if (0 != scp_session_set_password(session, buf)) { scp_session_destroy(session); /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ return SCP_SERVER_STATE_INTERNAL_ERR; } } else { log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } (*s) = session; return SCP_SERVER_STATE_OK; }
/* server API */ enum SCP_SERVER_STATES_E scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) { struct SCP_SESSION *session; tui32 ipaddr; tui16 cmd; tui8 sz; char buf[257]; /* reading command */ in_uint16_be(c->in_s, cmd); if (cmd != 1) /* manager login */ { return SCP_SERVER_STATE_SEQUENCE_ERR; } session = scp_session_create(); if (0 == session) { return SCP_SERVER_STATE_INTERNAL_ERR; } scp_session_set_version(session, 1); scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); /* reading username */ in_uint8(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_username(session, buf)) { scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ in_uint8(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_password(session, buf)) { scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading remote address */ in_uint8(c->in_s, sz); if (sz == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->in_s, ipaddr); scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); } else if (sz == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->in_s, buf, 16); scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); } /* reading hostname */ in_uint8(c->in_s, sz); buf[sz] = '\0'; in_uint8a(c->in_s, buf, sz); if (0 != scp_session_set_hostname(session, buf)) { scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } /* returning the struct */ (*s) = session; return SCP_SERVER_STATE_START_MANAGE; }
static enum SCP_SERVER_STATES_E _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { tui32 version; tui32 size; tui16 cmd; // tui8 dim; // char buf[257]; init_stream(c->in_s, c->in_s->size); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint32_be(c->in_s, version); if (version != 1) { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); init_stream(c->in_s, c->in_s->size); /* read the rest of the packet */ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_MANAGE) { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } in_uint16_be(c->in_s, cmd); if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ { log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); return SCP_SERVER_STATE_MNG_LISTREQ; } else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ { /*in_uint8(c->in_s, dim); buf[dim]='\0'; in_uint8a(c->in_s, buf, dim); scp_session_set_errstr(s, buf);*/ log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); return SCP_SERVER_STATE_MNG_ACTION; } /* else if (cmd == 20) / * password change * / { in_uint16_be(c->in_s, s->display); return SCP_SERVER_STATE_OK; } else if (cmd == 40) / * session list * / { return SCP_SERVER_STATE_SESSION_LIST; }*/ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; }
/* 006 */ enum SCP_SERVER_STATES_E scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s, int sescnt, struct SCP_DISCONNECTED_SESSION *ds) { tui32 version = 1; tui32 size = 12; tui16 cmd = SCP_CMD_MNG_LIST; int pktcnt; int idx; int sidx; int pidx; struct SCP_DISCONNECTED_SESSION *cds; /* calculating the number of packets to send */ pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE; if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0) { pktcnt++; } for (idx = 0; idx < pktcnt; idx++) { /* ok, we send session session list */ init_stream(c->out_s, c->out_s->size); /* size: ver+size+cmdset+cmd+sescnt+continue+count */ size = 4 + 4 + 2 + 2 + 4 + 1 + 1; /* header */ s_push_layer(c->out_s, channel_hdr, 8); out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); out_uint16_be(c->out_s, cmd); /* session count */ out_uint32_be(c->out_s, sescnt); /* setting the continue flag */ if ((idx + 1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt) { out_uint8(c->out_s, 0); /* setting session count for this packet */ pidx = sescnt - (idx * SCP_SERVER_MAX_LIST_SIZE); out_uint8(c->out_s, pidx); } else { out_uint8(c->out_s, 1); /* setting session count for this packet */ pidx = SCP_SERVER_MAX_LIST_SIZE; out_uint8(c->out_s, pidx); } /* adding session descriptors */ for (sidx = 0; sidx < pidx; sidx++) { /* shortcut to the current session to send */ cds = ds + ((idx) * SCP_SERVER_MAX_LIST_SIZE) + sidx; /* session data */ out_uint32_be(c->out_s, cds->SID); /* session id */ out_uint8(c->out_s, cds->type); out_uint16_be(c->out_s, cds->height); out_uint16_be(c->out_s, cds->width); out_uint8(c->out_s, cds->bpp); out_uint8(c->out_s, cds->idle_days); out_uint8(c->out_s, cds->idle_hours); out_uint8(c->out_s, cds->idle_minutes); size += 13; out_uint16_be(c->out_s, cds->conn_year); out_uint8(c->out_s, cds->conn_month); out_uint8(c->out_s, cds->conn_day); out_uint8(c->out_s, cds->conn_hour); out_uint8(c->out_s, cds->conn_minute); out_uint8(c->out_s, cds->addr_type); size += 7; if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->out_s, cds->ipv4addr); size += 4; } else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) { in_uint8a(c->out_s, cds->ipv6addr, 16); size += 16; } } s_pop_layer(c->out_s, channel_hdr); out_uint32_be(c->out_s, version); out_uint32_be(c->out_s, size); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } return _scp_v1s_mng_check_response(c, s); }