/* Process a colour pointer PDU */ static void process_colour_pointer_common(STREAM s, int bpp) { uint16 width, height, cache_idx, masklen, datalen; uint16 x, y; uint8 *mask; uint8 *data; RD_HCURSOR cursor; in_uint16_le(s, cache_idx); in_uint16_le(s, x); in_uint16_le(s, y); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, masklen); in_uint16_le(s, datalen); in_uint8p(s, data, datalen); in_uint8p(s, mask, masklen); if ((width != 32) || (height != 32)) { warning("process_colour_pointer_common: " "width %d height %d\n", width, height); } /* keep hotspot within cursor bounding box */ x = MIN(x, width - 1); y = MIN(y, height - 1); cursor = ui_create_cursor(x, y, width, height, mask, data, bpp); ui_set_cursor(cursor); cache_put_cursor(cache_idx, cursor); }
/* Process a colour pointer PDU */ static void process_colour_pointer_common(STREAM s, int bpp) { uint16 width, height, cache_idx, masklen, datalen; sint16 x, y; uint8 *mask; uint8 *data; RD_HCURSOR cursor; in_uint16_le(s, cache_idx); in_uint16_le(s, x); in_uint16_le(s, y); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, masklen); in_uint16_le(s, datalen); in_uint8p(s, data, datalen); in_uint8p(s, mask, masklen); if ((width != 32) || (height != 32)) { warning("process_colour_pointer_common: " "width %d height %d\n", width, height); } /* sometimes x or y is out of bounds */ x = MAX(x, 0); x = MIN(x, width - 1); y = MAX(y, 0); y = MIN(y, height - 1); // TODO cursor = ui_create_cursor(x, y, width, height, mask, data, bpp); // TODO ui_set_cursor(cursor); cache_put_cursor(cache_idx, cursor); }
void rdp_process_bitmap_codecs_capset(rdpRdp * rdp, STREAM s, int size) { int num_codecs; int index; int codec_id; int codec_properties_size; uint8 * codec_guid; uint8 * codec_property; STREAM out_codec_s; //printf("rdp_process_bitmap_codecs_capset:\n"); //hexdump(s->p, size); in_uint8(s, num_codecs); for (index = 0; index < num_codecs; index++) { in_uint8p(s, codec_guid, 16); in_uint8(s, codec_id); in_uint16_le(s, codec_properties_size); in_uint8p(s, codec_property, codec_properties_size); out_codec_s = surface_codec_cap(rdp, codec_guid, codec_id, codec_property, codec_properties_size); if (out_codec_s != NULL) { if (rdp_caps_add_codec(rdp, out_codec_s) == 0) { //printf("rdp_process_bitmap_codecs_capset: added ok\n"); rdp->got_bitmap_codecs_caps = 1; } else { stream_delete(out_codec_s); } } } }
/* Process a bitmap cache order */ static void process_bmpcache(STREAM s) { HBITMAP bitmap; uint16 cache_idx, size; uint8 cache_id, width, height, bpp; uint8 *data, *bmpdata; in_uint8(s, cache_id); in_uint8s(s, 1); /* pad */ in_uint8(s, width); in_uint8(s, height); in_uint8(s, bpp); in_uint8s(s, 2); /* bufsize */ in_uint16_le(s, cache_idx); in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* row_size, final_size */ in_uint8p(s, data, size); DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); bmpdata = xmalloc(width * height); if (bitmap_decompress(bmpdata, width, height, data, size)) { bitmap = ui_create_bitmap(width, height, bmpdata); cache_put_bitmap(cache_id, cache_idx, bitmap); } xfree(bmpdata); }
/* Process a font cache order */ static void process_fontcache(STREAM s) { HGLYPH bitmap; uint8 font, nglyphs; uint16 character, offset, baseline, width, height; int i, datasize; uint8 *data; in_uint8(s, font); in_uint8(s, nglyphs); DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs)); for (i = 0; i < nglyphs; i++) { in_uint16_le(s, character); in_uint16_le(s, offset); in_uint16_le(s, baseline); in_uint16_le(s, width); in_uint16_le(s, height); datasize = (height * ((width + 7) / 8) + 3) & ~3; in_uint8p(s, data, datasize); bitmap = ui_create_glyph(width, height, data); cache_put_font(font, character, offset, baseline, width, height, bitmap); } }
/* return error */ static int APP_CC process_server_paint_rect(struct mod *mod, struct stream *s) { int rv; int x; int y; int cx; int cy; int len_bmpdata; char *bmpdata; int width; int height; int srcx; int srcy; in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_uint32_le(s, len_bmpdata); in_uint8p(s, bmpdata, len_bmpdata); in_uint16_le(s, width); in_uint16_le(s, height); in_sint16_le(s, srcx); in_sint16_le(s, srcy); rv = mod->server_paint_rect(mod, x, y, cx, cy, bmpdata, width, height, srcx, srcy); return rv; }
/* Process a raw bitmap cache order */ static void process_raw_bmpcache(STREAM s) { HBITMAP bitmap; uint16 cache_idx, bufsize; uint8 cache_id, width, height, bpp; uint8 *data, *inverted; int y; in_uint8(s, cache_id); in_uint8s(s, 1); /* pad */ in_uint8(s, width); in_uint8(s, height); in_uint8(s, bpp); in_uint16_le(s, bufsize); in_uint16_le(s, cache_idx); in_uint8p(s, data, bufsize); DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); inverted = xmalloc(width * height); for (y = 0; y < height; y++) { memcpy(&inverted[(height - y - 1) * width], &data[y * width], width); } bitmap = ui_create_bitmap(width, height, inverted); xfree(inverted); cache_put_bitmap(cache_id, cache_idx, bitmap); }
/* return error */ static int APP_CC process_server_add_char_alpha(struct mod *mod, struct stream *s) { int rv; int font; int charactor; int x; int y; int cx; int cy; int len_bmpdata; char *bmpdata; in_uint16_le(s, font); in_uint16_le(s, charactor); in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_uint16_le(s, len_bmpdata); in_uint8p(s, bmpdata, len_bmpdata); rv = mod->server_add_char_alpha(mod, font, charactor, x, y, cx, cy, bmpdata); return rv; }
/* Process bitmap updates */ void process_bitmap_updates(STREAM s) { uint16 num_updates; uint16 left, top, right, bottom, width, height; uint16 cx, cy, bpp, Bpp, compress, bufsize, size; uint8 *data, *bmpdata; int i; in_uint16_le(s, num_updates); for (i = 0; i < num_updates; i++) { in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, bpp); Bpp = (bpp + 7) / 8; //Bpp = 4; in_uint16_le(s, compress); in_uint16_le(s, bufsize); cx = right - left + 1; cy = bottom - top + 1; //DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", // left, top, right, bottom, width, height, Bpp, compress)); __android_log_print(ANDROID_LOG_INFO,"JNIMsg","BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)",left, top, right, bottom, width, height, Bpp, compress); if (!compress) { int y; bmpdata = (uint8 *) xmalloc(width * height * Bpp); for (y = 0; y < height; y++) { in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], width * Bpp); } __android_log_print(ANDROID_LOG_INFO,"JNIMsg","in if do ui_paint_bitmap"); ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); xfree(bmpdata); continue; } if (compress & 0x400) { size = bufsize; } else { in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* line_size, final_size */ }in_uint8p(s, data, size); bmpdata = (uint8 *) xmalloc(width * height * Bpp); if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); } else { DEBUG_RDP5(("Failed to decompress data\n")); } xfree(bmpdata); } }
static void rdpdr_process(RDPCLIENT * This, STREAM s) { uint32 handle; uint8 *magic; #if WITH_DEBUG_RDP5 printf("--- rdpdr_process ---\n"); hexdump(s->p, s->end - s->p); #endif in_uint8p(s, magic, 4); if ((magic[0] == 'r') && (magic[1] == 'D')) { if ((magic[2] == 'R') && (magic[3] == 'I')) { rdpdr_process_irp(This, s); return; } if ((magic[2] == 'n') && (magic[3] == 'I')) { rdpdr_send_connect(This); rdpdr_send_name(This); return; } if ((magic[2] == 'C') && (magic[3] == 'C')) { /* connect from server */ rdpdr_send_clientcapabilty(This); rdpdr_send_available(This); return; } if ((magic[2] == 'r') && (magic[3] == 'd')) { /* connect to a specific resource */ in_uint32(s, handle); #if WITH_DEBUG_RDP5 DEBUG(("RDPDR: Server connected to resource %d\n", handle)); #endif return; } if ((magic[2] == 'P') && (magic[3] == 'S')) { /* server capability */ return; } } if ((magic[0] == 'R') && (magic[1] == 'P')) { if ((magic[2] == 'C') && (magic[3] == 'P')) { printercache_process(This, s); return; } } unimpl("RDPDR packet type %c%c%c%c\n", magic[0], magic[1], magic[2], magic[3]); }
/* Parse an authentication request packet */ static BOOL licence_parse_authreq(STREAM s, uint8 **token, uint8 **signature) { uint16 tokenlen; in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */ in_uint16_le(s, tokenlen); if (tokenlen != LICENCE_TOKEN_SIZE) { error("token len %d\n", tokenlen); return False; } in_uint8p(s, *token, tokenlen); in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); return s_check_end(s); }
/* Parse an platform challenge request packet */ static RD_BOOL licence_parse_platform_challenge(STREAM s, uint8 ** token, uint8 ** signature) { uint16 tokenlen; in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */ in_uint16_le(s, tokenlen); if (tokenlen != LICENCE_TOKEN_SIZE) { logger(Protocol, Error, "license_parse_platform_challenge(), tokenlen != LICENSE_TOKEN_SIZE"); return False; } in_uint8p(s, *token, tokenlen); in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); return s_check_end(s); }
/* Process a colour pointer PDU */ void process_colour_pointer_pdu(STREAM s) { uint16 x, y, width, height, cache_idx, masklen, datalen; uint8 *mask, *data; HCURSOR cursor; in_uint16_le(s, cache_idx); in_uint16_le(s, x); in_uint16_le(s, y); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, masklen); in_uint16_le(s, datalen); in_uint8p(s, data, datalen); in_uint8p(s, mask, masklen); cursor = ui_create_cursor(x, y, width, height, mask, data); ui_set_cursor(cursor); cache_put_cursor(cache_idx, cursor); }
/* Parse a Server Platform Challenge packet */ static RD_BOOL licence_parse_authreq(rdpLicence * licence, STREAM s, uint8 ** token, uint8 ** signature) { uint16 tokenlen; in_uint8s(s, 4); /* ConnectFlags (unused) */ /* Licensing Binary BLOB with EncryptedPlatformChallenge: */ in_uint8s(s, 2); /* wBlobType (unused) */ in_uint16_le(s, tokenlen); /* wBlobLen */ if (tokenlen != LICENCE_TOKEN_SIZE) { ui_error(licence->sec->rdp->inst, "token len %d\n", tokenlen); return False; } in_uint8p(s, *token, tokenlen); /* RC4-encrypted challenge data */ in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE); /* MACData for decrypted challenge data */ return s_check_end(s); }
/* Process a licence request packet */ static void licence_process_request(STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; RDSSL_RC4 crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(null_data, server_random, null_data); licence_size = load_licence(&licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(hwid); sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ rdssl_rc4_set_key(&crypt_key, g_licence_key, 16); rdssl_rc4_crypt(&crypt_key, hwid, hwid, sizeof(hwid)); logger(Protocol, Debug, "license_process_request(), sending licensing PDU (message type 0x%02x)", LICENCE_TAG_LICENCE_INFO); licence_info(null_data, null_data, licence_data, licence_size, hwid, signature); xfree(licence_data); return; } logger(Protocol, Debug, "license_process_request(), sending licensing PDU (message type 0x%02x)", LICENCE_TAG_NEW_LICENCE_REQUEST); licence_send_new_licence_request(null_data, null_data, g_username, g_hostname); }
/* return error */ static int APP_CC process_server_draw_text(struct mod *mod, struct stream *s) { int rv; int font; int flags; int mixmode; int clip_left; int clip_top; int clip_right; int clip_bottom; int box_left; int box_top; int box_right; int box_bottom; int x; int y; int len_bmpdata; char *bmpdata; in_uint16_le(s, font); in_uint16_le(s, flags); in_uint16_le(s, mixmode); in_sint16_le(s, clip_left); in_sint16_le(s, clip_top); in_sint16_le(s, clip_right); in_sint16_le(s, clip_bottom); in_sint16_le(s, box_left); in_sint16_le(s, box_top); in_sint16_le(s, box_right); in_sint16_le(s, box_bottom); in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, len_bmpdata); in_uint8p(s, bmpdata, len_bmpdata); rv = mod->server_draw_text(mod, font, flags, mixmode, clip_left, clip_top, clip_right, clip_bottom, box_left, box_top, box_right, box_bottom, x, y, bmpdata, len_bmpdata); return rv; }
/* Process a licence demand packet */ static void licence_process_demand(STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; void * crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(null_data, server_random, null_data); licence_size = load_licence(&licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(hwid); sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ crypt_key = ssl_rc4_info_create(); ssl_rc4_set_key(crypt_key, (char *)g_licence_key, 16); ssl_rc4_crypt(crypt_key, (char *)hwid, (char *)hwid, sizeof(hwid)); ssl_rc4_info_delete(crypt_key); licence_present(null_data, null_data, licence_data, licence_size, hwid, signature); xfree(licence_data); return; } licence_send_request(null_data, null_data, g_username, g_hostname); }
/* Process a licence demand packet */ static BOOL licence_process_demand(RDPCLIENT * This, STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; RC4_KEY crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(This, null_data, server_random, null_data); licence_size = load_licence(This, &licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(This, hwid); sec_sign(signature, 16, This->licence.sign_key, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ RC4_set_key(&crypt_key, 16, This->licence.key); RC4(&crypt_key, sizeof(hwid), hwid, hwid); if(!licence_present(This, null_data, null_data, licence_data, licence_size, hwid, signature)) return False; free(licence_data); return True; } return licence_send_request(This, null_data, null_data, This->licence_username, This->licence_hostname); }
/* Process a licence demand packet */ static void licence_process_demand(RDConnectionRef conn, RDStreamRef s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; RC4_KEY crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(conn, null_data, server_random, null_data); licence_size = load_licence(&licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(conn, hwid); sec_sign(signature, 16, conn->licenseSignKey, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ RC4_set_key(&crypt_key, 16, conn->licenseKey); RC4(&crypt_key, sizeof(hwid), hwid, hwid); licence_present(conn, null_data, null_data, licence_data, licence_size, hwid, signature); xfree(licence_data); return; } licence_send_request(conn, null_data, null_data, conn->username, conn->hostname); }
/* Process redirect PDU from Session Directory */ static RD_BOOL process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_reason */ ) { uint32 len; uint16 redirect_identifier; /* reset any previous redirection information */ g_redirect = True; free(g_redirect_server); free(g_redirect_username); free(g_redirect_domain); free(g_redirect_lb_info); free(g_redirect_cookie); g_redirect_server = NULL; g_redirect_username = NULL; g_redirect_domain = NULL; g_redirect_lb_info = NULL; g_redirect_cookie = NULL; /* these 2 bytes are unknown, seem to be zeros */ in_uint8s(s, 2); /* FIXME: Previous implementation only reads 4 bytes which has been working but todays spec says something different. Investigate and retest server redirection using WTS 2003 cluster. */ if (enhanced_redirect) { /* read identifier */ in_uint16_le(s, redirect_identifier); if (redirect_identifier != 0x0400) error("Protocol error in server redirection, unexpected data."); /* FIXME: skip total length */ in_uint8s(s, 2); /* read session_id */ in_uint32_le(s, g_redirect_session_id); } /* read connection flags */ in_uint32_le(s, g_redirect_flags); if (g_redirect_flags & PDU_REDIRECT_HAS_IP) { /* read length of ip string */ in_uint32_le(s, len); /* read ip string */ rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len); } if (g_redirect_flags & PDU_REDIRECT_HAS_LOAD_BALANCE_INFO) { /* read length of load balance info blob */ in_uint32_le(s, g_redirect_lb_info_len); /* reallocate a loadbalance info blob */ if (g_redirect_lb_info != NULL) free(g_redirect_lb_info); g_redirect_lb_info = xmalloc(g_redirect_lb_info_len); /* read load balance info blob */ in_uint8p(s, g_redirect_lb_info, g_redirect_lb_info_len); } if (g_redirect_flags & PDU_REDIRECT_HAS_USERNAME) { /* read length of username string */ in_uint32_le(s, len); /* read username string */ rdp_in_unistr(s, len, &g_redirect_username, &g_redirect_username_len); } if (g_redirect_flags & PDU_REDIRECT_HAS_DOMAIN) { /* read length of domain string */ in_uint32_le(s, len); /* read domain string */ rdp_in_unistr(s, len, &g_redirect_domain, &g_redirect_domain_len); } if (g_redirect_flags & PDU_REDIRECT_HAS_PASSWORD) { /* the information in this blob is either a password or a cookie that should be passed though as blob and not parsed as a unicode string */ /* read blob length */ in_uint32_le(s, g_redirect_cookie_len); /* reallocate cookie blob */ if (g_redirect_cookie != NULL) free(g_redirect_cookie); g_redirect_cookie = xmalloc(g_redirect_cookie_len); /* read cookie as is */ in_uint8p(s, g_redirect_cookie, g_redirect_cookie_len); } if (g_redirect_flags & PDU_REDIRECT_DONT_STORE_USERNAME) { warning("PDU_REDIRECT_DONT_STORE_USERNAME set\n"); } if (g_redirect_flags & PDU_REDIRECT_USE_SMARTCARD) { warning("PDU_REDIRECT_USE_SMARTCARD set\n"); } if (g_redirect_flags & PDU_REDIRECT_INFORMATIONAL) { /* By spec this is only for information and doesn't mean that an actual redirect should be performed. How it should be used is not mentioned. */ g_redirect = False; } if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN) { in_uint32_le(s, len); /* Let target fqdn replace target ip address */ if (g_redirect_server) { free(g_redirect_server); g_redirect_server = NULL; } /* read fqdn string */ rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len); } if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS) { warning("PDU_REDIRECT_HAS_TARGET_NETBIOS set\n"); } if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_IP_ARRAY) { warning("PDU_REDIRECT_HAS_TARGET_IP_ARRAY set\n"); } return True; }
/* return error */ int DEFAULT_CC lib_mod_signal(struct mod* mod) { struct stream* s; int num_orders; int index; int rv; int len; int type; int x; int y; int cx; int cy; int fgcolor; int opcode; int width; int height; int srcx; int srcy; int len_bmpdata; int style; int x1; int y1; int x2; int y2; char* bmpdata; char cur_data[32 * (32 * 3)]; char cur_mask[32 * (32 / 8)]; LIB_DEBUG(mod, "in lib_mod_signal"); make_stream(s); init_stream(s, 8192); rv = lib_recv(mod, s->data, 8); if (rv == 0) { in_uint16_le(s, type); in_uint16_le(s, num_orders); in_uint32_le(s, len); if (type == 1) { init_stream(s, len); rv = lib_recv(mod, s->data, len); if (rv == 0) { for (index = 0; index < num_orders; index++) { in_uint16_le(s, type); //g_writeln("-------------lib_mod_signal: type=%d",type); switch (type) { case 1: /* server_begin_update */ rv = mod->server_begin_update(mod); break; case 2: /* server_end_update */ rv = mod->server_end_update(mod); break; case 3: /* server_fill_rect */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); rv = mod->server_fill_rect(mod, x, y, cx, cy); break; case 4: /* server_screen_blt */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_sint16_le(s, srcx); in_sint16_le(s, srcy); rv = mod->server_screen_blt(mod, x, y, cx, cy, srcx, srcy); break; case 5: /* server_paint_rect */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); in_uint32_le(s, len_bmpdata); in_uint8p(s, bmpdata, len_bmpdata); in_uint16_le(s, width); in_uint16_le(s, height); in_sint16_le(s, srcx); in_sint16_le(s, srcy); rv = mod->server_paint_rect(mod, x, y, cx, cy, bmpdata, width, height, srcx, srcy); break; case 10: /* server_set_clip */ in_sint16_le(s, x); in_sint16_le(s, y); in_uint16_le(s, cx); in_uint16_le(s, cy); rv = mod->server_set_clip(mod, x, y, cx, cy); break; case 11: /* server_reset_clip */ rv = mod->server_reset_clip(mod); break; case 12: /* server_set_fgcolor */ in_uint32_le(s, fgcolor); rv = mod->server_set_fgcolor(mod, fgcolor); break; case 14: in_uint16_le(s, opcode); rv = mod->server_set_opcode(mod, opcode); break; case 17: in_uint16_le(s, style); in_uint16_le(s, width); rv = mod->server_set_pen(mod, style, width); break; case 18: in_sint16_le(s, x1); in_sint16_le(s, y1); in_sint16_le(s, x2); in_sint16_le(s, y2); rv = mod->server_draw_line(mod, x1, y1, x2, y2); break; case 19: in_sint16_le(s, x); in_sint16_le(s, y); in_uint8a(s, cur_data, 32 * (32 * 3)); in_uint8a(s, cur_mask, 32 * (32 / 8)); rv = mod->server_set_cursor(mod, x, y, cur_data, cur_mask); break; default: rv = 1; break; } if (rv != 0) { break; } } } } } free_stream(s); LIB_DEBUG(mod, "out lib_mod_signal"); return rv; }
/* Process bitmap updates */ void process_bitmap_updates(STREAM s) { uint16 num_updates; uint16 left, top, right, bottom, width, height; uint16 cx, cy, bpp, Bpp, compress, bufsize, size; uint8 *data, *bmpdata; int i; in_uint16_le(s, num_updates); for (i = 0; i < num_updates; i++) { in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, bpp); Bpp = (bpp + 7) / 8; in_uint16_le(s, compress); in_uint16_le(s, bufsize); cx = right - left + 1; cy = bottom - top + 1; DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", left, top, right, bottom, width, height, Bpp, compress)); /* Server may limit bpp - this is how we find out */ if (g_server_bpp != bpp) { warning("Server limited colour depth to %d bits\n", bpp); g_server_bpp = bpp; } if (!compress) { int y; bmpdata = (uint8 *) xmalloc(width * height * Bpp); for (y = 0; y < height; y++) { in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], width * Bpp); } ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); xfree(bmpdata); continue; } if (compress & 0x400) { size = bufsize; } else { in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* line_size, final_size */ } in_uint8p(s, data, size); bmpdata = (uint8 *) xmalloc(width * height * Bpp); if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); } else { DEBUG_RDP5(("Failed to decompress data\n")); } xfree(bmpdata); } }
/* Process bitmap updates */ void process_bitmap_updates(RDPCLIENT * This, STREAM s) { uint16 num_updates; uint16 left, top, right, bottom, width, height; uint16 cx, cy, bpp, Bpp, compress, bufsize, size; uint8 *data, *bmpdata; int i; in_uint16_le(s, num_updates); for (i = 0; i < num_updates; i++) { in_uint16_le(s, left); in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); in_uint16_le(s, width); in_uint16_le(s, height); in_uint16_le(s, bpp); Bpp = (bpp + 7) / 8; in_uint16_le(s, compress); in_uint16_le(s, bufsize); cx = right - left + 1; cy = bottom - top + 1; DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", left, top, right, bottom, width, height, Bpp, compress)); if (!compress) { #if 0 int y; bmpdata = (uint8 *) xmalloc(width * height * Bpp); for (y = 0; y < height; y++) { in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], width * Bpp); } ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata); xfree(bmpdata); #else in_uint8p(s, bmpdata, width * height * Bpp); ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata); #endif continue; } if (compress & 0x400) { size = bufsize; } else { in_uint8s(s, 2); /* pad */ in_uint16_le(s, size); in_uint8s(s, 4); /* line_size, final_size */ } in_uint8p(s, data, size); bmpdata = (uint8 *) malloc(width * height * Bpp); if(bmpdata == NULL) return; if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) { ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata); } else { DEBUG_RDP5(("Failed to decompress data\n")); } free(bmpdata); } }
/* Process a Server License Request packet */ static void licence_process_request(rdpLicence * licence, STREAM s) { uint8 null_data[SEC_MODULUS_SIZE]; uint8 *server_random; uint32 dwVersion; uint32 cbCompanyName; uint32 cbProductId; uint16 wBlobType, wBlobLen; uint32 ScopeCount, i; uint8 signature[LICENCE_SIGNATURE_SIZE]; uint8 hwid[LICENCE_HWID_SIZE]; uint8 *licence_data; int licence_size; CryptoRc4 crypt_key; /* Retrieve the server random from the incoming packet */ in_uint8p(s, server_random, SEC_RANDOM_SIZE); /* ServerRandom */ /* ProductInfo: */ in_uint32_le(s, dwVersion); in_uint32_le(s, cbCompanyName); in_uint8s(s, cbCompanyName); /* pbCompanyName */ in_uint32_le(s, cbProductId); in_uint8s(s, cbProductId); /* pbProductId - "A02"? */ /* KeyExchangeList */ in_uint16_le(s, wBlobType); /* BB_KEY_EXCHG_ALG_BLOB (0x000D) */ in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); /* KEY_EXCHANGE_ALG_RSA 0x00000001 */ /* ServerCertificate */ in_uint16_le(s, wBlobType); /* BB_CERTIFICATE_BLOB (0x0003). */ in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); /* cert to use for licensing instead of the one from MCS Connect Response */ /* ScopeList */ in_uint32_le(s, ScopeCount); for (i=0; i<ScopeCount; i++) { in_uint16_le(s, wBlobType); in_uint16_le(s, wBlobLen); in_uint8s(s, wBlobLen); } /* We currently use null client keys. This is a bit naughty but, hey, the security of licence negotiation isn't exactly paramount. */ memset(null_data, 0, sizeof(null_data)); licence_generate_keys(licence, null_data, server_random, null_data); licence_size = load_licence(&licence_data); if (licence_size > 0) { /* Generate a signature for the HWID buffer */ licence_generate_hwid(licence, hwid); sec_sign(signature, 16, licence->licence_sign_key, 16, hwid, sizeof(hwid)); /* Now encrypt the HWID */ crypt_key = crypto_rc4_init(licence->licence_key, 16); crypto_rc4(crypt_key, sizeof(hwid), hwid, hwid); crypto_rc4_free(crypt_key); licence_present(licence, null_data, null_data, licence_data, licence_size, hwid, signature); xfree(licence_data); return; } licence_send_request(licence, null_data, null_data, licence->sec->rdp->settings->username, licence->sec->rdp->settings->hostname); }