void credssp_read_ts_credentials(rdpCredssp* credssp, PSecBuffer ts_credentials) { wStream* s; int length; int ts_password_creds_length; s = stream_new(0); stream_attach(s, ts_credentials->pvBuffer, ts_credentials->cbBuffer); /* TSCredentials (SEQUENCE) */ ber_read_sequence_tag(s, &length); /* [0] credType (INTEGER) */ ber_read_contextual_tag(s, 0, &length, TRUE); ber_read_integer(s, NULL); /* [1] credentials (OCTET STRING) */ ber_read_contextual_tag(s, 1, &length, TRUE); ber_read_octet_string_tag(s, &ts_password_creds_length); credssp_read_ts_password_creds(credssp, s); stream_detach(s); stream_free(s); }
int rts_recv_pdu(rdpRpc* rpc, RTS_PDU* rts_pdu) { STREAM* s; int status; int length; BYTE header_buffer[20]; rdpTls* tls_out = rpc->tls_out; /* read first 20 bytes to get RTS PDU Header */ status = tls_read(tls_out, (BYTE*) &header_buffer, 20); if (status <= 0) { printf("rts_recv error\n"); return status; } s = stream_new(0); stream_attach(s, header_buffer, 20); rts_pdu_header_read(s, &(rts_pdu->header)); stream_detach(s); stream_free(s); length = rts_pdu->header.frag_length - 20; rts_pdu->content = (BYTE*) malloc(length); status = tls_read(tls_out, rts_pdu->content, length); if (status < 0) { printf("rts_recv error\n"); return status; } if (rts_pdu->header.ptype != PTYPE_RTS) { printf("rts_recv error: unexpected ptype:%d\n", rts_pdu->header.ptype); return -1; } #ifdef WITH_DEBUG_RTS printf("rts_recv(): length: %d\n", length); freerdp_hexdump(rts_pdu->content, length); printf("\n"); #endif rts_recv_pdu_commands(rpc, rts_pdu); return rts_pdu->header.frag_length; }
static void xf_cliprdr_process_dib(clipboardContext* cb, uint8* data, int size) { STREAM* s; uint16 bpp; uint32 offset; uint32 ncolors; /* size should be at least sizeof(BITMAPINFOHEADER) */ if (size < 40) { DEBUG_X11("dib size %d too short", size); return; } s = stream_new(0); stream_attach(s, data, size); stream_seek(s, 14); stream_read_uint16(s, bpp); stream_read_uint32(s, ncolors); offset = 14 + 40 + (bpp <= 8 ? (ncolors == 0 ? (1 << bpp) : ncolors) * 4 : 0); stream_detach(s); stream_free(s); DEBUG_X11("offset=%d bpp=%d ncolors=%d", offset, bpp, ncolors); s = stream_new(14 + size); stream_write_uint8(s, 'B'); stream_write_uint8(s, 'M'); stream_write_uint32(s, 14 + size); stream_write_uint32(s, 0); stream_write_uint32(s, offset); stream_write(s, data, size); cb->data = stream_get_head(s); cb->data_length = stream_get_length(s); stream_detach(s); stream_free(s); }
void credssp_encode_ts_credentials(rdpCredssp* credssp) { STREAM* s; int length; s = stream_new(0); length = credssp_skip_ts_credentials(credssp); sspi_SecBufferAlloc(&credssp->ts_credentials, length); stream_attach(s, credssp->ts_credentials.pvBuffer, length); credssp_write_ts_credentials(credssp, s); stream_detach(s); stream_free(s); }
static int alsa_seqmidi_detach(alsa_midi_t *m) { alsa_seqmidi_t *self = (alsa_seqmidi_t*) m; debug_log("midi: detach"); if (!self->seq) return -EALREADY; alsa_seqmidi_stop(m); jack_ringbuffer_reset(self->port_add); free_ports(self, self->port_del); stream_detach(self, PORT_INPUT); stream_detach(self, PORT_OUTPUT); snd_seq_close(self->seq); self->seq = NULL; return 0; }
void credssp_encode_ts_credentials(rdpCredssp* credssp) { STREAM* s; int length; s = stream_new(0); length = credssp_skip_ts_credentials(credssp); freerdp_blob_alloc(&credssp->ts_credentials, length); stream_attach(s, credssp->ts_credentials.data, length); credssp_write_ts_credentials(credssp, s); stream_detach(s); stream_free(s); }
int rpc_recv_bind_ack_pdu(rdpRpc* rpc) { BYTE* p; STREAM* s; int status; BYTE* pdu; BYTE* auth_data; RPC_PDU_HEADER header; int pdu_length = 0x8FFF; pdu = malloc(pdu_length); if (pdu == NULL) return -1; status = rpc_out_read(rpc, pdu, pdu_length); if (status > 0) { s = stream_new(0); stream_attach(s, pdu, pdu_length); rpc_pdu_header_read(s, &header); stream_detach(s); stream_free(s); auth_data = malloc(header.auth_length); if (auth_data == NULL) { free(pdu); return -1; } p = (pdu + (header.frag_length - header.auth_length)); memcpy(auth_data, p, header.auth_length); rpc->ntlm->inputBuffer.pvBuffer = auth_data; rpc->ntlm->inputBuffer.cbBuffer = header.auth_length; ntlm_authenticate(rpc->ntlm); } free(pdu); return status; }
boolean WTSVirtualChannelWrite( /* __in */ void* hChannelHandle, /* __in */ uint8* Buffer, /* __in */ uint32 Length, /* __out */ uint32* pBytesWritten) { rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; wts_data_item* item; STREAM* s; int cbLen; int cbChId; int first; uint32 written; if (channel == NULL) return false; if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC) { item = xnew(wts_data_item); item->buffer = xmalloc(Length); item->length = Length; memcpy(item->buffer, Buffer, Length); wts_queue_send_item(channel, item); } else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY) { DEBUG_DVC("drdynvc not ready"); return false; } else { s = stream_new(0); first = true; while (Length > 0) { item = xnew(wts_data_item); item->buffer = xmalloc(channel->client->settings->vc_chunk_size); stream_attach(s, item->buffer, channel->client->settings->vc_chunk_size); stream_seek_uint8(s); cbChId = wts_write_variable_uint(s, channel->channel_id); if (first && (Length > (uint32) stream_get_left(s))) { cbLen = wts_write_variable_uint(s, Length); item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId; } else { item->buffer[0] = (DATA_PDU << 4) | cbChId; } first = false; written = stream_get_left(s); if (written > Length) written = Length; stream_write(s, Buffer, written); item->length = stream_get_length(s); stream_detach(s); Length -= written; Buffer += written; wts_queue_send_item(channel->vcm->drdynvc_channel, item); } stream_free(s); } if (pBytesWritten != NULL) *pBytesWritten = Length; return true; }
int rpc_out_read(rdpRpc* rpc, uint8* data, int length) { STREAM* s; int status; uint8* pdu; int content_length; RPC_PDU_HEADER header; if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */ rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */ pdu = xmalloc(0xFFFF); if (pdu == NULL) { printf("rpc_out_read error: memory allocation failed") ; return -1 ; } status = tls_read(rpc->tls_out, pdu, 16); /* read first 16 bytes to get RPC PDU Header */ if (status <= 0) { xfree(pdu); return status; } s = stream_new(0); stream_attach(s, pdu, 16); rpc_pdu_header_read(s, &header); stream_detach(s); stream_free(s); content_length = header.frag_length - 16; status = tls_read(rpc->tls_out, pdu + 16, content_length); if (status < 0) { xfree(pdu); return status; } if (header.ptype == PTYPE_RTS) /* RTS PDU */ { printf("rpc_out_read error: Unexpected RTS PDU\n"); xfree(pdu); return -1; } else { /* RTS PDUs are not subject to flow control */ rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header.frag_length; rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header.frag_length; } if (length < header.frag_length) { printf("rpc_out_read error! receive buffer is not large enough\n"); xfree(pdu); return -1; } memcpy(data, pdu, header.frag_length); #ifdef WITH_DEBUG_RPC printf("rpc_out_read(): length: %d\n", header.frag_length); freerdp_hexdump(data, header.frag_length); printf("\n"); #endif xfree(pdu); return header.frag_length; }
static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, uint32 cbSize, uint8* pBuffer) { int length; STREAM* input; STREAM* output; int error = -1; TSMF_IFMAN ifman; uint32 MessageId; uint32 FunctionId; uint32 InterfaceId; TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback; /* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */ if (cbSize < 12) { DEBUG_WARN("invalid size. cbSize=%d", cbSize); return 1; } input = stream_new(0); stream_attach(input, (uint8*) pBuffer, cbSize); output = stream_new(256); stream_seek(output, 8); stream_read_uint32(input, InterfaceId); stream_read_uint32(input, MessageId); stream_read_uint32(input, FunctionId); DEBUG_DVC("cbSize=%d InterfaceId=0x%X MessageId=0x%X FunctionId=0x%X", cbSize, InterfaceId, MessageId, FunctionId); memset(&ifman, 0, sizeof(TSMF_IFMAN)); ifman.channel_callback = pChannelCallback; ifman.decoder_name = ((TSMF_PLUGIN*) callback->plugin)->decoder_name; ifman.audio_name = ((TSMF_PLUGIN*) callback->plugin)->audio_name; ifman.audio_device = ((TSMF_PLUGIN*) callback->plugin)->audio_device; memcpy(ifman.presentation_id, callback->presentation_id, 16); ifman.stream_id = callback->stream_id; ifman.message_id = MessageId; ifman.input = input; ifman.input_size = cbSize - 12; ifman.output = output; ifman.output_pending = false; ifman.output_interface_id = InterfaceId; switch (InterfaceId) { case TSMF_INTERFACE_CAPABILITIES | STREAM_ID_NONE: switch (FunctionId) { case RIM_EXCHANGE_CAPABILITY_REQUEST: error = tsmf_ifman_rim_exchange_capability_request(&ifman); break; default: break; } break; case TSMF_INTERFACE_DEFAULT | STREAM_ID_PROXY: switch (FunctionId) { case SET_CHANNEL_PARAMS: memcpy(callback->presentation_id, stream_get_tail(input), 16); stream_seek(input, 16); stream_read_uint32(input, callback->stream_id); DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id); ifman.output_pending = true; error = 0; break; case EXCHANGE_CAPABILITIES_REQ: error = tsmf_ifman_exchange_capability_request(&ifman); break; case CHECK_FORMAT_SUPPORT_REQ: error = tsmf_ifman_check_format_support_request(&ifman); break; case ON_NEW_PRESENTATION: error = tsmf_ifman_on_new_presentation(&ifman); break; case ADD_STREAM: error = tsmf_ifman_add_stream(&ifman); break; case SET_TOPOLOGY_REQ: error = tsmf_ifman_set_topology_request(&ifman); break; case REMOVE_STREAM: error = tsmf_ifman_remove_stream(&ifman); break; case SHUTDOWN_PRESENTATION_REQ: error = tsmf_ifman_shutdown_presentation(&ifman); break; case ON_STREAM_VOLUME: error = tsmf_ifman_on_stream_volume(&ifman); break; case ON_CHANNEL_VOLUME: error = tsmf_ifman_on_channel_volume(&ifman); break; case SET_VIDEO_WINDOW: error = tsmf_ifman_set_video_window(&ifman); break; case UPDATE_GEOMETRY_INFO: error = tsmf_ifman_update_geometry_info(&ifman); break; case SET_ALLOCATOR: error = tsmf_ifman_set_allocator(&ifman); break; case NOTIFY_PREROLL: error = tsmf_ifman_notify_preroll(&ifman); break; case ON_SAMPLE: error = tsmf_ifman_on_sample(&ifman); break; case ON_FLUSH: error = tsmf_ifman_on_flush(&ifman); break; case ON_END_OF_STREAM: error = tsmf_ifman_on_end_of_stream(&ifman); break; case ON_PLAYBACK_STARTED: error = tsmf_ifman_on_playback_started(&ifman); break; case ON_PLAYBACK_PAUSED: error = tsmf_ifman_on_playback_paused(&ifman); break; case ON_PLAYBACK_RESTARTED: error = tsmf_ifman_on_playback_restarted(&ifman); break; case ON_PLAYBACK_STOPPED: error = tsmf_ifman_on_playback_stopped(&ifman); break; case ON_PLAYBACK_RATE_CHANGED: error = tsmf_ifman_on_playback_rate_changed(&ifman); break; default: break; } break; default: break; } stream_detach(input); stream_free(input); input = NULL; ifman.input = NULL; if (error == -1) { switch (FunctionId) { case RIMCALL_RELEASE: /* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE) This message does not require a reply. */ error = 0; ifman.output_pending = 1; break; case RIMCALL_QUERYINTERFACE: /* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP) This message is not supported in this channel. */ error = 0; break; } if (error == -1) { DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.", InterfaceId, FunctionId); /* When a request is not implemented we return empty response indicating error */ } error = 0; } if (error == 0 && !ifman.output_pending) { /* Response packet does not have FunctionId */ length = stream_get_length(output); stream_set_pos(output, 0); stream_write_uint32(output, ifman.output_interface_id); stream_write_uint32(output, MessageId); DEBUG_DVC("response size %d", length); error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL); if (error) { DEBUG_WARN("response error %d", error); } } stream_free(output); return error; }
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) { wStream* s; int length; BYTE padding; UINT32 version; int modulus_length; int exponent_length; int error = 0; s = stream_new(0); stream_attach(s, cert->data, cert->length); info->Modulus = 0; if(!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */ goto error1; error++; if(!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */ goto error1; error++; if(!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */ goto error1; error++; if(!ber_read_integer(s, &version)) /* version (INTEGER) */ goto error1; error++; version++; /* serialNumber */ if(!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */ goto error1; error++; /* signature */ if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* issuer */ if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* validity */ if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Validity (SEQUENCE) */ goto error1; error++; /* subject */ if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo */ if(!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::AlgorithmIdentifier */ if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::subjectPublicKey */ if(!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */ goto error1; error++; /* RSAPublicKey (SEQUENCE) */ if(!ber_read_sequence_tag(s, &length)) /* SEQUENCE */ goto error1; error++; if(!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */ goto error1; error++; /* skip zero padding, if any */ do { if(stream_get_left(s) < 1) goto error1; stream_peek_BYTE(s, padding); if (padding == 0) { if(!stream_skip(s, 1)) goto error1; modulus_length--; } } while (padding == 0); error++; if(stream_get_left(s) < modulus_length) goto error1; info->ModulusLength = modulus_length; info->Modulus = (BYTE*) malloc(info->ModulusLength); stream_read(s, info->Modulus, info->ModulusLength); error++; if(!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */ goto error2; error++; if(stream_get_left(s) < exponent_length || exponent_length > 4) goto error2; stream_read(s, &info->exponent[4 - exponent_length], exponent_length); crypto_reverse(info->Modulus, info->ModulusLength); crypto_reverse(info->exponent, 4); stream_detach(s); stream_free(s); return TRUE; error2: free(info->Modulus); info->Modulus = 0; error1: fprintf(stderr, "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error); stream_detach(s); stream_free(s); return FALSE; }
tbool rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) { uint8 type; uint16 length; uint32 share_id; uint8 compressed_type; uint16 compressed_len; uint32 roff; uint32 rlen; STREAM* comp_stream; rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len); comp_stream = s; if (compressed_type & PACKET_COMPRESSED) { if (decompress_rdp(rdp, s->p, compressed_len - 18, compressed_type, &roff, &rlen)) { comp_stream = stream_new(0); comp_stream->data = rdp->mppc->history_buf + roff; comp_stream->p = comp_stream->data; comp_stream->size = rlen; } else { printf("decompress_rdp() failed\n"); return false; } } #ifdef WITH_DEBUG_RDP if (type != DATA_PDU_TYPE_UPDATE) printf("recv %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: update_recv(rdp->update, comp_stream); break; case DATA_PDU_TYPE_CONTROL: rdp_recv_server_control_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_POINTER: update_recv_pointer(rdp->update, comp_stream); break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: rdp_recv_synchronize_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: update_recv_play_sound(rdp->update, comp_stream); break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: rdp_recv_save_session_info(rdp, comp_stream); break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: rdp_recv_font_map_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: rdp_recv_set_error_info_data_pdu(rdp, comp_stream); break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } if (comp_stream != s) { stream_detach(comp_stream); stream_free(comp_stream); } return true; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length) { int pos; STREAM* s; uint32 blockLen; uint32 blockType; RFX_MESSAGE* message; s = stream_new(0); message = xnew(RFX_MESSAGE); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_uint16(s, blockType); /* blockType (2 bytes) */ stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ stream_seek(s, 2); } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
BOOL WTSVirtualChannelWrite( /* __in */ void* hChannelHandle, /* __in */ BYTE* Buffer, /* __in */ UINT32 Length, /* __out */ UINT32* pBytesWritten) { rdpPeerChannel* channel = (rdpPeerChannel*) hChannelHandle; wts_data_item* item; wStream* s; int cbLen; int cbChId; int first; UINT32 written; if (channel == NULL) return FALSE; if (channel->channel_type == RDP_PEER_CHANNEL_TYPE_SVC) { item = (wts_data_item*) malloc(sizeof(wts_data_item)); ZeroMemory(item, sizeof(wts_data_item)); item->buffer = malloc(Length); item->length = Length; CopyMemory(item->buffer, Buffer, Length); wts_queue_send_item(channel, item); } else if (channel->vcm->drdynvc_channel == NULL || channel->vcm->drdynvc_state != DRDYNVC_STATE_READY) { DEBUG_DVC("drdynvc not ready"); return FALSE; } else { s = stream_new(0); first = TRUE; while (Length > 0) { item = (wts_data_item*) malloc(sizeof(wts_data_item)); ZeroMemory(item, sizeof(wts_data_item)); item->buffer = malloc(channel->client->settings->VirtualChannelChunkSize); stream_attach(s, item->buffer, channel->client->settings->VirtualChannelChunkSize); stream_seek_BYTE(s); cbChId = wts_write_variable_uint(s, channel->channel_id); if (first && (Length > (UINT32) stream_get_left(s))) { cbLen = wts_write_variable_uint(s, Length); item->buffer[0] = (DATA_FIRST_PDU << 4) | (cbLen << 2) | cbChId; } else { item->buffer[0] = (DATA_PDU << 4) | cbChId; } first = FALSE; written = stream_get_left(s); if (written > Length) written = Length; stream_write(s, Buffer, written); item->length = stream_get_length(s); stream_detach(s); Length -= written; Buffer += written; wts_queue_send_item(channel->vcm->drdynvc_channel, item); } stream_free(s); } if (pBytesWritten != NULL) *pBytesWritten = Length; return TRUE; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, uint8* data, uint32 length, RECTANGLE_16* dst_rect) { int pos; STREAM* s; uint32 blockLen; uint32 blockType; RFX_CONTEXT_CVT_PRIV* priv; RFX_MESSAGE* message; s = stream_new(0); message = rfx_message_new(); if (dst_rect) memcpy(&message->dst_rect, dst_rect, sizeof(RECTANGLE_16)); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_uint16(s, blockType); /* blockType (2 bytes) */ stream_read_uint32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ stream_seek(s, 2); } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: priv = (RFX_CONTEXT_CVT_PRIV*) context->priv; if (priv->rfx_op_mode == RDVH_OPT) rfx_cvt_rdvh_opt_process_message_tileset(context, message, s); else rfx_cvt_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) { STREAM* s; int length; uint8 padding; uint32 version; int modulus_length; int exponent_length; s = stream_new(0); stream_attach(s, cert->data, cert->length); ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */ ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */ /* Explicit Contextual Tag [0] */ ber_read_contextual_tag(s, 0, &length, true); ber_read_integer(s, &version); /* version (INTEGER) */ version++; /* serialNumber */ ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */ /* signature */ ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ stream_seek(s, length); /* issuer */ ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ stream_seek(s, length); /* validity */ ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */ stream_seek(s, length); /* subject */ ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */ stream_seek(s, length); /* subjectPublicKeyInfo */ ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */ /* subjectPublicKeyInfo::AlgorithmIdentifier */ ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */ stream_seek(s, length); /* subjectPublicKeyInfo::subjectPublicKey */ ber_read_bit_string(s, &length, &padding); /* BIT_STRING */ /* RSAPublicKey (SEQUENCE) */ ber_read_sequence_tag(s, &length); /* SEQUENCE */ ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */ /* skip zero padding, if any */ do { stream_peek_uint8(s, padding); if (padding == 0) { stream_seek(s, 1); modulus_length--; } } while (padding == 0); freerdp_blob_alloc(&info->modulus, modulus_length); stream_read(s, info->modulus.data, modulus_length); ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */ stream_read(s, &info->exponent[4 - exponent_length], exponent_length); crypto_reverse(info->modulus.data, modulus_length); crypto_reverse(info->exponent, 4); stream_detach(s); stream_free(s); }
int rts_recv_pdu_commands(rdpRpc* rpc, RTS_PDU* rts_pdu) { int i; STREAM* s; UINT32 CommandType; DEBUG_RTS("numberOfCommands:%d", rts_pdu->header.numberOfCommands); if (rts_pdu->header.flags & RTS_FLAG_PING) { rts_send_keep_alive_pdu(rpc); return 0; } s = stream_new(0); stream_attach(s, rts_pdu->content, rts_pdu->header.frag_length); for (i = 0; i < rts_pdu->header.numberOfCommands; i++) { stream_read_UINT32(s, CommandType); /* CommandType (4 bytes) */ DEBUG_RTS("CommandType: %s (0x%08X)", RTS_CMD_STRINGS[CommandType % 14], CommandType); switch (CommandType) { case RTS_CMD_RECEIVE_WINDOW_SIZE: rts_receive_window_size_command_read(rpc, s); break; case RTS_CMD_FLOW_CONTROL_ACK: rts_flow_control_ack_command_read(rpc, s); break; case RTS_CMD_CONNECTION_TIMEOUT: rts_connection_timeout_command_read(rpc, s); break; case RTS_CMD_COOKIE: rts_cookie_command_read(rpc, s); break; case RTS_CMD_CHANNEL_LIFETIME: rts_channel_lifetime_command_read(rpc, s); break; case RTS_CMD_CLIENT_KEEPALIVE: rts_client_keepalive_command_read(rpc, s); break; case RTS_CMD_VERSION: rts_version_command_read(rpc, s); break; case RTS_CMD_EMPTY: rts_empty_command_read(rpc, s); break; case RTS_CMD_PADDING: rts_padding_command_read(rpc, s); break; case RTS_CMD_NEGATIVE_ANCE: rts_negative_ance_command_read(rpc, s); break; case RTS_CMD_ANCE: rts_ance_command_read(rpc, s); break; case RTS_CMD_CLIENT_ADDRESS: rts_client_address_command_read(rpc, s); break; case RTS_CMD_ASSOCIATION_GROUP_ID: rts_association_group_id_command_read(rpc, s); break; case RTS_CMD_DESTINATION: rts_destination_command_read(rpc, s); break; case RTS_CMD_PING_TRAFFIC_SENT_NOTIFY: rts_ping_traffic_sent_notify_command_read(rpc, s); break; default: printf("Error: Unknown RTS Command Type: 0x%x\n", CommandType); stream_detach(s) ; stream_free(s) ; return -1; break; } } stream_detach(s); stream_free(s); return 0; }
RFX_MESSAGE* rfx_process_message(RFX_CONTEXT* context, BYTE* data, UINT32 length) { int pos; STREAM* s; UINT32 blockLen; UINT32 blockType; RFX_MESSAGE* message; message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); ZeroMemory(message, sizeof(RFX_MESSAGE)); s = stream_new(0); stream_attach(s, data, length); while (stream_get_left(s) > 6) { /* RFX_BLOCKT */ stream_read_UINT16(s, blockType); /* blockType (2 bytes) */ stream_read_UINT32(s, blockLen); /* blockLen (4 bytes) */ DEBUG_RFX("blockType 0x%X blockLen %d", blockType, blockLen); if (blockLen == 0) { DEBUG_WARN("zero blockLen"); break; } if (stream_get_left(s) < blockLen - 6) { DEBUG_WARN("rfx_process_message: packet too small for blocklen=%d", blockLen); break; } pos = stream_get_pos(s) - 6 + blockLen; if (blockType >= WBT_CONTEXT && blockType <= WBT_EXTENSION) { /* RFX_CODEC_CHANNELT */ /* codecId (1 byte) must be set to 0x01 */ /* channelId (1 byte) must be set to 0x00 */ if (!stream_skip(s, 2)) { DEBUG_WARN("rfx_process_message: unable to skip RFX_CODEC_CHANNELT"); break; } } switch (blockType) { case WBT_SYNC: rfx_process_message_sync(context, s); break; case WBT_CODEC_VERSIONS: rfx_process_message_codec_versions(context, s); break; case WBT_CHANNELS: rfx_process_message_channels(context, s); break; case WBT_CONTEXT: rfx_process_message_context(context, s); break; case WBT_FRAME_BEGIN: rfx_process_message_frame_begin(context, message, s); break; case WBT_FRAME_END: rfx_process_message_frame_end(context, message, s); break; case WBT_REGION: rfx_process_message_region(context, message, s); break; case WBT_EXTENSION: rfx_process_message_tileset(context, message, s); break; default: DEBUG_WARN("unknown blockType 0x%X", blockType); break; } stream_set_pos(s, pos); } stream_detach(s); stream_free(s); return message; }
int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) { BYTE type; UINT16 length; UINT32 share_id; BYTE compressed_type; UINT16 compressed_len; UINT32 roff; UINT32 rlen; STREAM* comp_stream; if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len)) return -1; comp_stream = s; if (compressed_type & PACKET_COMPRESSED) { if (stream_get_left(s) < compressed_len - 18) { printf("decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len); return -1; } if (decompress_rdp(rdp->mppc_dec, s->p, compressed_len - 18, compressed_type, &roff, &rlen)) { comp_stream = stream_new(0); comp_stream->data = rdp->mppc_dec->history_buf + roff; comp_stream->p = comp_stream->data; comp_stream->size = rlen; } else { printf("decompress_rdp() failed\n"); return -1; } stream_seek(s, compressed_len - 18); } #ifdef WITH_DEBUG_RDP /* if (type != DATA_PDU_TYPE_UPDATE) */ DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d", type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length); #endif switch (type) { case DATA_PDU_TYPE_UPDATE: if (!update_recv(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_CONTROL: if (!rdp_recv_server_control_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_POINTER: if (!update_recv_pointer(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_INPUT: break; case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_REFRESH_RECT: break; case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, comp_stream)) return -1; break; case DATA_PDU_TYPE_SUPPRESS_OUTPUT: break; case DATA_PDU_TYPE_SHUTDOWN_REQUEST: break; case DATA_PDU_TYPE_SHUTDOWN_DENIED: break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: if(!rdp_recv_save_session_info(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_FONT_LIST: break; case DATA_PDU_TYPE_FONT_MAP: if(!rdp_recv_font_map_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: break; case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: break; case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: break; case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: break; case DATA_PDU_TYPE_SET_ERROR_INFO: if (!rdp_recv_set_error_info_data_pdu(rdp, comp_stream)) return -1; break; case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: break; case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: break; case DATA_PDU_TYPE_ARC_STATUS: break; case DATA_PDU_TYPE_STATUS_INFO: break; case DATA_PDU_TYPE_MONITOR_LAYOUT: break; default: break; } if (comp_stream != s) { stream_detach(comp_stream); stream_free(comp_stream); } return 0; }