/* receives a list of server supported formats and returns a list of client supported formats */ static void rdpsnd_process_message_formats(rdpsndPlugin* rdpsnd, STREAM* data_in) { uint16 wNumberOfFormats; uint16 nFormat; uint16 wVersion; STREAM* data_out; rdpsndFormat* out_formats; uint16 n_out_formats; rdpsndFormat* format; uint8* format_mark; uint8* data_mark; int pos; rdpsnd_free_supported_formats(rdpsnd); stream_seek_uint32(data_in); /* dwFlags */ stream_seek_uint32(data_in); /* dwVolume */ stream_seek_uint32(data_in); /* dwPitch */ stream_seek_uint16(data_in); /* wDGramPort */ stream_read_uint16(data_in, wNumberOfFormats); stream_read_uint8(data_in, rdpsnd->cBlockNo); /* cLastBlockConfirmed */ stream_read_uint16(data_in, wVersion); stream_seek_uint8(data_in); /* bPad */ DEBUG_SVC("wNumberOfFormats %d wVersion %d", wNumberOfFormats, wVersion); if (wNumberOfFormats < 1) { DEBUG_WARN("wNumberOfFormats is 0"); return; } out_formats = (rdpsndFormat*)xzalloc(wNumberOfFormats * sizeof(rdpsndFormat)); n_out_formats = 0; data_out = stream_new(24); stream_write_uint8(data_out, SNDC_FORMATS); /* msgType */ stream_write_uint8(data_out, 0); /* bPad */ stream_seek_uint16(data_out); /* BodySize */ stream_write_uint32(data_out, TSSNDCAPS_ALIVE | TSSNDCAPS_VOLUME); /* dwFlags */ stream_write_uint32(data_out, 0xFFFFFFFF); /* dwVolume */ stream_write_uint32(data_out, 0); /* dwPitch */ stream_write_uint16_be(data_out, 0); /* wDGramPort */ stream_seek_uint16(data_out); /* wNumberOfFormats */ stream_write_uint8(data_out, 0); /* cLastBlockConfirmed */ stream_write_uint16(data_out, 6); /* wVersion */ stream_write_uint8(data_out, 0); /* bPad */ for (nFormat = 0; nFormat < wNumberOfFormats; nFormat++) { stream_get_mark(data_in, format_mark); format = &out_formats[n_out_formats]; stream_read_uint16(data_in, format->wFormatTag); stream_read_uint16(data_in, format->nChannels); stream_read_uint32(data_in, format->nSamplesPerSec); stream_seek_uint32(data_in); /* nAvgBytesPerSec */ stream_read_uint16(data_in, format->nBlockAlign); stream_read_uint16(data_in, format->wBitsPerSample); stream_read_uint16(data_in, format->cbSize); stream_get_mark(data_in, data_mark); stream_seek(data_in, format->cbSize); format->data = NULL; DEBUG_SVC("wFormatTag=%d nChannels=%d nSamplesPerSec=%d nBlockAlign=%d wBitsPerSample=%d", format->wFormatTag, format->nChannels, format->nSamplesPerSec, format->nBlockAlign, format->wBitsPerSample); if (rdpsnd->fixed_format > 0 && rdpsnd->fixed_format != format->wFormatTag) continue; if (rdpsnd->fixed_channel > 0 && rdpsnd->fixed_channel != format->nChannels) continue; if (rdpsnd->fixed_rate > 0 && rdpsnd->fixed_rate != format->nSamplesPerSec) continue; if (rdpsnd->device && rdpsnd->device->FormatSupported(rdpsnd->device, format)) { DEBUG_SVC("format supported."); stream_check_size(data_out, 18 + format->cbSize); stream_write(data_out, format_mark, 18 + format->cbSize); if (format->cbSize > 0) { format->data = xmalloc(format->cbSize); memcpy(format->data, data_mark, format->cbSize); } n_out_formats++; } } rdpsnd->n_supported_formats = n_out_formats; if (n_out_formats > 0) { rdpsnd->supported_formats = out_formats; } else { xfree(out_formats); DEBUG_WARN("no formats supported"); } pos = stream_get_pos(data_out); stream_set_pos(data_out, 2); stream_write_uint16(data_out, pos - 4); stream_set_pos(data_out, 18); stream_write_uint16(data_out, n_out_formats); stream_set_pos(data_out, pos); svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out); if (wVersion >= 6) { data_out = stream_new(8); stream_write_uint8(data_out, SNDC_QUALITYMODE); /* msgType */ stream_write_uint8(data_out, 0); /* bPad */ stream_write_uint16(data_out, 4); /* BodySize */ stream_write_uint16(data_out, HIGH_QUALITY); /* wQualityMode */ stream_write_uint16(data_out, 0); /* Reserved */ svc_plugin_send((rdpSvcPlugin*)rdpsnd, data_out); } }
static uint32 handle_GetStatusChange(IRP* irp, boolean wide) { LONG rv; SCARDCONTEXT hContext; DWORD dwTimeout = 0; DWORD readerCount = 0; SCARD_READERSTATE *readerStates, *cur; int i; stream_seek(irp->input, 0x18); stream_read_uint32(irp->input, dwTimeout); stream_read_uint32(irp->input, readerCount); stream_seek(irp->input, 8); stream_read_uint32(irp->input, hContext); stream_seek(irp->input, 4); DEBUG_SCARD("context: 0x%08x, timeout: 0x%08x, count: %d", (unsigned) hContext, (unsigned) dwTimeout, (int) readerCount); if (readerCount > 0) { readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE)); if (!readerStates) return sc_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; stream_seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ stream_read_uint32(irp->input, cur->dwCurrentState); stream_read_uint32(irp->input, cur->dwEventState); stream_read_uint32(irp->input, cur->cbAtr); stream_read(irp->input, cur->rgbAtr, 32); stream_seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; cur->dwEventState &= 0x0000FFFF; cur->dwEventState = 0; } for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; uint32 dataLength; stream_seek(irp->input, 8); stream_read_uint32(irp->input, dataLength); sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } } else { readerStates = NULL; } rv = SCardGetStatusChange(hContext, (DWORD) dwTimeout, readerStates, (DWORD) readerCount); if (rv != SCARD_S_SUCCESS) DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); else DEBUG_SCARD("Success"); stream_write_uint32(irp->output, readerCount); stream_write_uint32(irp->output, 0x00084dd8); stream_write_uint32(irp->output, readerCount); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x\n", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); /* TODO: do byte conversions if necessary */ stream_write_uint32(irp->output, cur->dwCurrentState); stream_write_uint32(irp->output, cur->dwEventState); stream_write_uint32(irp->output, cur->cbAtr); stream_write(irp->output, cur->rgbAtr, 32); stream_write_zero(irp->output, 4); xfree((void *)cur->szReader); } sc_output_alignment(irp, 8); xfree(readerStates); return rv; }
static DWORD handle_Status(IRP *irp, boolean wide) { LONG rv; SCARDHANDLE hCard; DWORD state, protocol; DWORD readerLen = 0; DWORD atrLen = 0; char * readerName; BYTE pbAtr[MAX_ATR_SIZE]; uint32 dataLength; int pos, poslen1, poslen2; #ifdef WITH_DEBUG_SCARD int i; #endif stream_seek(irp->input, 0x24); stream_read_uint32(irp->input, readerLen); stream_read_uint32(irp->input, atrLen); stream_seek(irp->input, 0x0c); stream_read_uint32(irp->input, hCard); stream_seek(irp->input, 0x4); atrLen = MAX_ATR_SIZE; #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #else readerLen = 256; readerName = xmalloc(readerLen); rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #endif if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); return sc_output_return(irp, rv); } DEBUG_SCARD("Success (state: 0x%08x, proto: 0x%08x)", (unsigned) state, (unsigned) protocol); DEBUG_SCARD(" Reader: \"%s\"", readerName ? readerName : "NULL"); #ifdef WITH_DEBUG_SCARD printf(" ATR: "); for (i = 0; i < atrLen; i++) printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); printf("\n"); #endif state = sc_map_state(state); poslen1 = stream_get_pos(irp->output); stream_write_uint32(irp->output, readerLen); stream_write_uint32(irp->output, 0x00020000); stream_write_uint32(irp->output, state); stream_write_uint32(irp->output, protocol); stream_write(irp->output, pbAtr, atrLen); if (atrLen < 32) stream_write_zero(irp->output, 32 - atrLen); stream_write_uint32(irp->output, atrLen); poslen2 = stream_get_pos(irp->output); stream_write_uint32(irp->output, readerLen); dataLength = sc_output_string(irp, readerName, wide); dataLength += sc_output_string(irp, "\0", wide); sc_output_repos(irp, dataLength); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_uint32(irp->output,dataLength); stream_set_pos(irp->output, poslen2); stream_write_uint32(irp->output,dataLength); stream_set_pos(irp->output, pos); sc_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE /* SCardFreeMemory(NULL, readerName); */ free(readerName); #else xfree(readerName); #endif return rv; }
static uint32 handle_GetAttrib(IRP* irp) { LONG rv; SCARDHANDLE hCard; DWORD dwAttrId = 0, dwAttrLen = 0; DWORD attrLen = 0; uint8* pbAttr = NULL; stream_seek(irp->input, 0x20); stream_read_uint32(irp->input, dwAttrId); stream_seek(irp->input, 0x4); stream_read_uint32(irp->input, dwAttrLen); stream_seek(irp->input, 0xC); stream_read_uint32(irp->input, hCard); DEBUG_SCARD("hcard: 0x%08x, attrib: 0x%08x (%d bytes)\n", (unsigned) hCard, (unsigned) dwAttrId, (int) dwAttrLen); #ifdef SCARD_AUTOALLOCATE if(dwAttrLen == 0) { attrLen = 0; } else { attrLen = SCARD_AUTOALLOCATE; } #endif rv = SCardGetAttrib(hCard, dwAttrId, attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_A && rv == SCARD_E_UNSUPPORTED_FEATURE) { rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_W, attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); } if(dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W && rv == SCARD_E_UNSUPPORTED_FEATURE) { rv = SCardGetAttrib(hCard, SCARD_ATTR_DEVICE_FRIENDLY_NAME_A, attrLen == 0 ? NULL : (uint8*) &pbAttr, &attrLen); } if(attrLen > dwAttrLen && pbAttr != NULL) { rv = SCARD_E_INSUFFICIENT_BUFFER; } dwAttrLen = attrLen; if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned int) rv); free(pbAttr); return sc_output_return(irp, rv); } else { DEBUG_SCARD("Success (%d bytes)", (int) dwAttrLen); stream_write_uint32(irp->output, dwAttrLen); stream_write_uint32(irp->output, 0x00000200); stream_write_uint32(irp->output, dwAttrLen); if (!pbAttr) { stream_write_zero(irp->output, dwAttrLen); } else { stream_write(irp->output, pbAttr, dwAttrLen); } sc_output_repos(irp, dwAttrLen); /* align to multiple of 4 */ stream_write_uint32(irp->output, 0); } sc_output_alignment(irp, 8); xfree(pbAttr); return rv; }
void scard_device_control(SCARD_DEVICE* scard, IRP* irp) { uint32 output_len, input_len, ioctl_code; uint32 stream_len, result; uint32 pos, pad_len; uint32 irp_len; uint32 irp_result_pos, output_len_pos, result_pos; stream_read_uint32(irp->input, output_len); stream_read_uint32(irp->input, input_len); stream_read_uint32(irp->input, ioctl_code); stream_seek(irp->input, 20); /* padding */ // stream_seek(irp->input, 4); /* TODO: parse len, le, v1 */ // stream_seek(irp->input, 4); /* 0xcccccccc */ // stream_seek(irp->input, 4); /* rpce len */ /* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */ stream_extend(irp->output, 2048); irp_result_pos = stream_get_pos(irp->output); stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ /* [MS-RPCE] 2.2.6.1 */ stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */ stream_write_uint32(irp->output, 0xcccccccc); /* filler */ output_len_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* size */ stream_write_uint32(irp->output, 0x0); /* filler */ result_pos = stream_get_pos(irp->output); stream_seek(irp->output, 4); /* result */ /* body */ switch (ioctl_code) { case SCARD_IOCTL_ESTABLISH_CONTEXT: result = handle_EstablishContext(irp); break; case SCARD_IOCTL_IS_VALID_CONTEXT: result = handle_IsValidContext(irp); break; case SCARD_IOCTL_RELEASE_CONTEXT: result = handle_ReleaseContext(irp); break; case SCARD_IOCTL_LIST_READERS: result = handle_ListReaders(irp, 0); break; case SCARD_IOCTL_LIST_READERS + 4: result = handle_ListReaders(irp, 1); break; case SCARD_IOCTL_LIST_READER_GROUPS: case SCARD_IOCTL_LIST_READER_GROUPS + 4: /* typically not used unless list_readers fail */ result = SCARD_F_INTERNAL_ERROR; break; case SCARD_IOCTL_GET_STATUS_CHANGE: result = handle_GetStatusChange(irp, 0); break; case SCARD_IOCTL_GET_STATUS_CHANGE + 4: result = handle_GetStatusChange(irp, 1); break; case SCARD_IOCTL_CANCEL: result = handle_Cancel(irp); break; case SCARD_IOCTL_CONNECT: result = handle_Connect(irp, 0); break; case SCARD_IOCTL_CONNECT + 4: result = handle_Connect(irp, 1); break; case SCARD_IOCTL_RECONNECT: result = handle_Reconnect(irp); break; case SCARD_IOCTL_DISCONNECT: result = handle_Disconnect(irp); break; case SCARD_IOCTL_BEGIN_TRANSACTION: result = handle_BeginTransaction(irp); break; case SCARD_IOCTL_END_TRANSACTION: result = handle_EndTransaction(irp); break; case SCARD_IOCTL_STATE: result = handle_State(irp); break; case SCARD_IOCTL_STATUS: result = handle_Status(irp, 0); break; case SCARD_IOCTL_STATUS + 4: result = handle_Status(irp, 1); break; case SCARD_IOCTL_TRANSMIT: result = handle_Transmit(irp); break; case SCARD_IOCTL_CONTROL: result = handle_Control(irp); break; case SCARD_IOCTL_GETATTRIB: result = handle_GetAttrib(irp); break; case SCARD_IOCTL_ACCESS_STARTED_EVENT: result = handle_AccessStartedEvent(irp); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR: result = handle_LocateCardsByATR(irp, 0); break; case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4: result = handle_LocateCardsByATR(irp, 1); break; default: result = 0xc0000001; printf("scard unknown ioctl 0x%x\n", ioctl_code); break; } /* look for NTSTATUS errors */ if ((result & 0xc0000000) == 0xc0000000) return scard_error(scard, irp, result); /* per Ludovic Rousseau, map different usage of this particular * error code between pcsc-lite & windows */ if (result == 0x8010001F) result = 0x80100022; /* handle response packet */ pos = stream_get_pos(irp->output); stream_len = pos - irp_result_pos - 4; stream_set_pos(irp->output, output_len_pos); stream_write_uint32(irp->output, stream_len - 24); stream_set_pos(irp->output, result_pos); stream_write_uint32(irp->output, result); stream_set_pos(irp->output, pos); /* pad stream to 16 byte align */ pad_len = stream_len % 16; stream_write_zero(irp->output, pad_len); pos = stream_get_pos(irp->output); irp_len = stream_len + pad_len; stream_set_pos(irp->output, irp_result_pos); stream_write_uint32(irp->output, irp_len); stream_set_pos(irp->output, pos); #ifdef WITH_DEBUG_SCARD freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output)); #endif irp->IoStatus = 0; irp->Complete(irp); }
int lua_compile(const uuid_t uuid, uint64_t platform, resource_source_t* source, const uint256_t source_hash, const char* type, size_t type_length) { int result = 0; uint64_t* subplatforms = 0; size_t iplat, psize; hashmap_fixed_t fixedmap; hashmap_t* map = (hashmap_t*)&fixedmap; hash_t resource_type_hash; resource_type_hash = hash(type, type_length); if (resource_type_hash != HASH_LUA) return -1; array_push(subplatforms, platform); hashmap_initialize(map, sizeof(fixedmap.bucket) / sizeof(fixedmap.bucket[0]), 8); resource_source_map_all(source, map, false); resource_source_map_reduce(source, map, &subplatforms, resource_source_platform_reduce); resource_source_map_clear(map); for (iplat = 1, psize = array_size(subplatforms); (iplat != psize) && (result == 0); ++iplat) { void* compiled_blob = 0; size_t compiled_size = 0; stream_t* stream; uint64_t subplatform = subplatforms[iplat]; resource_change_t* sourcechange = resource_source_get(source, HASH_SOURCE, subplatform); if (sourcechange && (sourcechange->flags & RESOURCE_SOURCEFLAG_BLOB)) { compiled_size = sourcechange->value.blob.size; compiled_blob = memory_allocate(HASH_RESOURCE, compiled_size, 0, MEMORY_PERSISTENT); if (!resource_source_read_blob(uuid, HASH_SOURCE, subplatform, sourcechange->value.blob.checksum, compiled_blob, compiled_size)) { memory_deallocate(compiled_blob); compiled_blob = 0; compiled_size = 0; } } if (compiled_size <= 0) continue; stream = resource_local_create_static(uuid, subplatform); if (stream) { const uint32_t version = 1; resource_header_t header = { .type = resource_type_hash, .version = version, .source_hash = source_hash }; resource_stream_write_header(stream, header); stream_deallocate(stream); if (compiled_size > 0) { stream = resource_local_create_dynamic(uuid, subplatform); if (stream) { stream_write_uint32(stream, version); stream_write_uint64(stream, compiled_size); stream_write(stream, compiled_blob, compiled_size); stream_deallocate(stream); } else { log_errorf(HASH_RESOURCE, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to create dynamic resource stream")); result = -1; } } } else { log_errorf(HASH_RESOURCE, ERROR_SYSTEM_CALL_FAIL, STRING_CONST("Unable to create static resource stream")); result = -1; } memory_deallocate(compiled_blob); }
void input_write_synchronize_event(STREAM* s, uint32 flags) { stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ stream_write_uint32(s, flags); /* toggleFlags (4 bytes) */ }
void rail_write_client_sysmenu_order(STREAM* s, RAIL_SYSMENU_ORDER* sysmenu) { stream_write_uint32(s, sysmenu->windowId); /* windowId (4 bytes) */ stream_write_uint16(s, sysmenu->left); /* left (2 bytes) */ stream_write_uint16(s, sysmenu->top); /* top (2 bytes) */ }
void rail_write_client_syscommand_order(STREAM* s, RAIL_SYSCOMMAND_ORDER* syscommand) { stream_write_uint32(s, syscommand->windowId); /* windowId (4 bytes) */ stream_write_uint16(s, syscommand->command); /* command (2 bytes) */ }
void rail_write_handshake_order(STREAM* s, RAIL_HANDSHAKE_ORDER* handshake) { stream_write_uint32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ }
void rail_write_client_status_order(STREAM* s, RAIL_CLIENT_STATUS_ORDER* client_status) { stream_write_uint32(s, client_status->flags); /* flags (4 bytes) */ }
static void audin_server_send_version(audin_server* audin, STREAM* s) { stream_write_uint8(s, MSG_SNDIN_VERSION); stream_write_uint32(s, 1); /* Version (4 bytes) */ WTSVirtualChannelWrite(audin->audin_channel, stream_get_head(s), stream_get_length(s), NULL); }
void rdp_write_info_packet(STREAM* s, rdpSettings* settings) { size_t length; uint32 flags; uint8* domain; uint16 cbDomain; uint8* userName; uint16 cbUserName; uint8* password; uint16 cbPassword; uint8* alternateShell; uint16 cbAlternateShell; uint8* workingDir; uint16 cbWorkingDir; flags = INFO_MOUSE | INFO_UNICODE | INFO_LOGONERRORS | INFO_LOGONNOTIFY | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | INFO_DISABLECTRLALTDEL | RNS_INFO_AUDIOCAPTURE; if (settings->autologon) flags |= INFO_AUTOLOGON; if (settings->console_audio) flags |= INFO_REMOTECONSOLEAUDIO; if (settings->compression) flags |= INFO_COMPRESSION | PACKET_COMPR_TYPE_64K; if (settings->rail_mode_enabled) { flags |= INFO_RAIL; } domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length); cbDomain = length; userName = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->username, &length); cbUserName = length; password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &length); cbPassword = length; alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length); cbAlternateShell = length; workingDir = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->directory, &length); cbWorkingDir = length; stream_write_uint32(s, 0); /* CodePage */ stream_write_uint32(s, flags); /* flags */ stream_write_uint16(s, cbDomain); /* cbDomain */ stream_write_uint16(s, cbUserName); /* cbUserName */ stream_write_uint16(s, cbPassword); /* cbPassword */ stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */ stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */ if (cbDomain > 0) stream_write(s, domain, cbDomain); stream_write_uint16(s, 0); if (cbUserName > 0) stream_write(s, userName, cbUserName); stream_write_uint16(s, 0); if (cbPassword > 0) stream_write(s, password, cbPassword); stream_write_uint16(s, 0); if (cbAlternateShell > 0) stream_write(s, alternateShell, cbAlternateShell); stream_write_uint16(s, 0); if (cbWorkingDir > 0) stream_write(s, workingDir, cbWorkingDir); stream_write_uint16(s, 0); xfree(domain); xfree(userName); xfree(password); xfree(alternateShell); xfree(workingDir); if (settings->rdp_version >= 5) rdp_write_extended_info_packet(s, settings); /* extraInfo */ }
boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, const char* path, STREAM* output) { struct dirent* ent; char* ent_path; struct STAT st; UNICONV* uniconv; size_t len; boolean ret; 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); xfree(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 (disk_file_wildcard_match(file->pattern, ent->d_name)) 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 = xmalloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf(ent_path, "%s/%s", file->fullpath, ent->d_name); if (STAT(ent_path, &st) != 0) { DEBUG_WARN("stat %s failed. errno = %d", ent_path, errno); } DEBUG_SVC(" pattern %s matched %s", file->pattern, ent_path); xfree(ent_path); uniconv = freerdp_uniconv_new(); ent_path = freerdp_uniconv_out(uniconv, ent->d_name, &len); freerdp_uniconv_free(uniconv); ret = true; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ stream_write_uint32(output, 64 + len); /* Length */ stream_check_size(output, 64 + len); 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, len); /* FileNameLength */ stream_write(output, ent_path, len); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ stream_write_uint32(output, 68 + len); /* Length */ stream_check_size(output, 68 + len); 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, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write(output, ent_path, len); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ stream_write_uint32(output, 93 + len); /* Length */ stream_check_size(output, 93 + len); 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, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write_uint8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ stream_write_zero(output, 24); /* ShortName */ stream_write(output, ent_path, len); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ stream_write_uint32(output, 12 + len); /* Length */ stream_check_size(output, 12 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint32(output, len); /* FileNameLength */ stream_write(output, ent_path, len); break; default: stream_write_uint32(output, 0); /* Length */ stream_write_uint8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = false; break; } xfree(ent_path); return ret; }
boolean nego_send_negotiation_response(rdpNego* nego) { STREAM* s; uint8* bm; uint8* em; int length; boolean status; rdpSettings* settings; status = true; settings = nego->transport->settings; s = transport_send_stream_init(nego->transport, 256); length = TPDU_CONNECTION_CONFIRM_LENGTH; stream_get_mark(s, bm); stream_seek(s, length); if (nego->selected_protocol > PROTOCOL_RDP) { /* RDP_NEG_DATA must be present for TLS and NLA */ stream_write_uint8(s, TYPE_RDP_NEG_RSP); stream_write_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ stream_write_uint32(s, nego->selected_protocol); /* selectedProtocol */ length += 8; } else if (!settings->rdp_security) { stream_write_uint8(s, TYPE_RDP_NEG_FAILURE); stream_write_uint8(s, 0); /* flags */ stream_write_uint16(s, 8); /* RDP_NEG_DATA length (8) */ /* * TODO: Check for other possibilities, * like SSL_NOT_ALLOWED_BY_SERVER. */ printf("nego_send_negotiation_response: client supports only Standard RDP Security\n"); stream_write_uint32(s, SSL_REQUIRED_BY_SERVER); length += 8; status = false; } stream_get_mark(s, em); stream_set_mark(s, bm); tpkt_write_header(s, length); tpdu_write_connection_confirm(s, length - 5); stream_set_mark(s, em); if (transport_write(nego->transport, s) < 0) return false; if (status) { /* update settings with negotiated protocol security */ settings->requested_protocols = nego->requested_protocols; settings->selected_protocol = nego->selected_protocol; if (settings->selected_protocol == PROTOCOL_RDP) { settings->tls_security = false; settings->nla_security = false; settings->rdp_security = true; if (!settings->local) { settings->encryption = true; settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS; settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } if (settings->encryption && settings->server_key == NULL && settings->rdp_key_file == NULL) return false; } else if (settings->selected_protocol == PROTOCOL_TLS) { settings->tls_security = true; settings->nla_security = false; settings->rdp_security = false; settings->encryption = false; settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; } else if (settings->selected_protocol == PROTOCOL_NLA) { settings->tls_security = true; settings->nla_security = true; settings->rdp_security = false; settings->encryption = false; settings->encryption_method = ENCRYPTION_METHOD_NONE; settings->encryption_level = ENCRYPTION_LEVEL_NONE; } } return status; }
void rail_write_client_notify_event_order(STREAM* s, RAIL_NOTIFY_EVENT_ORDER* notify_event) { stream_write_uint32(s, notify_event->windowId); /* windowId (4 bytes) */ stream_write_uint32(s, notify_event->notifyIconId); /* notifyIconId (4 bytes) */ stream_write_uint32(s, notify_event->message); /* notifyIconId (4 bytes) */ }
void gcc_write_client_core_data(STREAM* s, rdpSettings *settings) { uint32 version; uint8* clientName; size_t clientNameLength; uint8 connectionType; uint16 highColorDepth; uint16 supportedColorDepths; uint16 earlyCapabilityFlags; uint8* clientDigProductId; size_t clientDigProductIdLength; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientName = freerdp_uniconv_out(settings->uniconv, settings->client_hostname, &clientNameLength); clientDigProductId = freerdp_uniconv_out(settings->uniconv, settings->client_product_id, &clientDigProductIdLength); stream_write_uint32(s, version); /* version */ stream_write_uint16(s, settings->width); /* desktopWidth */ stream_write_uint16(s, settings->height); /* 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->kbd_layout); /* keyboardLayout */ stream_write_uint32(s, settings->client_build); /* clientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength > 30) { clientNameLength = 30; clientName[clientNameLength] = 0; clientName[clientNameLength + 1] = 0; } stream_write(s, clientName, clientNameLength + 2); stream_write_zero(s, 32 - clientNameLength - 2); xfree(clientName); stream_write_uint32(s, settings->kbd_type); /* keyboardType */ stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */ stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */ stream_write_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->color_depth, 24); supportedColorDepths = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; connectionType = 0; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->performance_flags == PERF_FLAG_NONE) { earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; connectionType = CONNECTION_TYPE_LAN; } if (settings->color_depth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } 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 30 characters) */ if (clientDigProductIdLength > 62) { clientDigProductIdLength = 62; clientDigProductId[clientDigProductIdLength] = 0; clientDigProductId[clientDigProductIdLength + 1] = 0; } stream_write(s, clientDigProductId, clientDigProductIdLength + 2); stream_write_zero(s, 64 - clientDigProductIdLength - 2); xfree(clientDigProductId); stream_write_uint8(s, connectionType); /* connectionType */ stream_write_uint8(s, 0); /* pad1octet */ stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */ }
void rail_write_client_get_appid_req_order(STREAM* s, RAIL_GET_APPID_REQ_ORDER* get_appid_req) { stream_write_uint32(s, get_appid_req->windowId); /* windowId (4 bytes) */ }
void rdp_write_input_event_header(STREAM* s, uint32 time, uint16 type) { stream_write_uint32(s, time); /* eventTime (4 bytes) */ stream_write_uint16(s, type); /* messageType (2 bytes) */ }
void rail_write_langbar_info_order(STREAM* s, RAIL_LANGBAR_INFO_ORDER* langbar_info) { stream_write_uint32(s, langbar_info->languageBarStatus); /* languageBarStatus (4 bytes) */ }
void ntlm_output_av_pairs(NTLM_CONTEXT* context, PSecBuffer buffer) { STREAM* s; AV_PAIRS* av_pairs = context->av_pairs; s = stream_new(0); stream_attach(s, buffer->pvBuffer, buffer->cbBuffer); if (av_pairs->NbDomainName.length > 0) { stream_write_uint16(s, MsvAvNbDomainName); /* AvId */ stream_write_uint16(s, av_pairs->NbDomainName.length); /* AvLen */ stream_write(s, av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); /* Value */ } if (av_pairs->NbComputerName.length > 0) { stream_write_uint16(s, MsvAvNbComputerName); /* AvId */ stream_write_uint16(s, av_pairs->NbComputerName.length); /* AvLen */ stream_write(s, av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); /* Value */ } if (av_pairs->DnsDomainName.length > 0) { stream_write_uint16(s, MsvAvDnsDomainName); /* AvId */ stream_write_uint16(s, av_pairs->DnsDomainName.length); /* AvLen */ stream_write(s, av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); /* Value */ } if (av_pairs->DnsComputerName.length > 0) { stream_write_uint16(s, MsvAvDnsComputerName); /* AvId */ stream_write_uint16(s, av_pairs->DnsComputerName.length); /* AvLen */ stream_write(s, av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); /* Value */ } if (av_pairs->DnsTreeName.length > 0) { stream_write_uint16(s, MsvAvDnsTreeName); /* AvId */ stream_write_uint16(s, av_pairs->DnsTreeName.length); /* AvLen */ stream_write(s, av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); /* Value */ } if (av_pairs->Timestamp.length > 0) { stream_write_uint16(s, MsvAvTimestamp); /* AvId */ stream_write_uint16(s, av_pairs->Timestamp.length); /* AvLen */ stream_write(s, av_pairs->Timestamp.value, av_pairs->Timestamp.length); /* Value */ } if (av_pairs->Flags > 0) { stream_write_uint16(s, MsvAvFlags); /* AvId */ stream_write_uint16(s, 4); /* AvLen */ stream_write_uint32(s, av_pairs->Flags); /* Value */ } if (av_pairs->Restrictions.length > 0) { stream_write_uint16(s, MsvAvRestrictions); /* AvId */ stream_write_uint16(s, av_pairs->Restrictions.length); /* AvLen */ stream_write(s, av_pairs->Restrictions.value, av_pairs->Restrictions.length); /* Value */ } if (av_pairs->ChannelBindings.length > 0) { stream_write_uint16(s, MsvChannelBindings); /* AvId */ stream_write_uint16(s, av_pairs->ChannelBindings.length); /* AvLen */ stream_write(s, av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); /* Value */ } if (av_pairs->TargetName.length > 0) { stream_write_uint16(s, MsvAvTargetName); /* AvId */ stream_write_uint16(s, av_pairs->TargetName.length); /* AvLen */ stream_write(s, av_pairs->TargetName.value, av_pairs->TargetName.length); /* Value */ } /* This indicates the end of the AV_PAIR array */ stream_write_uint16(s, MsvAvEOL); /* AvId */ stream_write_uint16(s, 0); /* AvLen */ if (context->ntlm_v2) { stream_write_zero(s, 8); } xfree(s); }
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) { uint8 *bm, *em, *lm; uint16 numberCapabilities; uint16 lengthSourceDescriptor; uint16 lengthCombinedCapabilities; lengthSourceDescriptor = sizeof(SOURCE_DESCRIPTOR); stream_write_uint32(s, settings->share_id); /* shareId (4 bytes) */ stream_write_uint16(s, 0x03EA); /* originatorId (2 bytes) */ stream_write_uint16(s, lengthSourceDescriptor);/* lengthSourceDescriptor (2 bytes) */ stream_get_mark(s, lm); stream_seek_uint16(s); /* lengthCombinedCapabilities (2 bytes) */ stream_write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor); /* sourceDescriptor */ stream_get_mark(s, bm); stream_seek_uint16(s); /* numberCapabilities (2 bytes) */ stream_write_uint16(s, 0); /* pad2Octets (2 bytes) */ /* Capability Sets */ numberCapabilities = 15; rdp_write_general_capability_set(s, settings); rdp_write_bitmap_capability_set(s, settings); rdp_write_order_capability_set(s, settings); rdp_write_bitmap_cache_capability_set(s, settings); rdp_write_pointer_capability_set(s, settings); rdp_write_input_capability_set(s, settings); rdp_write_brush_capability_set(s, settings); rdp_write_glyph_cache_capability_set(s, settings); rdp_write_offscreen_bitmap_cache_capability_set(s, settings); rdp_write_virtual_channel_capability_set(s, settings); rdp_write_sound_capability_set(s, settings); rdp_write_share_capability_set(s, settings); rdp_write_control_capability_set(s, settings); rdp_write_color_cache_capability_set(s, settings); rdp_write_window_activation_capability_set(s, settings); if (settings->offscreen_bitmap_cache) { numberCapabilities++; rdp_write_offscreen_bitmap_cache_capability_set(s, settings); } if (settings->received_caps[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE]) { numberCapabilities++; rdp_write_multifragment_update_capability_set(s, settings); } if (settings->received_caps[CAPSET_TYPE_LARGE_POINTER]) { numberCapabilities++; rdp_write_large_pointer_capability_set(s, settings); } if (settings->received_caps[CAPSET_TYPE_SURFACE_COMMANDS]) { numberCapabilities++; rdp_write_surface_commands_capability_set(s, settings); } #if 0 if (settings->received_caps[CAPSET_TYPE_BITMAP_CODECS]) { numberCapabilities++; rdp_write_bitmap_codecs_capability_set(s, settings); } #endif if (settings->received_caps[CAPSET_TYPE_FRAME_ACKNOWLEDGE]) { if (settings->frame_acknowledge) { numberCapabilities++; rdp_write_frame_acknowledge_capability_set(s, settings); } } stream_get_mark(s, em); stream_set_mark(s, lm); /* go back to lengthCombinedCapabilities */ lengthCombinedCapabilities = (em - bm); stream_write_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ stream_set_mark(s, bm); /* go back to numberCapabilities */ stream_write_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ stream_set_mark(s, em); }
static uint32 handle_LocateCardsByATR(IRP* irp, boolean wide) { LONG rv; int i, j, k; SCARDCONTEXT hContext; uint32 atrMaskCount = 0; uint32 readerCount = 0; SCARD_READERSTATE* cur = NULL; SCARD_READERSTATE* rsCur = NULL; SCARD_READERSTATE* readerStates = NULL; SERVER_SCARD_ATRMASK* curAtr = NULL; SERVER_SCARD_ATRMASK* pAtrMasks = NULL; stream_seek(irp->input, 0x2C); stream_read_uint32(irp->input, hContext); stream_read_uint32(irp->input, atrMaskCount); pAtrMasks = xmalloc(atrMaskCount * sizeof(SERVER_SCARD_ATRMASK)); if (!pAtrMasks) return sc_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < atrMaskCount; i++) { stream_read_uint32(irp->input, pAtrMasks[i].cbAtr); stream_read(irp->input, pAtrMasks[i].rgbAtr, 36); stream_read(irp->input, pAtrMasks[i].rgbMask, 36); } stream_read_uint32(irp->input, readerCount); readerStates = xzalloc(readerCount * sizeof(SCARD_READERSTATE)); if (!readerStates) return sc_output_return(irp, SCARD_E_NO_MEMORY); for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; stream_seek(irp->input, 4); /* * TODO: on-wire is little endian; need to either * convert to host endian or fix the headers to * request the order we want */ stream_read_uint32(irp->input, cur->dwCurrentState); stream_read_uint32(irp->input, cur->dwEventState); stream_read_uint32(irp->input, cur->cbAtr); stream_read(irp->input, cur->rgbAtr, 32); stream_seek(irp->input, 4); /* reset high bytes? */ cur->dwCurrentState &= 0x0000FFFF; cur->dwEventState &= 0x0000FFFF; cur->dwEventState = 0; } for (i = 0; i < readerCount; i++) { cur = &readerStates[i]; uint32 dataLength; stream_seek(irp->input, 8); stream_read_uint32(irp->input, dataLength); sc_input_repos(irp, sc_input_string(irp, (char **) &cur->szReader, dataLength, wide)); DEBUG_SCARD(" \"%s\"", cur->szReader ? cur->szReader : "NULL"); DEBUG_SCARD(" user: 0x%08x, state: 0x%08x, event: 0x%08x", (unsigned) cur->pvUserData, (unsigned) cur->dwCurrentState, (unsigned) cur->dwEventState); if (strcmp(cur->szReader, "\\\\?PnP?\\Notification") == 0) cur->dwCurrentState |= SCARD_STATE_IGNORE; } rv = SCardGetStatusChange(hContext, 0x00000001, readerStates, readerCount); if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); return sc_output_return(irp, rv); } DEBUG_SCARD("Success"); for (i = 0, curAtr = pAtrMasks; i < atrMaskCount; i++, curAtr++) { for (j = 0, rsCur = readerStates; j < readerCount; j++, rsCur++) { boolean equal = 1; for (k = 0; k < cur->cbAtr; k++) { if ((curAtr->rgbAtr[k] & curAtr->rgbMask[k]) != (rsCur->rgbAtr[k] & curAtr->rgbMask[k])) { equal = 0; break; } } if (equal) { rsCur->dwEventState |= 0x00000040; /* SCARD_STATE_ATRMATCH 0x00000040 */ } } } stream_write_uint32(irp->output, readerCount); stream_write_uint32(irp->output, 0x00084dd8); stream_write_uint32(irp->output, readerCount); for (i = 0, rsCur = readerStates; i < readerCount; i++, rsCur++) { stream_write_uint32(irp->output, cur->dwCurrentState); stream_write_uint32(irp->output, cur->dwEventState); stream_write_uint32(irp->output, cur->cbAtr); stream_write(irp->output, cur->rgbAtr, 32); stream_write_zero(irp->output, 4); xfree((void*) cur->szReader); } sc_output_alignment(irp, 8); free(readerStates); return rv; }
static void rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, boolean user_loggedon) { STREAM* data_out; DEVICE* device; LIST_ITEM* item; uint32 count; uint8 c; int data_len; int i; int count_pos; int pos; data_out = stream_new(256); stream_write_uint16(data_out, RDPDR_CTYP_CORE); stream_write_uint16(data_out, PAKID_CORE_DEVICELIST_ANNOUNCE); count_pos = stream_get_pos(data_out); count = 0; stream_seek_uint32(data_out); /* deviceCount */ for (item = rdpdr->devman->devices->head; item; item = item->next) { device = (DEVICE*)item->data; /** * 1. versionMinor 0x0005 doesn't send PAKID_CORE_USER_LOGGEDON * so all devices should be sent regardless of user_loggedon * 2. smartcard devices should be always sent * 3. other devices are sent only after user_loggedon */ if (rdpdr->versionMinor == 0x0005 || device->type == RDPDR_DTYP_SMARTCARD || user_loggedon) { data_len = (device->data == NULL ? 0 : stream_get_length(device->data)); stream_check_size(data_out, 20 + data_len); stream_write_uint32(data_out, device->type); /* deviceType */ stream_write_uint32(data_out, device->id); /* deviceID */ strncpy((char*)stream_get_tail(data_out), device->name, 8); for (i = 0; i < 8; i++) { stream_peek_uint8(data_out, c); if (c > 0x7F) stream_write_uint8(data_out, '_'); else stream_seek_uint8(data_out); } stream_write_uint32(data_out, data_len); if (data_len > 0) stream_write(data_out, stream_get_data(device->data), data_len); count++; printf("registered device #%d: %s (type=%d id=%d)\n", count, device->name, device->type, device->id); } } pos = stream_get_pos(data_out); stream_set_pos(data_out, count_pos); stream_write_uint32(data_out, count); stream_set_pos(data_out, pos); stream_seal(data_out); svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); }
static uint32 handle_ListReaders(IRP* irp, boolean wide) { uint32 len, rv; SCARDCONTEXT hContext; DWORD dwReaders; char *readerList = NULL, *walker; int elemLength, dataLength; int pos, poslen1, poslen2; stream_seek(irp->input, 8); stream_read_uint32(irp->input, len); stream_seek(irp->input, 0x1c); stream_read_uint32(irp->input, len); if (len != 4) return SCARD_F_INTERNAL_ERROR; stream_read_uint32(irp->input, hContext); /* ignore rest of [MS-RDPESC] 2.2.2.4 ListReaders_Call */ rv = SCARD_S_SUCCESS; #ifdef SCARD_AUTOALLOCATE dwReaders = SCARD_AUTOALLOCATE; rv = SCardListReaders(hContext, NULL, (LPSTR) &readerList, &dwReaders); #else rv = SCardListReaders(hContext, NULL, NULL, &dwReaders); readerList = xmalloc(dwReaders); rv = SCardListReaders(hContext, NULL, readerList, &dwReaders); #endif if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); return rv; } /* DEBUG_SCARD("Success 0x%08x %d %d", (unsigned) hContext, (unsigned) cchReaders, (int) strlen(readerList));*/ poslen1 = stream_get_pos(irp->output); stream_seek_uint32(irp->output); stream_write_uint32(irp->output, 0x01760650); poslen2 = stream_get_pos(irp->output); stream_seek_uint32(irp->output); walker = readerList; dataLength = 0; while (1) { elemLength = strlen(walker); if (elemLength == 0) break; dataLength += sc_output_string(irp, walker, wide); walker += elemLength + 1; elemLength = strlen(walker); } dataLength += sc_output_string(irp, "\0", wide); pos = stream_get_pos(irp->output); stream_set_pos(irp->output, poslen1); stream_write_uint32(irp->output, dataLength); stream_set_pos(irp->output, poslen2); stream_write_uint32(irp->output, dataLength); stream_set_pos(irp->output, pos); sc_output_repos(irp, dataLength); sc_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE SCardFreeMemory(hContext, readerList); #else xfree(readerList); #endif return rv; }
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; }
static uint32 handle_State(IRP* irp) { LONG rv; SCARDHANDLE hCard; DWORD state = 0, protocol = 0; DWORD readerLen; DWORD atrLen = MAX_ATR_SIZE; char * readerName; BYTE pbAtr[MAX_ATR_SIZE]; #ifdef WITH_DEBUG_SCARD int i; #endif stream_seek(irp->input, 0x24); stream_seek_uint32(irp->input); /* atrLen */ stream_seek(irp->input, 0x0c); stream_read_uint32(irp->input, hCard); stream_seek(irp->input, 0x04); #ifdef SCARD_AUTOALLOCATE readerLen = SCARD_AUTOALLOCATE; rv = SCardStatus(hCard, (LPSTR) &readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #else readerLen = 256; readerName = xmalloc(readerLen); rv = SCardStatus(hCard, (LPSTR) readerName, &readerLen, &state, &protocol, pbAtr, &atrLen); #endif if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); return sc_output_return(irp, rv); } DEBUG_SCARD("Success (hcard: 0x%08x len: %d state: 0x%08x, proto: 0x%08x)", (unsigned) hCard, (int) atrLen, (unsigned) state, (unsigned) protocol); #ifdef WITH_DEBUG_SCARD printf(" ATR: "); for (i = 0; i < atrLen; i++) printf("%02x%c", pbAtr[i], (i == atrLen - 1) ? ' ' : ':'); printf("\n"); #endif state = sc_map_state(state); stream_write_uint32(irp->output, state); stream_write_uint32(irp->output, protocol); stream_write_uint32(irp->output, atrLen); stream_write_uint32(irp->output, 0x00000001); stream_write_uint32(irp->output, atrLen); stream_write(irp->output, pbAtr, atrLen); sc_output_repos(irp, atrLen); sc_output_alignment(irp, 8); #ifdef SCARD_AUTOALLOCATE xfree(readerName); #else xfree(readerName); #endif return rv; }
static tbool rdp_client_establish_keys(rdpRdp* rdp) { uint8 client_random[CLIENT_RANDOM_LENGTH]; uint8 crypt_client_random[256 + 8]; uint32 key_len; uint8* mod; uint8* exp; uint32 length; STREAM* s; if (rdp->settings->encryption == false) { /* no RDP encryption */ return true; } /* encrypt client random */ memset(crypt_client_random, 0, sizeof(crypt_client_random)); crypto_nonce(client_random, sizeof(client_random)); key_len = rdp->settings->server_cert->cert_info.modulus.length; mod = rdp->settings->server_cert->cert_info.modulus.data; exp = rdp->settings->server_cert->cert_info.exponent; crypto_rsa_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; s = transport_send_stream_init(rdp->mcs->transport, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; stream_write_uint32(s, length); stream_write(s, crypt_client_random, length); if (transport_write(rdp->mcs->transport, s) < 0) { return false; } /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return false; } rdp->do_crypt = true; if (rdp->settings->secure_checksum) rdp->do_secure_checksum = true; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return true; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return true; }
static uint32 handle_Transmit(IRP* irp) { LONG rv; SCARDCONTEXT hCard; uint32 map[7], linkedLen; SCARD_IO_REQUEST pioSendPci, pioRecvPci, *pPioRecvPci; DWORD cbSendLength = 0, cbRecvLength = 0; BYTE *sendBuf = NULL, *recvBuf = NULL; stream_seek(irp->input, 0x14); stream_read_uint32(irp->input, map[0]); stream_seek(irp->input, 0x4); stream_read_uint32(irp->input, map[1]); stream_read_uint32(irp->input, pioSendPci.dwProtocol); stream_read_uint32(irp->input, pioSendPci.cbPciLength); stream_read_uint32(irp->input, map[2]); stream_read_uint32(irp->input, cbSendLength); stream_read_uint32(irp->input, map[3]); stream_read_uint32(irp->input, map[4]); stream_read_uint32(irp->input, map[5]); stream_read_uint32(irp->input, cbRecvLength); if (map[0] & SCARD_INPUT_LINKED) sc_input_skip_linked(irp); stream_seek(irp->input, 4); stream_read_uint32(irp->input, hCard); if (map[2] & SCARD_INPUT_LINKED) { /* sendPci */ stream_read_uint32(irp->input, linkedLen); stream_read_uint32(irp->input, pioSendPci.dwProtocol); stream_seek(irp->input, linkedLen - 4); sc_input_repos(irp, linkedLen); } pioSendPci.cbPciLength = sizeof(SCARD_IO_REQUEST); if (map[3] & SCARD_INPUT_LINKED) { /* send buffer */ stream_read_uint32(irp->input, linkedLen); sendBuf = xmalloc(linkedLen); stream_read(irp->input, sendBuf, linkedLen); sc_input_repos(irp, linkedLen); } if (cbRecvLength) recvBuf = xmalloc(cbRecvLength); if (map[4] & SCARD_INPUT_LINKED) { /* recvPci */ stream_read_uint32(irp->input, linkedLen); stream_read_uint32(irp->input, pioRecvPci.dwProtocol); stream_seek(irp->input, linkedLen - 4); sc_input_repos(irp, linkedLen); stream_read_uint32(irp->input, map[6]); if (map[6] & SCARD_INPUT_LINKED) { /* not sure what this is */ stream_read_uint32(irp->input, linkedLen); stream_seek(irp->input, linkedLen); sc_input_repos(irp, linkedLen); } pioRecvPci.cbPciLength = sizeof(SCARD_IO_REQUEST); pPioRecvPci = &pioRecvPci; } else { pPioRecvPci = NULL; } pPioRecvPci = NULL; DEBUG_SCARD("SCardTransmit(hcard: 0x%08lx, send: %d bytes, recv: %d bytes)", (long unsigned) hCard, (int) cbSendLength, (int) cbRecvLength); rv = SCardTransmit(hCard, &pioSendPci, sendBuf, cbSendLength, pPioRecvPci, recvBuf, &cbRecvLength); if (rv != SCARD_S_SUCCESS) { DEBUG_SCARD("Failure: %s (0x%08x)", pcsc_stringify_error(rv), (unsigned) rv); } else { DEBUG_SCARD("Success (%d bytes)", (int) cbRecvLength); stream_write_uint32(irp->output, 0); /* pioRecvPci 0x00; */ sc_output_buffer_start(irp, cbRecvLength); /* start of recvBuf output */ sc_output_buffer(irp, (char *) recvBuf, cbRecvLength); } sc_output_alignment(irp, 8); xfree(sendBuf); xfree(recvBuf); return rv; }
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) { uint32 bias; sint32 sbias; uint32 bias2c; size_t length; uint8* standardName; uint8* daylightName; size_t standardNameLength; size_t daylightNameLength; TIME_ZONE_INFO* clientTimeZone; clientTimeZone = settings->client_time_zone; freerdp_time_zone_detect(clientTimeZone); standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length); standardNameLength = length; daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length); daylightNameLength = length; if (standardNameLength > 62) standardNameLength = 62; if (daylightNameLength > 62) daylightNameLength = 62; /* UTC = LocalTime + Bias <-> Bias = UTC - LocalTime */ /* Translate from biases used throughout libfreerdp-locale/timezone.c * to what RDP expects, which is minutes *west* of UTC. * Though MS-RDPBCGR specifies bias as unsigned, two's complement * (a negative integer) works fine for zones east of UTC. */ if (clientTimeZone->bias <= 720) bias = -1 * clientTimeZone->bias; else bias = 1440 - clientTimeZone->bias; stream_write_uint32(s, bias); /* Bias */ /* standardName (64 bytes) */ stream_write(s, standardName, standardNameLength); stream_write_zero(s, 64 - standardNameLength); rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'", bias, clientTimeZone->standardName, clientTimeZone->daylightName); sbias = clientTimeZone->standardBias - clientTimeZone->bias; if (sbias < 0) bias2c = (uint32) sbias; else bias2c = ~((uint32) sbias) + 1; /* Note that StandardBias is ignored if no valid standardDate is provided. */ stream_write_uint32(s, bias2c); /* StandardBias */ DEBUG_TIMEZONE("StandardBias=%d", bias2c); /* daylightName (64 bytes) */ stream_write(s, daylightName, daylightNameLength); stream_write_zero(s, 64 - daylightNameLength); rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ sbias = clientTimeZone->daylightBias - clientTimeZone->bias; if (sbias < 0) bias2c = (uint32) sbias; else bias2c = ~((uint32) sbias) + 1; /* Note that DaylightBias is ignored if no valid daylightDate is provided. */ stream_write_uint32(s, bias2c); /* DaylightBias */ DEBUG_TIMEZONE("DaylightBias=%d", bias2c); xfree(standardName); xfree(daylightName); }