/* Process a new licence packet */ static void licence_process_new_license(STREAM s) { RDSSL_RC4 crypt_key; uint32 length; int i; in_uint8s(s, 2); // Skip license binary blob type in_uint16_le(s, length); if (!s_check_rem(s, length)) return; rdssl_rc4_set_key(&crypt_key, g_licence_key, 16); rdssl_rc4_crypt(&crypt_key, s->p, s->p, length); /* Parse NEW_LICENSE_INFO block */ in_uint8s(s, 4); // skip dwVersion /* Skip strings, Scope, CompanyName and ProductId to get to the LicenseInfo which we store in license blob. */ length = 0; for (i = 0; i < 4; i++) { in_uint8s(s, length); in_uint32_le(s, length); if (!s_check_rem(s, length)) return; } g_licence_issued = True; save_licence(s->p, length); }
/* returns error */ static int APP_CC process_message(void) { struct stream *s = (struct stream *)NULL; int size = 0; int id = 0; int rv = 0; char *next_msg = (char *)NULL; if (g_con_trans == 0) { return 1; } s = trans_get_in_s(g_con_trans); if (s == 0) { return 1; } rv = 0; while (s_check_rem(s, 8)) { next_msg = s->p; in_uint32_le(s, id); in_uint32_le(s, size); next_msg += size; switch (id) { case 1: /* init */ rv = process_message_init(s); break; case 3: /* channel setup */ rv = process_message_channel_setup(s); break; case 5: /* channel data */ rv = process_message_channel_data(s); break; case 7: /* channel data response */ rv = process_message_channel_data_response(s); break; default: LOGM((LOG_LEVEL_ERROR, "process_message: error in process_message ", "unknown msg %d", id)); break; } if (rv != 0) { break; } s->p = next_msg; } return rv; }
int clipboard_c2s_in_files(struct stream *s, char *file_list) { int cItems; int lindex; int str_len; struct clip_file_desc *cfd; char *ptr; if (!s_check_rem(s, 4)) { LLOGLN(0, ("clipboard_c2s_in_files: parse error")); return 1; } in_uint32_le(s, cItems); if (cItems > 64 * 1024) /* sanity check */ { LLOGLN(0, ("clipboard_c2s_in_files: error cItems %d too big", cItems)); return 1; } xfuse_clear_clip_dir(); LLOGLN(10, ("clipboard_c2s_in_files: cItems %d", cItems)); cfd = (struct clip_file_desc *) g_malloc(sizeof(struct clip_file_desc), 0); ptr = file_list; for (lindex = 0; lindex < cItems; lindex++) { g_memset(cfd, 0, sizeof(struct clip_file_desc)); clipboard_c2s_in_file_info(s, cfd); if ((g_pos(cfd->cFileName, "\\") >= 0) || (cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY)) { LLOGLN(0, ("clipboard_c2s_in_files: skipping directory not " "supported [%s]", cfd->cFileName)); continue; } xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex); g_strcpy(ptr, "file://"); ptr += 7; str_len = g_strlen(g_fuse_clipboard_path); g_strcpy(ptr, g_fuse_clipboard_path); ptr += str_len; *ptr = '/'; ptr++; str_len = g_strlen(cfd->cFileName); g_strcpy(ptr, cfd->cFileName); ptr += str_len; *ptr = '\n'; ptr++; } *ptr = 0; g_free(cfd); return 0; }
/* Process a Server New (or Upgrade) License packet */ static void licence_process_new_license(rdpLicence * licence, STREAM s) { int i; uint32 length; uint32 os_major; uint32 os_minor; CryptoRc4 crypt_key; /* Licensing Binary BLOB with EncryptedLicenseInfo: */ in_uint8s(s, 2); /* wBlobType should be 0x0009 (BB_ENCRYPTED_DATA_BLOB) */ in_uint16_le(s, length); /* wBlobLen */ /* RC4-encrypted New License Information */ if (!s_check_rem(s, length)) return; crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, length, s->p, s->p); /* decrypt in place */ crypto_rc4_free(crypt_key); /* dwVersion */ in_uint16_le(s, os_major); /* OS major version */ in_uint16_le(s, os_minor); /* OS minor version */ /* Skip Scope, CompanyName and ProductId */ for (i = 0; i < 3; i++) { in_uint32_le(s, length); if (!s_check_rem(s, length)) return; in_uint8s(s, length); } /* LicenseInfo - CAL from license server */ in_uint32_le(s, length); if (!s_check_rem(s, length)) return; licence->licence_issued = True; save_licence(s->p, length); }
/* returns error */ static int APP_CC process_message(void) { struct stream* s; int size; int id; int rv; char* next_msg; if (g_con_trans == 0) { return 1; } s = trans_get_in_s(g_con_trans); if (s == 0) { return 1; } rv = 0; while (s_check_rem(s, 8)) { next_msg = s->p; in_uint32_le(s, id); in_uint32_le(s, size); next_msg += size; switch (id) { case 1: /* init */ rv = process_message_init(s); break; case 3: /* channel setup */ rv = process_message_channel_setup(s); break; case 5: /* channel data */ rv = process_message_channel_data(s); break; case 7: /* channel data response */ rv = process_message_channel_data_response(s); break; default: log_message(&log_conf, LOG_LEVEL_DEBUG, "chansrv[process_message]: " "unknown msg %d", id); break; } if (rv != 0) { break; } s->p = next_msg; } return rv; }
/* Process an licence issue packet */ static void licence_process_issue(STREAM s) { void * crypt_key; uint32 length; uint16 check; int i; in_uint8s(s, 2); /* 3d 45 - unknown */ in_uint16_le(s, length); if (!s_check_rem(s, length)) return; crypt_key = ssl_rc4_info_create(); ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); ssl_rc4_crypt(crypt_key, (char *)s->p, (char *)s->p, length); ssl_rc4_info_delete(crypt_key); in_uint16(s, check); if (check != 0) return; g_licence_issued = True; in_uint8s(s, 2); /* pad */ /* advance to fourth string */ length = 0; for (i = 0; i < 4; i++) { in_uint8s(s, length); in_uint32_le(s, length); if (!s_check_rem(s, length)) return; } g_licence_issued = True; save_licence(s->p, length); }
/* Process an licence issue packet */ static void licence_process_issue(RDPCLIENT * This, STREAM s) { RC4_KEY crypt_key; uint32 length; uint16 check; int i; in_uint8s(s, 2); /* 3d 45 - unknown */ in_uint16_le(s, length); if (!s_check_rem(s, length)) return; RC4_set_key(&crypt_key, 16, This->licence.key); RC4(&crypt_key, length, s->p, s->p); in_uint16(s, check); if (check != 0) return; This->licence_issued = True; in_uint8s(s, 2); /* pad */ /* advance to fourth string */ length = 0; for (i = 0; i < 4; i++) { in_uint8s(s, length); in_uint32_le(s, length); if (!s_check_rem(s, length)) return; } This->licence_issued = True; save_licence(This, s->p, length); }
/* Process an licence issue packet */ static void licence_process_issue(RDConnectionRef conn, RDStreamRef s) { RC4_KEY crypt_key; uint32 length; uint16 check; int i; in_uint8s(s, 2); /* 3d 45 - unknown */ in_uint16_le(s, length); if (!s_check_rem(s, length)) return; RC4_set_key(&crypt_key, 16, conn->licenseKey); RC4(&crypt_key, length, s->p, s->p); in_uint16(s, check); if (check != 0) return; conn->licenseIssued = True; in_uint8s(s, 2); /* pad */ /* advance to fourth string */ length = 0; for (i = 0; i < 4; i++) { in_uint8s(s, length); in_uint32_le(s, length); if (!s_check_rem(s, length)) return; } conn->licenseIssued = True; save_licence(s->p, length); }
/* returns error process a message for the channel handler */ static int APP_CC xrdp_mm_chan_process_msg(struct xrdp_mm* self, struct trans* trans, struct stream* s) { int rv = 0; int id = 0; int size = 0; char* next_msg = (char *)NULL; rv = 0; while (s_check_rem(s, 8)) { next_msg = s->p; in_uint32_le(s, id); in_uint32_le(s, size); next_msg += size; switch (id) { case 2: /* channel init response */ rv = xrdp_mm_trans_process_init_response(self, trans); break; case 4: /* channel setup response */ break; case 6: /* channel data response */ break; case 8: /* channel data */ rv = xrdp_mm_trans_process_channel_data(self, trans); break; default: g_writeln("xrdp_mm_chan_process_msg: unknown id %d", id); break; } if (rv != 0) { break; } s->p = next_msg; } return rv; }
/* Process an licence issue packet */ static void licence_process_issue(STREAM s) { RC4_KEY crypt_key; uint32 length; uint16 check; in_uint8s(s, 2); /* 3d 45 - unknown */ in_uint16_le(s, length); if (!s_check_rem(s, length)) return; RC4_set_key(&crypt_key, 16, licence_key); RC4(&crypt_key, length, s->p, s->p); in_uint16(s, check); if (check != 0) return; licence_issued = True; save_licence(s->p, length-2); }
/* Establish a connection up to the ISO layer */ RD_BOOL iso_connect(char *server, char *username, RD_BOOL reconnect, uint32 * selected_protocol) { STREAM s; uint8 code; g_negotiate_rdp_protocol = True; retry: *selected_protocol = PROTOCOL_RDP; code = 0; if (!tcp_connect(server)) return False; if (reconnect) { iso_send_msg(ISO_PDU_CR); } else { iso_send_connection_request(username); } s = iso_recv_msg(&code, NULL); if (s == NULL) return False; if (code != ISO_PDU_CC) { error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8)) { /* handle RDP_NEG_REQ response */ const char *reason = NULL; uint8 type = 0, flags = 0; uint16 length = 0; uint32 data = 0; in_uint8(s, type); in_uint8(s, flags); in_uint16(s, length); in_uint32(s, data); if (type == RDP_NEG_FAILURE) { switch (data) { case SSL_REQUIRED_BY_SERVER: reason = "SSL required by server"; break; case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER: reason = "SSL with user authentication required by server"; break; case SSL_NOT_ALLOWED_BY_SERVER: reason = "SSL not allowed by server"; break; case SSL_CERT_NOT_ON_SERVER: reason = "SSL certificated not on server"; break; case INCONSISTENT_FLAGS: reason = "inconsistent flags"; break; case HYBRID_REQUIRED_BY_SERVER: reason = "hybrid authentication (CredSSP) required by server"; break; default: reason = "unknown reason"; } tcp_disconnect(); warning("RDP protocol negotiation failed with reason: %s (error 0x%x),\n", reason, data); warning("retrying without negotiation using plain RDP protocol.\n"); g_negotiate_rdp_protocol = False; goto retry; } if (type != RDP_NEG_RSP) { tcp_disconnect(); error("expected RDP_NEG_RSP, got type = 0x%x\n", type); warning("retrying without negotiation using plain RDP protocol.\n"); g_negotiate_rdp_protocol = False; goto retry; } /* handle negotiation response */ if (data == PROTOCOL_SSL) { DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL\n")); if (!tcp_tls_connect()) { tcp_disconnect(); DEBUGMSG(1,(L"iso_connect: negotiation: PROTOCOL_SSL FAILED\n")); return False; } /* do not use encryption when using TLS */ g_encryption = False; } else if (data != PROTOCOL_RDP) { tcp_disconnect(); error("unexpected protocol in neqotiation response, got data = 0x%x.\n", data); return False; } *selected_protocol = data; } return True; }
int APP_CC xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s) { int cap_len; int source_len; int num_caps; int index; int type; int len; char *p; DEBUG(("in xrdp_caps_process_confirm_active")); in_uint8s(s, 4); /* rdp_shareid */ in_uint8s(s, 2); /* userid */ in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ in_uint16_le(s, cap_len); in_uint8s(s, source_len); in_uint16_le(s, num_caps); in_uint8s(s, 2); /* pad */ if ((cap_len < 0) || (cap_len > 1024 * 1024)) { return 1; } for (index = 0; index < num_caps; index++) { p = s->p; if (!s_check_rem(s, 4)) { g_writeln("xrdp_caps_process_confirm_active: error 1"); return 1; } in_uint16_le(s, type); in_uint16_le(s, len); if ((len < 4) || !s_check_rem(s, len - 4)) { g_writeln("xrdp_caps_process_confirm_active: error: len %d, " "remaining %d", len, (int) (s->end - s->p)); return 1; } len -= 4; switch (type) { case RDP_CAPSET_GENERAL: /* 1 */ DEBUG(("RDP_CAPSET_GENERAL")); xrdp_caps_process_general(self, s, len); break; case RDP_CAPSET_BITMAP: /* 2 */ DEBUG(("RDP_CAPSET_BITMAP")); break; case RDP_CAPSET_ORDER: /* 3 */ DEBUG(("RDP_CAPSET_ORDER")); xrdp_caps_process_order(self, s, len); break; case RDP_CAPSET_BMPCACHE: /* 4 */ DEBUG(("RDP_CAPSET_BMPCACHE")); xrdp_caps_process_bmpcache(self, s, len); break; case RDP_CAPSET_CONTROL: /* 5 */ DEBUG(("RDP_CAPSET_CONTROL")); break; case 6: xrdp_caps_process_cache_v3_codec_id(self, s, len); break; case RDP_CAPSET_ACTIVATE: /* 7 */ DEBUG(("RDP_CAPSET_ACTIVATE")); break; case RDP_CAPSET_POINTER: /* 8 */ DEBUG(("RDP_CAPSET_POINTER")); xrdp_caps_process_pointer(self, s, len); break; case RDP_CAPSET_SHARE: /* 9 */ DEBUG(("RDP_CAPSET_SHARE")); break; case RDP_CAPSET_COLCACHE: /* 10 */ DEBUG(("RDP_CAPSET_COLCACHE")); break; case 12: /* 12 */ DEBUG(("--12")); break; case 13: /* 13 */ xrdp_caps_process_input(self, s, len); break; case 14: /* 14 */ DEBUG(("--14")); break; case RDP_CAPSET_BRUSHCACHE: /* 15 */ xrdp_caps_process_brushcache(self, s, len); break; case 16: /* 16 */ DEBUG(("--16")); break; case 17: /* 17 */ DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); xrdp_caps_process_offscreen_bmpcache(self, s, len); break; case RDP_CAPSET_BMPCACHE2: /* 19 */ DEBUG(("RDP_CAPSET_BMPCACHE2")); xrdp_caps_process_bmpcache2(self, s, len); break; case 20: /* 20 */ DEBUG(("--20")); break; case 21: /* 21 */ DEBUG(("--21")); break; case 22: /* 22 */ DEBUG(("--22")); break; case 0x0017: /* 23 CAPSETTYPE_RAIL */ xrdp_caps_process_rail(self, s, len); break; case 0x0018: /* 24 CAPSETTYPE_WINDOW */ xrdp_caps_process_window(self, s, len); break; case 0x001A: /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */ xrdp_caps_process_multifragmentupdate(self, s, len); break; case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ xrdp_caps_process_codecs(self, s, len); break; case 0x001E: /* CAPSSETTYPE_FRAME_ACKNOWLEDGE */ xrdp_caps_process_frame_ack(self, s, len); break; case RDP_CAPSET_SURFCMDS: /* CAPSETTYPE_SURFACE_COMMANDS */ xrdp_caps_process_surface_cmds(self, s, len); break; default: g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); break; } s->p = p + len + 4; } if (self->client_info.no_orders_supported && (self->client_info.offscreen_support_level != 0)) { g_writeln("xrdp_caps_process_confirm_active: not enough orders " "supported by client, client wants off screen bitmap but " "offscreen bitmaps disabled"); self->client_info.offscreen_support_level = 0; self->client_info.offscreen_cache_size = 0; self->client_info.offscreen_cache_entries = 0; } DEBUG(("out xrdp_caps_process_confirm_active")); return 0; }
/* returns error */ static int APP_CC file_read_line(struct stream *s, char *text, int text_bytes) { int i; int skip_to_end; int at_end; char c; char *hold; skip_to_end = 0; if (!s_check_rem(s, 1)) { return 1; } hold = s->p; i = 0; in_uint8(s, c); while (c != 10 && c != 13) { /* these mean skip the rest of the line */ if (c == '#' || c == '!' || c == ';') { skip_to_end = 1; } if (!skip_to_end) { text[i] = c; i++; if (i >= text_bytes) { return 1; } } if (s_check_rem(s, 1)) { in_uint8(s, c); } else { c = 0; break; } } if (c == 10 || c == 13) { at_end = 0; while (c == 10 || c == 13) { if (s_check_rem(s, 1)) { in_uint8(s, c); } else { at_end = 1; break; } } if (!at_end) { s->p--; } } text[i] = 0; if (text[0] == '[') { s->p = hold; return 1; } return 0; }
static void cliprdr_process(STREAM s) { uint16 type, status; uint32 length, format; uint8 *data; struct stream packet = *s; in_uint16_le(s, type); in_uint16_le(s, status); in_uint32_le(s, length); data = s->p; DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length)); if (!s_check_rem(s, length)) { rdp_protocol_error("cliprdr_process(), consume of packet from stream would overrun", &packet); } if (status == CLIPRDR_ERROR) { switch (type) { case CLIPRDR_FORMAT_ACK: /* FIXME: We seem to get this when we send an announce while the server is still processing a paste. Try sending another announce. */ cliprdr_send_native_format_announce(last_formats, last_formats_length); break; case CLIPRDR_DATA_RESPONSE: ui_clip_request_failed(); break; default: DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type)); } return; } switch (type) { case CLIPRDR_CONNECT: ui_clip_sync(); break; case CLIPRDR_FORMAT_ANNOUNCE: ui_clip_format_announce(data, length); cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0); return; case CLIPRDR_FORMAT_ACK: break; case CLIPRDR_DATA_REQUEST: in_uint32_le(s, format); ui_clip_request_data(format); break; case CLIPRDR_DATA_RESPONSE: ui_clip_handle_data(data, length); break; case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */ break; default: unimpl("CLIPRDR packet type %d\n", type); } }
void rdpsnd_process_negotiate(STREAM in) { unsigned int in_format_count, i; WAVEFORMATEX *format; STREAM out; BOOL device_available = False; int readcnt; int discardcnt; in_uint8s(in, 14); /* flags, volume, pitch, UDP port */ in_uint16_le(in, in_format_count); in_uint8s(in, 4); /* pad, status, pad */ if (wave_out_open()) { wave_out_close(); device_available = True; } format_count = 0; if (s_check_rem(in, 18 * in_format_count)) { for (i = 0; i < in_format_count; i++) { format = &formats[format_count]; in_uint16_le(in, format->wFormatTag); in_uint16_le(in, format->nChannels); in_uint32_le(in, format->nSamplesPerSec); in_uint32_le(in, format->nAvgBytesPerSec); in_uint16_le(in, format->nBlockAlign); in_uint16_le(in, format->wBitsPerSample); in_uint16_le(in, format->cbSize); /* read in the buffer of unknown use */ readcnt = format->cbSize; discardcnt = 0; if (format->cbSize > MAX_CBSIZE) { fprintf(stderr, "cbSize too large for buffer: %d\n", format->cbSize); readcnt = MAX_CBSIZE; discardcnt = format->cbSize - MAX_CBSIZE; } in_uint8a(in, format->cb, readcnt); in_uint8s(in, discardcnt); if (device_available && wave_out_format_supported(format)) { format_count++; if (format_count == MAX_FORMATS) break; } } } out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count); out_uint32_le(out, 3); /* flags */ out_uint32(out, 0xffffffff); /* volume */ out_uint32(out, 0); /* pitch */ out_uint16(out, 0); /* UDP port */ out_uint16_le(out, format_count); out_uint8(out, 0x95); /* pad? */ out_uint16_le(out, 2); /* status */ out_uint8(out, 0x77); /* pad? */ for (i = 0; i < format_count; i++) { format = &formats[i]; out_uint16_le(out, format->wFormatTag); out_uint16_le(out, format->nChannels); out_uint32_le(out, format->nSamplesPerSec); out_uint32_le(out, format->nAvgBytesPerSec); out_uint16_le(out, format->nBlockAlign); out_uint16_le(out, format->wBitsPerSample); out_uint16(out, 0); /* cbSize */ } s_mark_end(out); rdpsnd_send(out); }
/* return error */ static int APP_CC l_file_read_section(int fd, int max_file_size, const char *section, struct list *names, struct list *values) { struct stream *s; char *data; char *text; char *name; char *value; char *lvalue; char c; int in_it; int in_it_index; int len; int index; int file_size; data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0); text = data; name = text + FILE_MAX_LINE_BYTES; value = name + FILE_MAX_LINE_BYTES; file_size = 32 * 1024; /* 32 K file size limit */ g_file_seek(fd, 0); in_it_index = 0; in_it = 0; g_memset(text, 0, FILE_MAX_LINE_BYTES); list_clear(names); list_clear(values); make_stream(s); init_stream(s, file_size); len = g_file_read(fd, s->data, file_size); if (len > 0) { s->end = s->p + len; for (index = 0; index < len; index++) { if (!s_check_rem(s, 1)) { break; } in_uint8(s, c); if ((c == '#') || (c == ';')) { if (file_read_line(s, text, FILE_MAX_LINE_BYTES) != 0) { break; } in_it = 0; in_it_index = 0; g_memset(text, 0, FILE_MAX_LINE_BYTES); continue; } if (c == '[') { in_it = 1; } else if (c == ']') { if (g_strcasecmp(section, text) == 0) { file_read_line(s, text, FILE_MAX_LINE_BYTES); while (file_read_line(s, text, FILE_MAX_LINE_BYTES) == 0) { if (g_strlen(text) > 0) { file_split_name_value(text, name, value); list_add_item(names, (tbus)g_strdup(name)); if (value[0] == '$') { lvalue = g_getenv(value + 1); if (lvalue != 0) { list_add_item(values, (tbus)g_strdup(lvalue)); } else { list_add_item(values, (tbus)g_strdup("")); } } else { list_add_item(values, (tbus)g_strdup(value)); } } } free_stream(s); g_free(data); return 0; } in_it = 0; in_it_index = 0; g_memset(text, 0, FILE_MAX_LINE_BYTES); } else if (in_it) { text[in_it_index] = c; in_it_index++; if (in_it_index >= FILE_MAX_LINE_BYTES) { break; } } } } free_stream(s); g_free(data); return 1; }
static void rdpsnd_process_negotiate(STREAM in) { uint16 in_format_count, i; uint8 pad; uint16 version; RD_WAVEFORMATEX *format; STREAM out; RD_BOOL device_available = False; int readcnt; int discardcnt; in_uint8s(in, 14); /* initial bytes not valid from server */ in_uint16_le(in, in_format_count); in_uint8(in, pad); in_uint16_le(in, version); in_uint8s(in, 1); /* padding */ DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n", (int) in_format_count, (unsigned) pad, (unsigned) version)); if (rdpsnd_negotiated) { error("RDPSND: Extra RDPSND_NEGOTIATE in the middle of a session\n"); /* Do a complete reset of the sound state */ rdpsnd_reset_state(); } if (!current_driver && g_rdpsnd) device_available = rdpsnd_auto_select(); if (current_driver && !device_available && current_driver->wave_out_open()) { current_driver->wave_out_close(); device_available = True; } format_count = 0; if (s_check_rem(in, 18 * in_format_count)) { for (i = 0; i < in_format_count; i++) { format = &formats[format_count]; in_uint16_le(in, format->wFormatTag); in_uint16_le(in, format->nChannels); in_uint32_le(in, format->nSamplesPerSec); in_uint32_le(in, format->nAvgBytesPerSec); in_uint16_le(in, format->nBlockAlign); in_uint16_le(in, format->wBitsPerSample); in_uint16_le(in, format->cbSize); /* read in the buffer of unknown use */ readcnt = format->cbSize; discardcnt = 0; if (format->cbSize > MAX_CBSIZE) { fprintf(stderr, "cbSize too large for buffer: %d\n", format->cbSize); readcnt = MAX_CBSIZE; discardcnt = format->cbSize - MAX_CBSIZE; } in_uint8a(in, format->cb, readcnt); in_uint8s(in, discardcnt); if (current_driver && current_driver->wave_out_format_supported(format)) { format_count++; if (format_count == MAX_FORMATS) break; } } } out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count); uint32 flags = TSSNDCAPS_VOLUME; /* if sound is enabled, set snd caps to alive to enable transmision of audio from server */ if (g_rdpsnd) { flags |= TSSNDCAPS_ALIVE; } out_uint32_le(out, flags); /* TSSNDCAPS flags */ out_uint32(out, 0xffffffff); /* volume */ out_uint32(out, 0); /* pitch */ out_uint16(out, 0); /* UDP port */ out_uint16_le(out, format_count); out_uint8(out, 0); /* padding */ out_uint16_le(out, 2); /* version */ out_uint8(out, 0); /* padding */ for (i = 0; i < format_count; i++) { format = &formats[i]; out_uint16_le(out, format->wFormatTag); out_uint16_le(out, format->nChannels); out_uint32_le(out, format->nSamplesPerSec); out_uint32_le(out, format->nAvgBytesPerSec); out_uint16_le(out, format->nBlockAlign); out_uint16_le(out, format->wBitsPerSample); out_uint16(out, 0); /* cbSize */ } s_mark_end(out); DEBUG_SOUND(("RDPSND: -> RDPSND_NEGOTIATE(formats: %d)\n", (int) format_count)); rdpsnd_send(out); rdpsnd_negotiated = True; }
static void rdpsnd_process_rec_negotiate(STREAM in) { uint16 in_format_count, i; uint16 version; RD_WAVEFORMATEX *format; STREAM out; RD_BOOL device_available = False; int readcnt; int discardcnt; in_uint8s(in, 8); /* initial bytes not valid from server */ in_uint16_le(in, in_format_count); in_uint16_le(in, version); DEBUG_SOUND(("RDPSND: RDPSND_REC_NEGOTIATE(formats: %d, version: %x)\n", (int) in_format_count, (unsigned) version)); if (rdpsnd_rec_negotiated) { error( "RDPSND: Extra RDPSND_REC_NEGOTIATE in the middle of a session\n"); /* Do a complete reset of the sound state */ rdpsnd_reset_state(); } if (!current_driver) device_available = rdpsnd_auto_select(); if (current_driver && !device_available && current_driver->wave_in_open && current_driver->wave_in_open()) { current_driver->wave_in_close(); device_available = True; } rec_format_count = 0; if (s_check_rem(in, 18 * in_format_count)) { for (i = 0; i < in_format_count; i++) { format = &rec_formats[rec_format_count]; in_uint16_le(in, format->wFormatTag); in_uint16_le(in, format->nChannels); in_uint32_le(in, format->nSamplesPerSec); in_uint32_le(in, format->nAvgBytesPerSec); in_uint16_le(in, format->nBlockAlign); in_uint16_le(in, format->wBitsPerSample); in_uint16_le(in, format->cbSize); /* read in the buffer of unknown use */ readcnt = format->cbSize; discardcnt = 0; if (format->cbSize > MAX_CBSIZE) { fprintf(stderr, "cbSize too large for buffer: %d\n", format->cbSize); readcnt = MAX_CBSIZE; discardcnt = format->cbSize - MAX_CBSIZE; }in_uint8a(in, format->cb, readcnt); in_uint8s(in, discardcnt); if (current_driver && current_driver->wave_in_format_supported && current_driver->wave_in_format_supported(format)) { rec_format_count++; if (rec_format_count == MAX_FORMATS ) break; } } } out = rdpsnd_init_packet(RDPSND_REC_NEGOTIATE, 12 + 18 * rec_format_count); out_uint32_le(out, 0x00000000); /* flags */ out_uint32_le(out, 0xffffffff); /* volume */ out_uint16_le(out, rec_format_count); out_uint16_le(out, 1); /* version */ for (i = 0; i < rec_format_count; i++) { format = &rec_formats[i]; out_uint16_le(out, format->wFormatTag); out_uint16_le(out, format->nChannels); out_uint32_le(out, format->nSamplesPerSec); out_uint32_le(out, format->nAvgBytesPerSec); out_uint16_le(out, format->nBlockAlign); out_uint16_le(out, format->wBitsPerSample); out_uint16(out, 0); /* cbSize */ } s_mark_end(out); DEBUG_SOUND(("RDPSND: -> RDPSND_REC_NEGOTIATE(formats: %d)\n", (int) rec_format_count)); rdpsnd_send(out); rdpsnd_rec_negotiated = True; }
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; }
/* return error */ static int l_file_read_section(int fd, int max_file_size, const char *section, xrdpList *names, xrdpList *values) { struct stream *s; char text[512]; char name[512]; char value[512]; char *lvalue; char c; int in_it; int in_it_index; int len; int index; int file_size; file_size = 32 * 1024; /* 32 K file size limit */ g_file_seek(fd, 0); in_it_index = 0; in_it = 0; g_memset(text, 0, 512); list_clear(names); list_clear(values); make_stream(s); init_stream(s, file_size); len = g_file_read(fd, s->data, file_size); if (len > 0) { s->end = s->p + len; for (index = 0; index < len; index++) { if (!s_check_rem(s, 1)) { break; } in_uint8(s, c); if ((c == '#') || (c == ';')) { file_read_line(s, text); in_it = 0; in_it_index = 0; g_memset(text, 0, 512); continue; } if (c == '[') { in_it = 1; } else if (c == ']') { if (g_strcasecmp(section, text) == 0) { file_read_line(s, text); while (file_read_line(s, text) == 0) { if (g_strlen(text) > 0) { file_split_name_value(text, name, value); list_add_item(names, (tbus) g_strdup(name)); if (value[0] == '$') { lvalue = g_getenv(value + 1); if (lvalue != 0) { list_add_item(values, (tbus) g_strdup(lvalue)); } else { list_add_item(values, (tbus) g_strdup("")); } } else { list_add_item(values, (tbus) g_strdup(value)); } } } free_stream(s); return 0; } in_it = 0; in_it_index = 0; g_memset(text, 0, 512); } else if (in_it) { text[in_it_index] = c; in_it_index++; } } } free_stream(s); return 1; }
/* Establish a connection up to the ISO layer */ RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 * selected_protocol) { STREAM s; uint8 code; uint32 neg_proto; g_negotiate_rdp_protocol = True; neg_proto = PROTOCOL_SSL; #ifdef WITH_CREDSSP if (!g_use_password_as_pin) neg_proto |= PROTOCOL_HYBRID; else if (g_sc_csp_name || g_sc_reader_name || g_sc_card_name || g_sc_container_name) neg_proto |= PROTOCOL_HYBRID; else warning("Disables CredSSP due to missing smartcard information for SSO.\n"); #endif retry: *selected_protocol = PROTOCOL_RDP; code = 0; if (!tcp_connect(server)) return False; iso_send_connection_request(username, neg_proto); s = iso_recv_msg(&code, NULL); if (s == NULL) return False; if (code != ISO_PDU_CC) { error("expected CC, got 0x%x\n", code); tcp_disconnect(); return False; } if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8)) { /* handle RDP_NEG_REQ response */ const char *reason = NULL; uint8 type = 0, flags = 0; uint16 length = 0; uint32 data = 0; in_uint8(s, type); in_uint8(s, flags); in_uint16(s, length); in_uint32(s, data); if (type == RDP_NEG_FAILURE) { RD_BOOL retry_without_neg = False; switch (data) { case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER: reason = "SSL with user authentication required by server"; break; case SSL_NOT_ALLOWED_BY_SERVER: reason = "SSL not allowed by server"; retry_without_neg = True; break; case SSL_CERT_NOT_ON_SERVER: reason = "no valid authentication certificate on server"; retry_without_neg = True; break; case INCONSISTENT_FLAGS: reason = "inconsistent negotiation flags"; break; case SSL_REQUIRED_BY_SERVER: reason = "SSL required by server"; break; case HYBRID_REQUIRED_BY_SERVER: reason = "CredSSP required by server"; break; default: reason = "unknown reason"; } tcp_disconnect(); if (retry_without_neg) { fprintf(stderr, "Failed to negotiate protocol, retrying with plain RDP.\n"); g_negotiate_rdp_protocol = False; goto retry; } fprintf(stderr, "Failed to connect, %s.\n", reason); return False; } if (type != RDP_NEG_RSP) { tcp_disconnect(); error("Expected RDP_NEG_RSP, got type = 0x%x\n", type); return False; } /* handle negotiation response */ if (data == PROTOCOL_SSL) { if (!tcp_tls_connect()) { /* failed to connect using cssp, let retry with plain TLS */ tcp_disconnect(); neg_proto = PROTOCOL_RDP; goto retry; } /* do not use encryption when using TLS */ g_encryption = False; fprintf(stderr, "Connection established using SSL.\n"); } #ifdef WITH_CREDSSP else if (data == PROTOCOL_HYBRID) { if (!cssp_connect(server, username, domain, password, s)) { /* failed to connect using cssp, let retry with plain TLS */ tcp_disconnect(); neg_proto = PROTOCOL_SSL; goto retry; } /* do not use encryption when using TLS */ fprintf(stderr, "Connection established using CredSSP.\n"); g_encryption = False; } #endif else if (data == PROTOCOL_RDP) { fprintf(stderr, "Connection established using plain RDP.\n"); } else if (data != PROTOCOL_RDP) { tcp_disconnect(); error("Unexpected protocol in negotiation response, got data = 0x%x.\n", data); return False; } *selected_protocol = data; } return True; }
static int file_read_line(struct stream *s, char *text) { int i; int skip_to_end; int at_end; char c; char *hold; skip_to_end = 0; if (!s_check_rem(s, 1)) { return 1; } hold = s->p; i = 0; in_uint8(s, c); while (c != 10 && c != 13) { if (c == '#' || c == '!' || c == ';') { skip_to_end = 1; } if (!skip_to_end) { text[i] = c; i++; } if (s_check_rem(s, 1)) { in_uint8(s, c); } else { c = 0; break; } } if (c == 10 || c == 13) { at_end = 0; while (c == 10 || c == 13) { if (s_check_rem(s, 1)) { in_uint8(s, c); } else { at_end = 1; break; } } if (!at_end) { s->p--; } } text[i] = 0; if (text[0] == '[') { s->p = hold; return 1; } return 0; }
int xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s) { int cap_len; int source_len; int num_caps; int index; int type; int len; char *p; DEBUG(("in xrdp_caps_process_confirm_active")); in_uint8s(s, 4); /* rdp_shareid */ in_uint8s(s, 2); /* userid */ in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ in_uint16_le(s, cap_len); in_uint8s(s, source_len); in_uint16_le(s, num_caps); in_uint8s(s, 2); /* pad */ if ((cap_len < 0) || (cap_len > 1024 * 1024)) { return 1; } for (index = 0; index < num_caps; index++) { p = s->p; if (!s_check_rem(s, 4)) { g_writeln("xrdp_caps_process_confirm_active: error 1"); return 1; } in_uint16_le(s, type); in_uint16_le(s, len); if ((len < 4) || !s_check_rem(s, len - 4)) { g_writeln("xrdp_caps_process_confirm_active: error: len %d, " "remaining %d", len, (int) (s->end - s->p)); return 1; } len -= 4; switch (type) { case CAPSTYPE_GENERAL: DEBUG(("CAPSTYPE_GENERAL")); xrdp_caps_process_general(self, s, len); break; case CAPSTYPE_BITMAP: DEBUG(("CAPSTYPE_BITMAP")); break; case CAPSTYPE_ORDER: DEBUG(("CAPSTYPE_ORDER")); xrdp_caps_process_order(self, s, len); break; case CAPSTYPE_BITMAPCACHE: DEBUG(("CAPSTYPE_BMPCACHE")); xrdp_caps_process_bmpcache(self, s, len); break; case CAPSTYPE_CONTROL: DEBUG(("CAPSTYPE_CONTROL")); break; case 6: xrdp_caps_process_cache_v3_codec_id(self, s, len); break; case CAPSTYPE_ACTIVATION: DEBUG(("CAPSTYPE_ACTIVAION")); break; case CAPSTYPE_POINTER: DEBUG(("CAPSTYPE_POINTER")); xrdp_caps_process_pointer(self, s, len); break; case CAPSTYPE_SHARE: DEBUG(("CAPSTYPE_SHARE")); break; case CAPSTYPE_COLORCACHE: DEBUG(("CAPSTYPE_COLORCACHE")); break; case CAPSTYPE_SOUND: DEBUG(("CAPSTYPE_SOUND")); break; case CAPSTYPE_INPUT: xrdp_caps_process_input(self, s, len); break; case CAPSTYPE_FONT: DEBUG(("CAPSTYPE_FONT")); break; case CAPSTYPE_BRUSH: xrdp_caps_process_brushcache(self, s, len); break; case CAPSTYPE_GLYPHCACHE: DEBUG(("CAPSTYPE_GLYPHCACHE")); xrdp_caps_process_glyphcache(self, s, len); break; case CAPSTYPE_OFFSCREENCACHE: DEBUG(("CAPSTYPE_OFFSCREENCACHE")); xrdp_caps_process_offscreen_bmpcache(self, s, len); break; case CAPSTYPE_BITMAPCACHE_REV2: DEBUG(("CAPSTYPE_BITMAPCACHE_REV2")); xrdp_caps_process_bmpcache2(self, s, len); break; case CAPSTYPE_VIRTUALCHANNEL: DEBUG(("CAPSTYPE_VIRTUALCHANNEL")); break; case CAPSTYPE_DRAWNINGRIDCACHE: DEBUG(("CAPSTYPE_DRAWNINGRIDCACHE")); break; case CAPSTYPE_DRAWGDIPLUS: DEBUG(("CAPSTYPE_DRAWGDIPLUS")); break; case CAPSTYPE_RAIL: xrdp_caps_process_rail(self, s, len); break; case CAPSTYPE_WINDOW: xrdp_caps_process_window(self, s, len); break; case CAPSSETTYPE_MULTIFRAGMENTUPDATE: xrdp_caps_process_multifragmentupdate(self, s, len); break; case CAPSETTYPE_SURFACE_COMMANDS: xrdp_caps_process_surface_cmds(self, s, len); break; case CAPSSETTYPE_BITMAP_CODECS: xrdp_caps_process_codecs(self, s, len); break; case CAPSTYPE_FRAME_ACKNOWLEDGE: xrdp_caps_process_frame_ack(self, s, len); break; default: g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); break; } s->p = p + len + 4; } if (self->client_info.no_orders_supported && (self->client_info.offscreen_support_level != 0)) { g_writeln("xrdp_caps_process_confirm_active: not enough orders " "supported by client, client wants off screen bitmap but " "offscreen bitmaps disabled"); self->client_info.offscreen_support_level = 0; self->client_info.offscreen_cache_size = 0; self->client_info.offscreen_cache_entries = 0; } DEBUG(("out xrdp_caps_process_confirm_active")); return 0; }