void ntlm_output_restriction_encoding(NTLM_CONTEXT* context) { wStream* s; AV_PAIR* restrictions = &context->av_pairs->Restrictions; BYTE machineID[32] = "\x3A\x15\x8E\xA6\x75\x82\xD8\xF7\x3E\x06\xFA\x7A\xB4\xDF\xFD\x43" "\x84\x6C\x02\x3A\xFD\x5A\x94\xFE\xCF\x97\x0F\x3D\x19\x2C\x38\x20"; restrictions->value = malloc(48); restrictions->length = 48; s = PStreamAllocAttach(restrictions->value, restrictions->length); Stream_Write_UINT32(s, 48); /* Size */ Stream_Zero(s, 4); /* Z4 (set to zero) */ /* IntegrityLevel (bit 31 set to 1) */ Stream_Write_UINT8(s, 1); Stream_Zero(s, 3); Stream_Write_UINT32(s, 0x00002000); /* SubjectIntegrityLevel */ Stream_Write(s, machineID, 32); /* MachineID */ PStreamFreeDetach(s); }
static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { SERIAL_TTY* tty; tty = serial->tty; if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; DEBUG_WARN("tty not valid."); } else { DEBUG_SVC("%s(%d) closed.", serial->path, tty->id); TerminateThread(serial->mthread, 0); WaitForSingleObject(serial->mthread, INFINITE); CloseHandle(serial->mthread); serial->mthread = NULL; serial_tty_free(tty); serial->tty = NULL; } Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); }
int cliprdr_temp_directory(CliprdrClientContext* context, CLIPRDR_TEMP_DIRECTORY* tempDirectory) { int length; wStream* s; WCHAR* wszTempDir = NULL; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 520 * 2); length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0); if (length < 0) return -1; if (length > 520) length = 520; Stream_Write(s, tempDirectory->szTempDir, length * 2); Stream_Zero(s, (520 - length) * 2); free(wszTempDir); WLog_Print(cliprdr->log, WLOG_DEBUG, "TempDirectory: %s", tempDirectory->szTempDir); cliprdr_packet_send(cliprdr, s); return 1; }
static UINT video_control_send_client_notification(VideoClientContext *context, TSMM_CLIENT_NOTIFICATION *notif) { BYTE buf[100]; wStream *s; VIDEO_PLUGIN* video = (VIDEO_PLUGIN *)context->handle; IWTSVirtualChannel* channel; UINT ret; UINT32 cbSize; s = Stream_New(buf, 30); if (!s) return CHANNEL_RC_NO_MEMORY; cbSize = 16; Stream_Seek_UINT32(s); /* cbSize */ Stream_Write_UINT32(s, TSMM_PACKET_TYPE_CLIENT_NOTIFICATION); /* PacketType */ Stream_Write_UINT8(s, notif->PresentationId); Stream_Write_UINT8(s, notif->NotificationType); Stream_Zero(s, 2); if (notif->NotificationType == TSMM_CLIENT_NOTIFICATION_TYPE_FRAMERATE_OVERRIDE) { Stream_Write_UINT32(s, 16); /* cbData */ /* TSMM_CLIENT_NOTIFICATION_FRAMERATE_OVERRIDE */ Stream_Write_UINT32(s, notif->FramerateOverride.Flags); Stream_Write_UINT32(s, notif->FramerateOverride.DesiredFrameRate); Stream_Zero(s, 4 * 2); cbSize += 4 * 4; } else { Stream_Write_UINT32(s, 0); /* cbData */ } Stream_SealLength(s); Stream_SetPosition(s, 0); Stream_Write_UINT32(s, cbSize); Stream_Free(s, FALSE); channel = video->control_callback->channel_callback->channel; ret = channel->Write(channel, cbSize, buf, NULL); return ret; }
static void update_send_synchronize(rdpContext* context) { wStream* s; rdpRdp* rdp = context->rdp; s = fastpath_update_pdu_init(rdp->fastpath); Stream_Zero(s, 2); /* pad2Octets (2 bytes) */ fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s); Stream_Release(s); }
static void parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp) { if (close(parallel->file) < 0) DEBUG_SVC("failed to close %s(%d)", parallel->path, parallel->id); else DEBUG_SVC("%s(%d) closed", parallel->path, parallel->id); Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT parallel_process_irp_close(PARALLEL_DEVICE* parallel, IRP* irp) { if (close(parallel->file) < 0) { } else { } Stream_Zero(irp->output, 5); /* Padding(5) */ return irp->Complete(irp); }
void guac_rdpdr_fs_process_lock_control(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_NOT_SUPPORTED, 5); guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] Lock not supported", __func__, file_id); Stream_Zero(output_stream, 5); /* Padding */ svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); }
static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { Stream_Seek(irp->input, 32); /* Padding (32 bytes) */ if (!CloseHandle(serial->hComm)) { WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%d) closed.", serial->device.name, irp->device->id); irp->IoStatus = STATUS_UNSUCCESSFUL; goto error_handle; } WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %d, FileId: %d) closed.", serial->device.name, irp->device->id, irp->FileId); serial->hComm = NULL; irp->IoStatus = STATUS_SUCCESS; error_handle: Stream_Zero(irp->output, 5); /* Padding (5 bytes) */ }
static UINT32 smartcard_GetAttrib_Call(SMARTCARD_DEVICE* smartcard, SMARTCARD_OPERATION* operation, GetAttrib_Call* call) { LONG status; DWORD cbAttrLen; GetAttrib_Return ret; IRP* irp = operation->irp; ret.pbAttr = NULL; if (call->fpbAttrIsNULL) call->cbAttrLen = 0; if (call->cbAttrLen) ret.pbAttr = (BYTE*) malloc(call->cbAttrLen); cbAttrLen = call->cbAttrLen; status = ret.ReturnCode = SCardGetAttrib(operation->hCard, call->dwAttrId, ret.pbAttr, &cbAttrLen); ret.cbAttrLen = cbAttrLen; smartcard_trace_get_attrib_return(smartcard, &ret, call->dwAttrId); if (ret.ReturnCode) { WLog_Print(smartcard->log, WLOG_WARN, "SCardGetAttrib: %s (0x%08X) cbAttrLen: %d\n", SCardGetAttributeString(call->dwAttrId), call->dwAttrId, call->cbAttrLen); Stream_Zero(irp->output, 256); return ret.ReturnCode; } status = smartcard_pack_get_attrib_return(smartcard, irp->output, &ret); if (status != SCARD_S_SUCCESS) return status; free(ret.pbAttr); return ret.ReturnCode; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT drive_process_irp_close(DRIVE_DEVICE* drive, IRP* irp) { void* key; DRIVE_FILE* file; file = drive_get_file_by_id(drive, irp->FileId); key = (void*)(size_t) irp->FileId; if (!file) { irp->IoStatus = STATUS_UNSUCCESSFUL; } else { ListDictionary_Remove(drive->files, key); drive_file_free(file); } Stream_Zero(irp->output, 5); /* Padding(5) */ return irp->Complete(irp); }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) { rdpPrintJob* printjob = NULL; if (printer_dev->printer) printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); if (!printjob) { irp->IoStatus = STATUS_UNSUCCESSFUL; } else { printjob->Close(printjob); } Stream_Zero(irp->output, 4); /* Padding(4) */ return irp->Complete(irp); }
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength) { UINT32 length; length = ModulusLength + 8; if (blob->length > ModulusLength) { fprintf(stderr, "license_write_encrypted_premaster_secret_blob: invalid blob\n"); return; } Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */ if (blob->length > 0) Stream_Write(s, blob->data, blob->length); /* blobData */ Stream_Zero(s, length - blob->length); }
void license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength) { UINT32 length; length = ModulusLength + 8; if (blob->length > ModulusLength) { WLog_ERR(TAG, "license_write_encrypted_premaster_secret_blob: invalid blob"); return; } Stream_EnsureRemainingCapacity(s, length + 4); Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */ Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */ if (blob->length > 0) Stream_Write(s, blob->data, blob->length); /* blobData */ Stream_Zero(s, length - blob->length); }
static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { SERIAL_TTY* tty; tty = serial->tty; if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; DEBUG_WARN("tty not valid."); } else { DEBUG_SVC("%s(%d) closed.", serial->path, tty->id); serial_tty_free(tty); serial->tty = NULL; } Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); }
static UINT serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { if (Stream_GetRemainingLength(irp->input) < 32) return ERROR_INVALID_DATA; Stream_Seek(irp->input, 32); /* Padding (32 bytes) */ if (!CloseHandle(serial->hComm)) { WLog_Print(serial->log, WLOG_WARN, "CloseHandle failure: %s (%"PRIu32") closed.", serial->device.name, irp->device->id); irp->IoStatus = STATUS_UNSUCCESSFUL; goto error_handle; } WLog_Print(serial->log, WLOG_DEBUG, "%s (DeviceId: %"PRIu32", FileId: %"PRIu32") closed.", serial->device.name, irp->device->id, irp->FileId); serial->hComm = NULL; irp->IoStatus = STATUS_SUCCESS; error_handle: Stream_Zero(irp->output, 5); /* Padding (5 bytes) */ return CHANNEL_RC_OK; }
static BOOL TestStream_Zero(void) { UINT32 x; BOOL rc = FALSE; const BYTE data[] = "someteststreamdata"; wStream* s = Stream_New(NULL, sizeof(data)); if (!s) goto out; Stream_Write(s, data, sizeof(data)); if (memcmp(Stream_Buffer(s), data, sizeof(data)) != 0) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Zero(s, 5); if (s->pointer != s->buffer + 5) goto out; if (memcmp(Stream_Pointer(s), data+5, sizeof(data)-5) != 0) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; for (x=0; x<5; x++) { UINT8 val; Stream_Read_UINT8(s, val); if (val != 0) goto out; } rc = TRUE; out: Stream_Free(s, TRUE); return rc; }
static UINT video_control_send_presentation_response(VideoClientContext *context, TSMM_PRESENTATION_RESPONSE *resp) { BYTE buf[12]; wStream *s; VIDEO_PLUGIN* video = (VIDEO_PLUGIN *)context->handle; IWTSVirtualChannel* channel; UINT ret; s = Stream_New(buf, 12); if (!s) return CHANNEL_RC_NO_MEMORY; Stream_Write_UINT32(s, 12); /* cbSize */ Stream_Write_UINT32(s, TSMM_PACKET_TYPE_PRESENTATION_RESPONSE); /* PacketType */ Stream_Write_UINT8(s, resp->PresentationId); Stream_Zero(s, 3); Stream_SealLength(s); channel = video->control_callback->channel_callback->channel; ret = channel->Write(channel, 12, buf, NULL); Stream_Free(s, FALSE); return ret; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_server_format_list(CliprdrServerContext* context, CLIPRDR_FORMAT_LIST* formatList) { wStream* s; UINT32 index; int length = 0; int cchWideChar; LPWSTR lpWideCharStr; int formatNameSize; int formatNameLength; char* szFormatName; WCHAR* wszFormatName; BOOL asciiNames = FALSE; CLIPRDR_FORMAT* format; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; if (!cliprdr->useLongFormatNames) { length = formatList->numFormats * 36; s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length); if (!s) { WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); return ERROR_INTERNAL_ERROR; } for (index = 0; index < formatList->numFormats; index++) { format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ formatNameSize = 0; formatNameLength = 0; szFormatName = format->formatName; if (asciiNames) { if (szFormatName) formatNameLength = strlen(szFormatName); if (formatNameLength > 31) formatNameLength = 31; Stream_Write(s, szFormatName, formatNameLength); Stream_Zero(s, 32 - formatNameLength); } else { wszFormatName = NULL; if (szFormatName) formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0); if (formatNameSize > 15) formatNameSize = 15; if (wszFormatName) Stream_Write(s, wszFormatName, formatNameSize * 2); Stream_Zero(s, 32 - (formatNameSize * 2)); free(wszFormatName); } } } else { for (index = 0; index < formatList->numFormats; index++) { format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); length += 4; formatNameSize = 2; if (format->formatName) formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2; length += formatNameSize; } s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length); if (!s) { WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); return ERROR_INTERNAL_ERROR; } for (index = 0; index < formatList->numFormats; index++) { format = (CLIPRDR_FORMAT*) &(formatList->formats[index]); Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */ if (format->formatName) { lpWideCharStr = (LPWSTR) Stream_Pointer(s); cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2; formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, lpWideCharStr, cchWideChar) * 2; Stream_Seek(s, formatNameSize); } else { Stream_Write_UINT16(s, 0); } } } WLog_DBG(TAG, "ServerFormatList: numFormats: %d", formatList->numFormats); return cliprdr_server_packet_send(cliprdr, s); }
static BOOL rdpsnd_server_send_audio_pdu(RdpsndServerContext* context) { int size; BYTE* src; int frames; int fill_size; BOOL status; AUDIO_FORMAT* format; int tbytes_per_frame; wStream* s = context->priv->rdpsnd_pdu; format = &context->client_formats[context->selected_client_format]; tbytes_per_frame = format->nChannels * context->priv->src_bytes_per_sample; if ((format->nSamplesPerSec == context->src_format.nSamplesPerSec) && (format->nChannels == context->src_format.nChannels)) { src = context->priv->out_buffer; frames = context->priv->out_pending_frames; } else { context->priv->dsp_context->resample(context->priv->dsp_context, context->priv->out_buffer, context->priv->src_bytes_per_sample, context->src_format.nChannels, context->src_format.nSamplesPerSec, context->priv->out_pending_frames, format->nChannels, format->nSamplesPerSec); frames = context->priv->dsp_context->resampled_frames; src = context->priv->dsp_context->resampled_buffer; } size = frames * tbytes_per_frame; if (format->wFormatTag == WAVE_FORMAT_DVI_ADPCM) { context->priv->dsp_context->encode_ima_adpcm(context->priv->dsp_context, src, size, format->nChannels, format->nBlockAlign); src = context->priv->dsp_context->adpcm_buffer; size = context->priv->dsp_context->adpcm_size; } else if (format->wFormatTag == WAVE_FORMAT_ADPCM) { context->priv->dsp_context->encode_ms_adpcm(context->priv->dsp_context, src, size, format->nChannels, format->nBlockAlign); src = context->priv->dsp_context->adpcm_buffer; size = context->priv->dsp_context->adpcm_size; } context->block_no = (context->block_no + 1) % 256; /* Fill to nBlockAlign for the last audio packet */ fill_size = 0; if ((format->wFormatTag == WAVE_FORMAT_DVI_ADPCM || format->wFormatTag == WAVE_FORMAT_ADPCM) && (context->priv->out_pending_frames < context->priv->out_frames) && ((size % format->nBlockAlign) != 0)) { fill_size = format->nBlockAlign - (size % format->nBlockAlign); } /* WaveInfo PDU */ Stream_SetPosition(s, 0); Stream_Write_UINT8(s, SNDC_WAVE); /* msgType */ Stream_Write_UINT8(s, 0); /* bPad */ Stream_Write_UINT16(s, size + fill_size + 8); /* BodySize */ Stream_Write_UINT16(s, 0); /* wTimeStamp */ Stream_Write_UINT16(s, context->selected_client_format); /* wFormatNo */ Stream_Write_UINT8(s, context->block_no); /* cBlockNo */ Stream_Seek(s, 3); /* bPad */ Stream_Write(s, src, 4); status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); if (!status) goto out; Stream_SetPosition(s, 0); /* Wave PDU */ Stream_EnsureRemainingCapacity(s, size + fill_size); Stream_Write_UINT32(s, 0); /* bPad */ Stream_Write(s, src + 4, size - 4); if (fill_size > 0) Stream_Zero(s, fill_size); status = WTSVirtualChannelWrite(context->priv->ChannelHandle, (PCHAR) Stream_Buffer(s), Stream_GetPosition(s), NULL); out: Stream_SetPosition(s, 0); context->priv->out_pending_frames = 0; return status; }
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery, const char* path, wStream* output) { int length; BOOL ret; WCHAR* ent_path; struct STAT st; struct dirent* ent; DEBUG_SVC("path %s FsInformationClass %d InitialQuery %d", path, FsInformationClass, InitialQuery); if (!file->dir) { Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } if (InitialQuery != 0) { rewinddir(file->dir); free(file->pattern); if (path[0]) file->pattern = _strdup(strrchr(path, '\\') + 1); else file->pattern = NULL; } if (file->pattern) { do { ent = readdir(file->dir); if (ent == NULL) continue; if (FilePatternMatchA(ent->d_name, file->pattern)) break; } while (ent); } else { ent = readdir(file->dir); } if (ent == NULL) { DEBUG_SVC(" pattern %s not found.", file->pattern); Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ return FALSE; } memset(&st, 0, sizeof(struct STAT)); ent_path = (WCHAR*) malloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf((char*) ent_path, "%s/%s", file->fullpath, ent->d_name); if (STAT((char*) ent_path, &st) != 0) { DEBUG_WARN("stat %s failed. errno = %d", (char*) ent_path, errno); } DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path); free(ent_path); ent_path = NULL; length = ConvertToUnicode(CP_UTF8, 0, ent->d_name, -1, &ent_path, 0) * 2; ret = TRUE; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ Stream_Write_UINT32(output, 64 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 64 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write(output, ent_path, length); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ Stream_Write_UINT32(output, 68 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 68 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write_UINT32(output, 0); /* EaSize */ Stream_Write(output, ent_path, length); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ Stream_Write_UINT32(output, 93 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 93 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ Stream_Write_UINT64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ Stream_Write_UINT64(output, st.st_size); /* EndOfFile */ Stream_Write_UINT64(output, st.st_size); /* AllocationSize */ Stream_Write_UINT32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write_UINT32(output, 0); /* EaSize */ Stream_Write_UINT8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ Stream_Zero(output, 24); /* ShortName */ Stream_Write(output, ent_path, length); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ Stream_Write_UINT32(output, 12 + length); /* Length */ Stream_EnsureRemainingCapacity(output, 12 + length); Stream_Write_UINT32(output, 0); /* NextEntryOffset */ Stream_Write_UINT32(output, 0); /* FileIndex */ Stream_Write_UINT32(output, length); /* FileNameLength */ Stream_Write(output, ent_path, length); break; default: Stream_Write_UINT32(output, 0); /* Length */ Stream_Write_UINT8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = FALSE; break; } free(ent_path); return ret; }
void gcc_write_client_core_data(wStream* s, rdpMcs* mcs) { UINT32 version; WCHAR* clientName = NULL; int clientNameLength; BYTE connectionType; UINT16 highColorDepth; UINT16 supportedColorDepths; UINT16 earlyCapabilityFlags; WCHAR* clientDigProductId = NULL; int clientDigProductIdLength; rdpSettings* settings = mcs->settings; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->RdpVersion >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); clientDigProductIdLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); Stream_Write_UINT32(s, version); /* Version */ Stream_Write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ Stream_Write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* ColorDepth, ignored because of postBeta2ColorDepth */ Stream_Write_UINT16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ Stream_Write_UINT32(s, settings->KeyboardLayout); /* KeyboardLayout */ Stream_Write_UINT32(s, settings->ClientBuild); /* ClientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength >= 16) { clientNameLength = 16; clientName[clientNameLength - 1] = 0; } Stream_Write(s, clientName, (clientNameLength * 2)); Stream_Zero(s, 32 - (clientNameLength * 2)); free(clientName); Stream_Write_UINT32(s, settings->KeyboardType); /* KeyboardType */ Stream_Write_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType */ Stream_Write_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey */ Stream_Zero(s, 64); /* imeFileName */ Stream_Write_UINT16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ Stream_Write_UINT16(s, 1); /* clientProductID */ Stream_Write_UINT32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->ColorDepth, 24); supportedColorDepths = RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->NetworkAutoDetect) settings->ConnectionType = CONNECTION_TYPE_AUTODETECT; if (settings->RemoteFxCodec && !settings->NetworkAutoDetect) settings->ConnectionType = CONNECTION_TYPE_LAN; connectionType = settings->ConnectionType; if (connectionType) earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; if (settings->ColorDepth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } if (settings->NetworkAutoDetect) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_NETWORK_AUTODETECT; if (settings->SupportHeartbeatPdu) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_HEARTBEAT_PDU; if (settings->SupportGraphicsPipeline) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL; if (settings->SupportDynamicTimeZone) earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE; Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */ Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */ Stream_Write_UINT16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 31 characters) */ if (clientDigProductIdLength >= 32) { clientDigProductIdLength = 32; clientDigProductId[clientDigProductIdLength - 1] = 0; } Stream_Write(s, clientDigProductId, (clientDigProductIdLength * 2) ); Stream_Zero(s, 64 - (clientDigProductIdLength * 2) ); free(clientDigProductId); Stream_Write_UINT8(s, connectionType); /* connectionType */ Stream_Write_UINT8(s, 0); /* pad1octet */ Stream_Write_UINT32(s, settings->SelectedProtocol); /* serverSelectedProtocol */ }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; /** * Re: settings->EncryptionLevel: * This is configured/set by the server implementation and serves the same * purpose as the "Encryption Level" setting in the RDP-Tcp configuration * dialog of Microsoft's Remote Desktop Session Host Configuration. * Re: settings->EncryptionMethods: * at this point this setting contains the client's supported encryption * methods we've received in gcc_read_client_security_data() */ if (!settings->UseRdpSecurityLayer) { /* TLS/NLA is used: disable rdp style encryption */ settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } /* verify server encryption level value */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: WLog_INFO(TAG, "Active rdp encryption level: NONE"); break; case ENCRYPTION_LEVEL_FIPS: WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant"); break; case ENCRYPTION_LEVEL_HIGH: WLog_INFO(TAG, "Active rdp encryption level: HIGH"); break; case ENCRYPTION_LEVEL_LOW: WLog_INFO(TAG, "Active rdp encryption level: LOW"); break; case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE"); break; default: WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel); WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE"); settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } /* choose rdp encryption method based on server level and client methods */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: /* The only valid method is NONE in this case */ settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; break; case ENCRYPTION_LEVEL_FIPS: /* The only valid method is FIPS in this case */ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)) { WLog_WARN(TAG, "client does not support FIPS as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; break; case ENCRYPTION_LEVEL_HIGH: /* Maximum key strength supported by the server must be used (128 bit)*/ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)) { WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; break; case ENCRYPTION_LEVEL_LOW: case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: /* Maximum key strength supported by the client must be used */ if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; else { WLog_WARN(TAG, "client has not announced any supported encryption methods"); settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } break; default: WLog_ERR(TAG, "internal error: unknown encryption level"); } /* log selected encryption method */ switch (settings->EncryptionMethods) { case ENCRYPTION_METHOD_NONE: WLog_INFO(TAG, "Selected rdp encryption method: NONE"); break; case ENCRYPTION_METHOD_40BIT: WLog_INFO(TAG, "Selected rdp encryption method: 40BIT"); break; case ENCRYPTION_METHOD_56BIT: WLog_INFO(TAG, "Selected rdp encryption method: 56BIT"); break; case ENCRYPTION_METHOD_128BIT: WLog_INFO(TAG, "Selected rdp encryption method: 128BIT"); break; case ENCRYPTION_METHOD_FIPS: WLog_INFO(TAG, "Selected rdp encryption method: FIPS"); break; default: WLog_ERR(TAG, "internal error: unknown encryption method"); } headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(s); Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ Stream_Write(s, "RSA1", 4); /* magic */ Stream_Write_UINT32(s, keyLen + 8); /* keylen */ Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ Stream_Write_UINT32(s, keyLen - 1); /* datalen */ Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(s) - sigData; Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); if (!md5) { WLog_ERR(TAG, "unable to allocate a md5"); return; } crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); Stream_Zero(s, 8); }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; if (!settings->DisableEncryption) { settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; } if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE || settings->EncryptionLevel != ENCRYPTION_LEVEL_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->exponent); wPublicKeyBlobLen = 4; /* magic (RSA1) */ wPublicKeyBlobLen += 4; /* keylen */ wPublicKeyBlobLen += 4; /* bitlen */ wPublicKeyBlobLen += 4; /* datalen */ wPublicKeyBlobLen += expLen; wPublicKeyBlobLen += keyLen; wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */ serverCertLen = 4; /* dwVersion */ serverCertLen += 4; /* dwSigAlgId */ serverCertLen += 4; /* dwKeyAlgId */ serverCertLen += 2; /* wPublicKeyBlobType */ serverCertLen += 2; /* wPublicKeyBlobLen */ serverCertLen += wPublicKeyBlobLen; serverCertLen += 2; /* wSignatureBlobType */ serverCertLen += 2; /* wSignatureBlobLen */ serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */ serverCertLen += 8; /* 8 bytes of zero padding */ headerLen += sizeof(serverRandomLen); headerLen += sizeof(serverCertLen); headerLen += serverRandomLen; headerLen += serverCertLen; } gcc_write_user_data_header(s, SC_SECURITY, headerLen); Stream_Write_UINT32(s, settings->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(s); Stream_Write_UINT32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */ Stream_Write_UINT32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */ Stream_Write_UINT32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */ Stream_Write_UINT16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */ Stream_Write_UINT16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */ Stream_Write(s, "RSA1", 4); /* magic */ Stream_Write_UINT32(s, keyLen + 8); /* keylen */ Stream_Write_UINT32(s, keyLen * 8); /* bitlen */ Stream_Write_UINT32(s, keyLen - 1); /* datalen */ Stream_Write(s, settings->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(s) - sigData; Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, keyLen + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); crypto_md5_update(md5, sigData, sigDataLen); crypto_md5_final(md5, signature); crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH, tssk_modulus, tssk_privateExponent, encryptedSignature); Stream_Write(s, encryptedSignature, sizeof(encryptedSignature)); Stream_Zero(s, 8); }