Second Batch: Update files using ChatGPT 4o

This commit is contained in:
Stig-Ørjan Smelror 2024-05-31 15:52:13 +02:00
parent 1fb029cde7
commit 669e3a9e11
4 changed files with 860 additions and 979 deletions

View File

@ -20,6 +20,7 @@
*/
#include "rdesktop.h"
#include <string.h>
#define MAX_CHANNELS 6
#define CHANNEL_CHUNK_LENGTH 1600
@ -27,139 +28,91 @@
#define CHANNEL_FLAG_LAST 0x02
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
#define MIN(a, b) ((a) < (b) ? (a) : (b))
extern RDP_VERSION g_rdp_version;
extern RD_BOOL g_encryption;
uint32 vc_chunk_size = CHANNEL_CHUNK_LENGTH;
uint32_t vc_chunk_size = CHANNEL_CHUNK_LENGTH;
VCHANNEL g_channels[MAX_CHANNELS];
unsigned int g_num_channels;
/* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
channels to MCS channels.
The format of TAG_SRV_CHANNELS seems to be
global_channel_no (uint16le)
number_of_other_channels (uint16le)
..followed by uint16les for the other channels.
*/
VCHANNEL *
channel_register(char *name, uint32 flags, void (*callback) (STREAM))
{
VCHANNEL *channel;
if (g_rdp_version < RDP_V5)
return NULL;
if (g_num_channels >= MAX_CHANNELS)
{
logger(Core, Error,
"channel_register(), channel table full, increase MAX_CHANNELS");
VCHANNEL *channel_register(const char *name, uint32_t flags, void (*callback) (STREAM)) {
if (g_rdp_version < RDP_V5) {
return NULL;
}
channel = &g_channels[g_num_channels];
if (g_num_channels >= MAX_CHANNELS) {
logger(Core, Error, "channel_register(), channel table full, increase MAX_CHANNELS");
return NULL;
}
VCHANNEL *channel = &g_channels[g_num_channels];
channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
strncpy(channel->name, name, 8);
strncpy(channel->name, name, sizeof(channel->name) - 1);
channel->name[sizeof(channel->name) - 1] = '\0'; // Ensure null-termination
channel->flags = flags;
channel->process = callback;
g_num_channels++;
return channel;
}
STREAM
channel_init(VCHANNEL * channel, uint32 length)
{
STREAM channel_init(VCHANNEL *channel, uint32_t length) {
UNUSED(channel);
STREAM s;
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
STREAM s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
s_push_layer(s, channel_hdr, 8);
return s;
}
static void
channel_send_chunk(STREAM s, VCHANNEL * channel, uint32 length)
{
uint32 flags;
uint32 thislength;
static void channel_send_chunk(STREAM s, VCHANNEL *channel, uint32_t length) {
uint32_t flags;
uint32_t thislength;
RD_BOOL inplace;
STREAM chunk;
/* Note: In the original clipboard implementation, this number was
1592, not 1600. However, I don't remember the reason and 1600 seems
to work so.. This applies only to *this* length, not the length of
continuation or ending packets. */
/* Actually, CHANNEL_CHUNK_LENGTH (default value is 1600 bytes) is described
in MS-RDPBCGR (s. 2.2.6, s.3.1.5.2.1) and can be set by server only
in the optional field VCChunkSize of VC Caps) */
thislength = MIN(s_remaining(s), vc_chunk_size);
flags = 0;
if (length == s_remaining(s))
{
if (length == s_remaining(s)) {
flags |= CHANNEL_FLAG_FIRST;
}
if (s_remaining(s) == thislength)
{
if (s_remaining(s) == thislength) {
flags |= CHANNEL_FLAG_LAST;
}
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
{
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) {
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
logger(Protocol, Debug, "channel_send_chunk(), sending %d bytes with flags 0x%x",
thislength, flags);
/* first fragment sent in-place */
inplace = False;
if ((flags & (CHANNEL_FLAG_FIRST|CHANNEL_FLAG_LAST)) ==
(CHANNEL_FLAG_FIRST|CHANNEL_FLAG_LAST))
{
inplace = True;
}
inplace = (flags & (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST)) == (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST);
if (inplace)
{
if (inplace) {
s_pop_layer(s, channel_hdr);
chunk = s;
}
else
{
} else {
chunk = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
}
out_uint32_le(chunk, length);
out_uint32_le(chunk, flags);
if (!inplace)
{
if (!inplace) {
out_uint8stream(chunk, s, thislength);
s_mark_end(chunk);
}
sec_send_to_channel(chunk, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
/* Sending modifies the current offset, so make it is marked as
fully completed. */
if (inplace)
{
if (inplace) {
in_uint8s(s, s_remaining(s));
}
if (!inplace)
{
} else {
s_free(chunk);
}
}
void
channel_send(STREAM s, VCHANNEL * channel)
{
uint32 length;
void channel_send(STREAM s, VCHANNEL *channel) {
uint32_t length;
#ifdef WITH_SCARD
scard_lock(SCARD_LOCK_CHANNEL);
@ -169,11 +122,9 @@ channel_send(STREAM s, VCHANNEL * channel)
in_uint8s(s, 8);
length = s_remaining(s);
logger(Protocol, Debug, "channel_send(), channel = %d, length = %d", channel->mcs_id,
length);
logger(Protocol, Debug, "channel_send(), channel = %d, length = %d", channel->mcs_id, length);
while (!s_check_end(s))
{
while (!s_check_end(s)) {
channel_send_chunk(s, channel, length);
}
@ -182,38 +133,31 @@ channel_send(STREAM s, VCHANNEL * channel)
#endif
}
void
channel_process(STREAM s, uint16 mcs_channel)
{
uint32 length, flags;
uint32 thislength;
void channel_process(STREAM s, uint16_t mcs_channel) {
uint32_t length, flags;
uint32_t thislength;
VCHANNEL *channel = NULL;
unsigned int i;
STREAM in;
for (i = 0; i < g_num_channels; i++)
{
for (i = 0; i < g_num_channels; i++) {
channel = &g_channels[i];
if (channel->mcs_id == mcs_channel)
if (channel->mcs_id == mcs_channel) {
break;
}
}
if (i >= g_num_channels)
if (i >= g_num_channels) {
return;
}
in_uint32_le(s, length);
in_uint32_le(s, flags);
if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
{
/* single fragment - pass straight up */
if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST)) {
channel->process(s);
}
else
{
/* add fragment to defragmentation buffer */
} else {
in = &channel->in;
if (flags & CHANNEL_FLAG_FIRST)
{
if (flags & CHANNEL_FLAG_FIRST) {
s_realloc(in, length);
s_reset(in);
}
@ -221,8 +165,7 @@ channel_process(STREAM s, uint16 mcs_channel)
thislength = s_remaining(s);
out_uint8stream(in, s, thislength);
if (flags & CHANNEL_FLAG_LAST)
{
if (flags & CHANNEL_FLAG_LAST) {
s_mark_end(in);
s_seek(in, 0);
channel->process(in);

View File

@ -20,6 +20,7 @@
*/
#include "rdesktop.h"
#include <string.h>
#define CLIPRDR_CONNECT 1
#define CLIPRDR_FORMAT_ANNOUNCE 2
@ -31,24 +32,25 @@
#define CLIPRDR_RESPONSE 1
#define CLIPRDR_ERROR 2
#define FORMAT_DESCRIPTOR_SIZE 36
static VCHANNEL *cliprdr_channel;
static uint8 *last_formats = NULL;
static uint32 last_formats_length = 0;
static void
cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
{
static void cliprdr_send_packet(uint16 type, uint16 status, const uint8 *data, uint32 length) {
STREAM s;
logger(Clipboard, Debug, "cliprdr_send_packet(), type=%d, status=%d, length=%d", type,
status, length);
logger(Clipboard, Debug, "cliprdr_send_packet(), type=%d, status=%d, length=%d", type, status, length);
s = channel_init(cliprdr_channel, length + 12);
out_uint16_le(s, type);
out_uint16_le(s, status);
out_uint32_le(s, length);
if (data && length > 0) {
out_uint8a(s, data, length);
}
out_uint32(s, 0); /* pad? */
s_mark_end(s);
channel_send(s, cliprdr_channel);
@ -60,16 +62,12 @@ cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
To announce more than one format at a time, use
cliprdr_send_native_format_announce.
*/
void
cliprdr_send_simple_native_format_announce(uint32 format)
{
uint8 buffer[36];
void cliprdr_send_simple_native_format_announce(uint32 format) {
uint8 buffer[FORMAT_DESCRIPTOR_SIZE] = {0};
logger(Clipboard, Debug, "cliprdr_send_simple_native_format_announce() format 0x%x",
format);
logger(Clipboard, Debug, "cliprdr_send_simple_native_format_announce() format 0x%x", format);
buf_out_uint32(buffer, format);
memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */
cliprdr_send_native_format_announce(buffer, sizeof(buffer));
}
@ -77,18 +75,15 @@ cliprdr_send_simple_native_format_announce(uint32 format)
formats, each denoted by a 36-byte format descriptor of
[ uint32 format + 32-byte description ].
*/
void
cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length)
{
void cliprdr_send_native_format_announce(const uint8 *formats_data, uint32 formats_data_length) {
logger(Clipboard, Debug, "cliprdr_send_native_format_announce()");
cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data,
formats_data_length);
cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data, formats_data_length);
if (formats_data != last_formats)
{
if (last_formats)
if (formats_data != last_formats) {
if (last_formats) {
xfree(last_formats);
}
last_formats = xmalloc(formats_data_length);
memcpy(last_formats, formats_data, formats_data_length);
@ -96,9 +91,7 @@ cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_le
}
}
void
cliprdr_send_data_request(uint32 format)
{
void cliprdr_send_data_request(uint32 format) {
uint8 buffer[4];
logger(Clipboard, Debug, "cliprdr_send_data_request(), format 0x%x", format);
@ -106,50 +99,39 @@ cliprdr_send_data_request(uint32 format)
cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
}
void
cliprdr_send_data(uint8 * data, uint32 length)
{
void cliprdr_send_data(const uint8 *data, uint32 length) {
logger(Clipboard, Debug, "cliprdr_send_data(), length %d bytes", length);
cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
}
static void
cliprdr_process(STREAM s)
{
static void cliprdr_process(STREAM s) {
uint16 type, status;
uint32 length, format;
uint8 *data;
const uint8 *data;
in_uint16_le(s, type);
in_uint16_le(s, status);
in_uint32_le(s, length);
logger(Clipboard, Debug, "cliprdr_process(), type=%d, status=%d, length=%d", type, status,
length);
logger(Clipboard, Debug, "cliprdr_process(), type=%d, status=%d, length=%d", type, status, length);
if (status == CLIPRDR_ERROR)
{
switch (type)
{
if (status == CLIPRDR_ERROR) {
switch (type) {
case CLIPRDR_FORMAT_ACK:
/* FIXME: We seem to get this when we send an announce while the server is
still processing a paste. Try sending another announce. */
cliprdr_send_native_format_announce(last_formats,
last_formats_length);
cliprdr_send_native_format_announce(last_formats, last_formats_length);
break;
case CLIPRDR_DATA_RESPONSE:
ui_clip_request_failed();
break;
default:
logger(Clipboard, Warning,
"cliprdr_process(), unhandled error (type=%d)", type);
logger(Clipboard, Warning, "cliprdr_process(), unhandled error (type=%d)", type);
}
return;
}
switch (type)
{
switch (type) {
case CLIPRDR_CONNECT:
ui_clip_sync();
break;
@ -171,22 +153,16 @@ cliprdr_process(STREAM s)
case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
break;
default:
logger(Clipboard, Warning, "cliprdr_process(), unhandled packet type %d",
type);
logger(Clipboard, Warning, "cliprdr_process(), unhandled packet type %d", type);
}
}
void
cliprdr_set_mode(const char *optarg)
{
void cliprdr_set_mode(const char *optarg) {
ui_clip_set_mode(optarg);
}
RD_BOOL
cliprdr_init(void)
{
cliprdr_channel =
channel_register("cliprdr",
RD_BOOL cliprdr_init(void) {
cliprdr_channel = channel_register("cliprdr",
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
cliprdr_process);

View File

@ -22,24 +22,27 @@
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
#include <stdint.h>
/* TCP port for Remote Desktop Protocol */
#define TCP_PORT_RDP 3389
/* Default codepages */
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16LE"
/* T-REC-T.123-200701, section 8 */
/* T.123 header version */
#define T123_HEADER_VERSION 0x3
/* [MS-RDPBCGR] 2.2.9.1.2 */
/* Fast-Path Output Action Types */
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
#define FASTPATH_OUTPUT_ACTION_X224 T123_HEADER_VERSION
/* Fast-Path Output Security Flags */
#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
/* [MS-RDPBCGR] 2.2.9.1.2.1 */
/* adjusted for position in updateHeader */
/* Fast-Path Update Types (adjusted for position in updateHeader) */
#define FASTPATH_UPDATETYPE_ORDERS 0x0
#define FASTPATH_UPDATETYPE_BITMAP 0x1
#define FASTPATH_UPDATETYPE_PALETTE 0x2
@ -52,53 +55,54 @@
#define FASTPATH_UPDATETYPE_CACHED 0xA
#define FASTPATH_UPDATETYPE_POINTER 0xB
/* Fast-Path Fragmentation Flags */
#define FASTPATH_FRAGMENT_SINGLE (0x0 << 4)
#define FASTPATH_FRAGMENT_LAST (0x1 << 4)
#define FASTPATH_FRAGMENT_FIRST (0x2 << 4)
#define FASTPATH_FRAGMENT_NEXT (0x3 << 4)
/* Fast-Path Output Compression Flags */
#define FASTPATH_OUTPUT_COMPRESSION_USED (0x2 << 6)
/* Fast-Path Maximum Multi-Fragment Size */
#define RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE 65535
/* ISO PDU codes */
enum ISO_PDU_CODE
{
/* ISO PDU Codes */
typedef enum {
ISO_PDU_CR = 0xE0, /* Connection Request */
ISO_PDU_CC = 0xD0, /* Connection Confirm */
ISO_PDU_DR = 0x80, /* Disconnect Request */
ISO_PDU_DT = 0xF0, /* Data */
ISO_PDU_ER = 0x70 /* Error */
};
} ISO_PDU_CODE;
/* RDP protocol negotiating constants */
enum RDP_NEG_TYPE_CODE
{
/* RDP Negotiation Types */
typedef enum {
RDP_NEG_REQ = 1,
RDP_NEG_RSP = 2,
RDP_NEG_FAILURE = 3
};
} RDP_NEG_TYPE_CODE;
enum RDP_NEG_REQ_CODE
{
/* RDP Negotiation Request Codes */
typedef enum {
PROTOCOL_RDP = 0,
PROTOCOL_SSL = 1,
PROTOCOL_HYBRID = 2
};
PROTOCOL_HYBRID = 2,
PROTOCOL_HYBRID_EX = 8 /* Added for hybrid extended security */
} RDP_NEG_REQ_CODE;
enum RDP_NEG_FAILURE_CODE
{
/* RDP Negotiation Failure Codes */
typedef enum {
SSL_REQUIRED_BY_SERVER = 1,
SSL_NOT_ALLOWED_BY_SERVER = 2,
SSL_CERT_NOT_ON_SERVER = 3,
INCONSISTENT_FLAGS = 4,
HYBRID_REQUIRED_BY_SERVER = 5,
SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 6
};
} RDP_NEG_FAILURE_CODE;
/* MCS PDU codes */
enum MCS_PDU_TYPE
{
/* MCS PDU Types */
typedef enum {
MCS_EDRQ = 1, /* Erect Domain Request */
MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
MCS_AURQ = 10, /* Attach User Request */
@ -107,11 +111,12 @@ enum MCS_PDU_TYPE
MCS_CJCF = 15, /* Channel Join Confirm */
MCS_SDRQ = 25, /* Send Data Request */
MCS_SDIN = 26 /* Send Data Indication */
};
} MCS_PDU_TYPE;
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
/* BER Tags */
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
@ -125,18 +130,16 @@ enum MCS_PDU_TYPE
#define MCS_GLOBAL_CHANNEL 1003
#define MCS_USERCHANNEL_BASE 1001
/* ITU-T Rec. T.125, Reason enumeration used with Disconnect Provider
Ultimatum, see mcs_send_dpu(reason) */
enum MCS_DPU_REASON
{
/* ITU-T Rec. T.125, Reason enumeration for Disconnect Provider Ultimatum */
typedef enum {
RN_DOMAIN_DISCONNECTED = 0,
RN_PROVIDER_INITIATED,
RN_TOKEN_PURGED,
RN_USER_REQUESTED,
RN_CHANNEL_PURGED,
};
} MCS_DPU_REASON;
/* RDP secure transport constants */
/* RDP Secure Transport Constants */
#define SEC_RANDOM_SIZE 32
#define SEC_MODULUS_SIZE 64
#define SEC_MAX_MODULUS_SIZE 256
@ -186,107 +189,98 @@ enum MCS_DPU_REASON
#define SEC_CC_REDIRECT_VERSION_5 0x04
#define SEC_CC_REDIRECT_VERSION_6 0x05
/* RDP licensing constants */
#define LICENCE_TOKEN_SIZE 10
#define LICENCE_HWID_SIZE 20
#define LICENCE_SIGNATURE_SIZE 16
/* RDP Licensing Constants */
#define LICENSE_TOKEN_SIZE 10
#define LICENSE_HWID_SIZE 20
#define LICENSE_SIGNATURE_SIZE 16
#define LICENCE_TAG_REQUEST 0x01
#define LICENCE_TAG_PLATFORM_CHALLENGE 0x02
#define LICENCE_TAG_NEW_LICENCE 0x03
#define LICENCE_TAG_UPGRADE_LICENCE 0x04
#define LICENCE_TAG_LICENCE_INFO 0x12
#define LICENCE_TAG_NEW_LICENCE_REQUEST 0x13
#define LICENCE_TAG_PLATFORM_CHALLENGE_RESPONSE 0x15
#define LICENCE_TAG_ERROR_ALERT 0xff
#define LICENSE_TAG_REQUEST 0x01
#define LICENSE_TAG_PLATFORM_CHALLENGE 0x02
#define LICENSE_TAG_NEW_LICENSE 0x03
#define LICENSE_TAG_UPGRADE_LICENSE 0x04
#define LICENSE_TAG_LICENSE_INFO 0x12
#define LICENSE_TAG_NEW_LICENSE_REQUEST 0x13
#define LICENSE_TAG_PLATFORM_CHALLENGE_RESPONSE 0x15
#define LICENSE_TAG_ERROR_ALERT 0xff
#define BB_CLIENT_USER_NAME_BLOB 0x000f
#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
/* RDP PDU codes */
enum RDP_PDU_TYPE
{
/* RDP PDU Codes */
typedef enum {
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
RDP_PDU_REDIRECT = 4, /* Standard Server Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7,
RDP_PDU_ENHANCED_REDIRECT = 10 /* Enhanced Server Redirect */
};
} RDP_PDU_TYPE;
enum RDP_DATA_PDU_TYPE
{
typedef enum {
RDP_DATA_PDU_UPDATE = 0x02, /* PDUTYPE2_UPDATE */
RDP_DATA_PDU_CONTROL = 0x14, /* PDUTYPE2_CONTROL */
RDP_DATA_PDU_POINTER = 0x1b, /* PDUTYPE2_POINTER */
RDP_DATA_PDU_INPUT = 0x1c, /* PDUTYPE2_INPUT */
RDP_DATA_PDU_SYNCHRONISE = 0x1f, /* PDUTYPE2_SYNCHRONIZE */
RDP_DATA_PDU_SYNCHRONIZE = 0x1f, /* PDUTYPE2_SYNCHRONIZE */
RDP_DATA_PDU_BELL = 0x22, /* PDUTYPE2_PLAY_SOUND */
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 0x23, /* PDUTYPE2_SUPRESS_OUTPUT */
RDP_DATA_PDU_LOGON = 0x26, /* PDUTYPE2_SAVE_SESSION_INFO */
RDP_DATA_PDU_FONT2 = 0x27, /* PDUTYPE2_FONTLIST */
RDP_DATA_PDU_KEYBOARD_INDICATORS = 0x29, /* PDUTYPE2_SET_KEYBOARD_INDICATORS */
RDP_DATA_PDU_SET_ERROR_INFO = 0x2f, /* PDUTYPE2_SET_ERROR_INFO */
RDP_DATA_PDU_AUTORECONNECT_STATUS = 0x32, /* PDUTYPE2_ARC_STATUS_PDU */
};
RDP_DATA_PDU_AUTORECONNECT_STATUS = 0x32 /* PDUTYPE2_ARC_STATUS_PDU */
} RDP_DATA_PDU_TYPE;
enum RDP_SAVE_SESSION_PDU_TYPE
{
typedef enum {
INFOTYPE_LOGON = 0,
INFOTYPE_LOGON_LONG = 1,
INFOTYPE_LOGON_PLAINNOTIFY = 2,
INFOTYPE_LOGON_EXTENDED_INF = 3
};
} RDP_SAVE_SESSION_PDU_TYPE;
enum RDP_LOGON_INFO_EXTENDED_TYPE
{
typedef enum {
LOGON_EX_AUTORECONNECTCOOKIE = 1,
LOGON_EX_LOGONERRORS = 2
};
} RDP_LOGON_INFO_EXTENDED_TYPE;
enum RDP_CONTROL_PDU_TYPE
{
typedef enum {
RDP_CTL_REQUEST_CONTROL = 1,
RDP_CTL_GRANT_CONTROL = 2,
RDP_CTL_DETACH = 3,
RDP_CTL_COOPERATE = 4
};
} RDP_CONTROL_PDU_TYPE;
enum RDP_UPDATE_PDU_TYPE
{
typedef enum {
RDP_UPDATE_ORDERS = 0,
RDP_UPDATE_BITMAP = 1,
RDP_UPDATE_PALETTE = 2,
RDP_UPDATE_SYNCHRONIZE = 3
};
} RDP_UPDATE_PDU_TYPE;
enum RDP_POINTER_PDU_TYPE
{
typedef enum {
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7,
RDP_POINTER_NEW = 8
};
} RDP_POINTER_PDU_TYPE;
/* [MS-RDPBCGR] 2.2.9.1.1.4.3 */
enum RDP_SYSTEM_POINTER_TYPE
{
/* System Pointer Types */
typedef enum {
SYSPTR_NULL = 0x00000000,
SYSPTR_DEFAULT = 0x00007F00
};
} RDP_SYSTEM_POINTER_TYPE;
enum RDP_INPUT_DEVICE
{
typedef enum {
RDP_INPUT_SYNCHRONIZE = 0,
RDP_INPUT_CODEPOINT = 1,
RDP_INPUT_VIRTKEY = 2,
RDP_INPUT_SCANCODE = 4,
RDP_INPUT_MOUSE = 0x8001,
RDP_INPUT_MOUSEX = 0x8002
};
} RDP_INPUT_DEVICE;
/* Device flags */
/* Device Flags */
#define KBD_FLAG_RIGHT 0x0001
#define KBD_FLAG_EXT 0x0100
#define KBD_FLAG_EXT1 0x0200
@ -294,15 +288,15 @@ enum RDP_INPUT_DEVICE
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
/* These are for synchronization; not for keystrokes */
#define KBD_FLAG_SCROLL 0x0001
#define KBD_FLAG_NUMLOCK 0x0002
#define KBD_FLAG_CAPITAL 0x0004
/* See T.128 */
/* Keypress and Keyrelease */
#define RDP_KEYPRESS 0
#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
/* Mouse Flags */
#define MOUSE_FLAG_MOVE 0x0800
#define MOUSE_FLAG_BUTTON1 0x1000
#define MOUSE_FLAG_BUTTON2 0x2000
@ -313,7 +307,7 @@ enum RDP_INPUT_DEVICE
#define MOUSEX_FLAG_BUTTON2 0x0002
#define MOUSE_FLAG_DOWN 0x8000
/* Raster operation masks */
/* Raster Operation Masks */
#define ROP2_S(rop3) (rop3 & 0xf)
#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2))
@ -332,7 +326,7 @@ enum RDP_INPUT_DEVICE
#define ALTERNATE 1
#define WINDING 2
/* RDP bitmap cache (version 2) constants */
/* RDP Bitmap Cache (Version 2) Constants */
#define BMPCACHE2_C0_CELLS 0x78
#define BMPCACHE2_C1_CELLS 0x78
#define BMPCACHE2_C2_CELLS 0x150
@ -341,8 +335,8 @@ enum RDP_INPUT_DEVICE
#define PDU_FLAG_FIRST 0x01
#define PDU_FLAG_LAST 0x02
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
/* RDP Capabilities */
#define RDP_CAPSET_GENERAL 1
#define RDP_CAPLEN_GENERAL 0x18
#define OS_MAJOR_TYPE_UNIX 4
#define OS_MINOR_TYPE_XSERVER 7
@ -391,7 +385,7 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
#define BMPCACHE2_FLAG_PERSIST ((uint32_t)1 << 31)
#define RDP_CAPSET_MULTIFRAGMENTUPDATE 26
#define RDP_CAPLEN_MULTIFRAGMENTUPDATE 8
@ -404,7 +398,7 @@ enum RDP_INPUT_DEVICE
#define RDP_SOURCE "MSTSC"
/* Logon flags */
/* Logon Flags */
#define RDP_INFO_MOUSE 0x00000001
#define RDP_INFO_DISABLECTRLALTDEL 0x00000002
#define RDP_INFO_AUTOLOGON 0x00000008
@ -425,7 +419,7 @@ enum RDP_INPUT_DEVICE
#define PERF_DISABLE_CURSORSETTINGS 0x40 /* disables cursor blinking */
#define PERF_ENABLE_FONT_SMOOTHING 0x80
/* compression types */
/* Compression Types */
#define RDP_MPPC_BIG 0x01
#define RDP_MPPC_COMPRESSED 0x20
#define RDP_MPPC_RESET 0x40
@ -434,7 +428,7 @@ enum RDP_INPUT_DEVICE
#define RDP5_COMPRESSED 0x80
/* Keymap flags */
/* Keymap Flags */
#define MapRightShiftMask (1 << 0)
#define MapLeftShiftMask (1 << 1)
#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
@ -455,7 +449,6 @@ enum RDP_INPUT_DEVICE
#define MapCapsLockMask (1 << 9)
#define MapLocalStateMask (1 << 10)
#define MapInhibitMask (1 << 11)
#define MASK_ADD_BITS(var, mask) (var |= mask)
@ -463,10 +456,7 @@ enum RDP_INPUT_DEVICE
#define MASK_HAS_BITS(var, mask) ((var & mask) > 0)
#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
/* Clipboard constants, "borrowed" from GCC system headers in
the w32 cross compiler
this is the CF_ set when WINVER is 0x0400 */
/* Clipboard Constants */
#ifndef CF_TEXT
#define CF_TEXT 1
#define CF_BITMAP 2
@ -496,19 +486,19 @@ enum RDP_INPUT_DEVICE
#define CF_GDIOBJLAST 1023
#endif
/* Sound format constants */
/* Sound Format Constants */
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
/* Virtual Channel Options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
/* NT status codes for RDPDR */
/* NT Status Codes for RDPDR */
#define RD_STATUS_SUCCESS 0x00000000
#define RD_STATUS_NOT_IMPLEMENTED 0x00000001
#define RD_STATUS_PENDING 0x00000103
@ -534,12 +524,11 @@ enum RDP_INPUT_DEVICE
#define RD_STATUS_CANCELLED 0xc0000120
#define RD_STATUS_DIRECTORY_NOT_EMPTY 0xc0000101
/* RDPSND constants */
/* RDPSND Constants */
#define TSSNDCAPS_ALIVE 0x00000001
#define TSSNDCAPS_VOLUME 0x00000002
/* RDPDR constants */
/* RDPDR Constants */
#define RDPDR_CTYP_CORE 0x4472
#define RDPDR_CTYP_PRN 0x5052
@ -612,11 +601,7 @@ enum RDP_INPUT_DEVICE
#define RDPDR_CLIENT_DISPLAY_NAME_PDU 0x00000002
#define RDPDR_USER_LOGGEDON_PDU 0x00000004
/* RDP5 disconnect PDU
*
* Named after the corresponding names on the server side:
* https://msdn.microsoft.com/en-us/library/cc240544.aspx
*/
/* RDP5 Disconnect PDU Error Codes */
#define ERRINFO_UNSET (unsigned)(-1)
#define ERRINFO_NO_INFO 0x0000
#define ERRINFO_RPC_INITIATED_DISCONNECT 0x0001
@ -658,7 +643,7 @@ enum RDP_INPUT_DEVICE
#define ERRINFO_DECRYPTFAILED 0x1192
#define ERRINFO_ENCRYPTFAILED 0x1193
/* SeamlessRDP constants */
/* SeamlessRDP Constants */
#define SEAMLESSRDP_NOTYETMAPPED -1
#define SEAMLESSRDP_NORMAL 0
#define SEAMLESSRDP_MINIMIZED 1
@ -671,17 +656,15 @@ enum RDP_INPUT_DEVICE
#define SEAMLESSRDP_HELLO_RECONNECT 0x0001
#define SEAMLESSRDP_HELLO_HIDDEN 0x0002
/* Smartcard constants */
/* Smartcard Constants */
#define SCARD_LOCK_TCP 0
#define SCARD_LOCK_SEC 1
#define SCARD_LOCK_CHANNEL 2
#define SCARD_LOCK_RDPDR 3
#define SCARD_LOCK_LAST 4
/* redirect flags, from [MS-RDPBCGR] 2.2.13.1 */
enum RDP_PDU_REDIRECT_FLAGS
{
/* Redirect Flags, from [MS-RDPBCGR] 2.2.13.1 */
typedef enum {
LB_TARGET_NET_ADDRESS = 0x1,
LB_LOAD_BALANCE_INFO = 0x2,
LB_USERNAME = 0x4,
@ -698,17 +681,17 @@ enum RDP_PDU_REDIRECT_FLAGS
LB_PASSWORD_IS_PK_ENCRYPTED = 0x4000,
LB_REDIRECTION_GUID = 0x8000,
LB_TARGET_CERTIFICATE = 0x10000
};
} RDP_PDU_REDIRECT_FLAGS;
/* desktop orientation */
enum RDP_DESKTOP_ORIENTATION
{
/* Desktop Orientation */
typedef enum {
ORIENTATION_LANDSCAPE = 0,
ORIENTATION_PORTRAIT = 90,
ORIENTATION_LANDSCAPE_FLIPPED = 180,
ORIENTATION_PORTRAIT_FLIPPED = 270
};
/* color depths, from [MS-RDPBCGR] 2.2.1.3.2 */
} RDP_DESKTOP_ORIENTATION;
/* Color Depths, from [MS-RDPBCGR] 2.2.1.3.2 */
#define RNS_UD_COLOR_4BPP 0xCA00
#define RNS_UD_COLOR_8BPP 0xCA01
#define RNS_UD_COLOR_16BPP_555 0xCA02
@ -717,7 +700,7 @@ enum RDP_DESKTOP_ORIENTATION
#define RNS_UD_SAS_DEL 0xAA03
/* version, [MS-RDPBCGR] 2.2.1.3.2 */
/* Version, from [MS-RDPBCGR] 2.2.1.3.2 */
#define RDP_40 0x00080001 /* RDP 4.0 clients */
#define RDP_50 0x00080004 /* RDP 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 8.0, and 8.1 clients */
#define RDP_10_0 0x00080005 /* RDP 10.0 clients */
@ -725,13 +708,13 @@ enum RDP_DESKTOP_ORIENTATION
#define RDP_10_2 0x00080007 /* RDP 10.2 clients */
#define RDP_10_3 0x00080008 /* RDP 10.3 clients */
/* supportedColorDepths, [MS-RDPBCGR] 2.2.1.3.2 */
/* Supported Color Depths, from [MS-RDPBCGR] 2.2.1.3.2 */
#define RNS_UD_24BPP_SUPPORT 0x0001
#define RNS_UD_16BPP_SUPPORT 0x0002
#define RNS_UD_15BPP_SUPPORT 0x0004
#define RNS_UD_32BPP_SUPPORT 0x0008
/* earlyCapabilityFlags, [MS-RDPBCGR] 2.2.1.3.2 */
/* Early Capability Flags, from [MS-RDPBCGR] 2.2.1.3.2 */
#define RNS_UD_CS_SUPPORT_ERRINFO_PDU 0x0001
#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002
#define RNS_UD_CS_SUPPORT_STATUSINFO_PDU 0x0004
@ -744,29 +727,29 @@ enum RDP_DESKTOP_ORIENTATION
#define RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE 0x0200
#define RNS_UD_CS_SUPPORT_HEARTBEAT_PDU 0x0400
/* [MS-RDPBCGR] 2.2.7.1.1 */
/* OS Major and Minor Types, from [MS-RDPBCGR] 2.2.7.1.1 */
#define OSMAJORTYPE_WINDOWS 0x0001
#define OSMINORTYPE_WINDOWSNT 0x0003
#define TS_CAPS_PROTOCOLVERSION 0x0200
/* extraFlags, [MS-RDPBCGR] 2.2.7.1.1 */
/* Extra Flags, from [MS-RDPBCGR] 2.2.7.1.1 */
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
#define LONG_CREDENTIALS_SUPPORTED 0x0004
#define AUTORECONNECT_SUPPORTED 0x0008
#define ENC_SALTED_CHECKSUM 0x0010
#define NO_BITMAP_COMPRESSION_HDR 0x0400
/* [MS-RDPBCGR], TS_BITMAP_DATA, flags */
/* Bitmap Compression, from [MS-RDPBCGR] TS_BITMAP_DATA.flags */
#define BITMAP_COMPRESSION 0x0001
/* orderFlags, [MS-RDPBCGR] 2.2.7.1.3 */
/* Order Flags, from [MS-RDPBCGR] 2.2.7.1.3 */
#define NEGOTIATEORDERSUPPORT 0x0002
#define ZEROBOUNDSDELTASSUPPORT 0x0008
#define COLORINDEXSUPPORT 0x0020
#define SOLIDPATTERNBRUSHONLY 0x0040
#define ORDERFLAGS_EXTRA_FLAGS 0x0080
/* orderSupport index, [MS-RDPBCGR] 2.2.7.1.3 */
/* Order Support Index, from [MS-RDPBCGR] 2.2.7.1.3 */
#define TS_NEG_DSTBLT_INDEX 0x00
#define TS_NEG_PATBLT_INDEX 0x01
#define TS_NEG_SCRBLT_INDEX 0x02
@ -789,7 +772,7 @@ enum RDP_DESKTOP_ORIENTATION
#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
#define TS_NEG_INDEX_INDEX 0x1B
/* [MS-RDPBCGR] 2.2.7.1.6 */
/* Input Flags, from [MS-RDPBCGR] 2.2.7.1.6 */
#define INPUT_FLAG_SCANCODES 0x0001
#define INPUT_FLAG_MOUSEX 0x0004
#define INPUT_FLAG_FASTPATH_INPUT 0x0008
@ -800,26 +783,25 @@ enum RDP_DESKTOP_ORIENTATION
#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
/* [MS-RDPBCGR] 2.2.7.1.8 */
/* Glyph Support Flags, from [MS-RDPBCGR] 2.2.7.1.8 */
#define GLYPH_SUPPORT_NONE 0x0000
#define GLYPH_SUPPORT_PARTIAL 0x0001
#define GLYPH_SUPPORT_FULL 0x0002
#define GLYPH_SUPPORT_ENCODE 0x0003
/* [MS-RDPBCGR] 2.2.7.1.11 */
/* Sound Beeps Flag, from [MS-RDPBCGR] 2.2.7.1.11 */
#define SOUND_BEEPS_FLAG 0x0001
/* [MS-RDPBCGR] 2.2.7.2.5 */
/* Font Support Flag, from [MS-RDPBCGR] 2.2.7.2.5 */
#define FONTSUPPORT_FONTLIST 0x0001
/* [MS-RDPBCGR] 2.2.7.2.7 */
/* Large Pointer Flag, from [MS-RDPBCGR] 2.2.7.2.7 */
#define LARGE_POINTER_FLAG_96x96 1
/* [MS-RDPBCGR] TS_SUPPRESS_OUTPUT_PDU allowDisplayUpdates */
enum RDP_SUPPRESS_STATUS
{
/* TS_SUPPRESS_OUTPUT_PDU allowDisplayUpdates */
typedef enum {
SUPPRESS_DISPLAY_UPDATES = 0x00,
ALLOW_DISPLAY_UPDATES = 0x01
};
} RDP_SUPPRESS_STATUS;
#endif /* _CONSTANTS_H */

340
cssp.c
View File

@ -44,9 +44,8 @@ ber_wrap_hdr_data(int tagval, STREAM in)
return out;
}
static void
cssp_gss_report_error(OM_uint32 code, char *str, OM_uint32 major_status, OM_uint32 minor_status)
cssp_gss_report_error(OM_uint32 code, const char *str, OM_uint32 major_status, OM_uint32 minor_status)
{
OM_uint32 msgctx = 0, ms;
gss_buffer_desc status_string;
@ -63,23 +62,19 @@ cssp_gss_report_error(OM_uint32 code, char *str, OM_uint32 major_status, OM_uint
if (ms != GSS_S_COMPLETE)
continue;
logger(Core, Debug, " - %s", status_string.value);
logger(Core, Debug, " - %s", (char*)status_string.value);
gss_release_buffer(&minor_status, &status_string);
}
while (ms == GSS_S_COMPLETE && msgctx);
}
static RD_BOOL
cssp_gss_mech_available(gss_OID mech)
{
int mech_found;
int mech_found = 0;
OM_uint32 major_status, minor_status;
gss_OID_set mech_set;
mech_found = 0;
if (mech == GSS_C_NO_OID)
return True;
@ -91,26 +86,26 @@ cssp_gss_mech_available(gss_OID mech)
{
cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to get available mechs on system",
major_status, minor_status);
gss_release_oid_set(&minor_status, &mech_set);
return False;
}
gss_test_oid_set_member(&minor_status, mech, mech_set, &mech_found);
major_status = gss_test_oid_set_member(&minor_status, mech, mech_set, &mech_found);
if (GSS_ERROR(major_status))
{
cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to match mechanism in set",
major_status, minor_status);
gss_release_oid_set(&minor_status, &mech_set);
return False;
}
if (!mech_found)
return False;
return True;
gss_release_oid_set(&minor_status, &mech_set);
return mech_found;
}
static RD_BOOL
cssp_gss_get_service_name(char *server, gss_name_t * name)
cssp_gss_get_service_name(const char *server, gss_name_t * name)
{
gss_buffer_desc output;
OM_uint32 major_status, minor_status;
@ -118,9 +113,14 @@ cssp_gss_get_service_name(char *server, gss_name_t * name)
const char service_name[] = "TERMSRV";
gss_OID type = (gss_OID) GSS_C_NT_HOSTBASED_SERVICE;
int size = (strlen(service_name) + 1 + strlen(server) + 1);
int size = snprintf(NULL, 0, "%s@%s", service_name, server) + 1;
output.value = malloc(size);
if (!output.value)
{
logger(Core, Error, "cssp_gss_get_service_name(), memory allocation failed");
return False;
}
snprintf(output.value, size, "%s@%s", service_name, server);
output.length = strlen(output.value) + 1;
@ -130,13 +130,12 @@ cssp_gss_get_service_name(char *server, gss_name_t * name)
{
cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to create service principal name",
major_status, minor_status);
free(output.value);
return False;
}
gss_release_buffer(&minor_status, &output);
return True;
}
static STREAM
@ -167,6 +166,7 @@ cssp_gss_wrap(gss_ctx_id_t ctx, STREAM in)
{
logger(Core, Error,
"cssp_gss_wrap(), GSS Confidentiality failed, no encryption of message performed.");
gss_release_buffer(&minor_status, &outbuf);
return NULL;
}
@ -177,7 +177,6 @@ cssp_gss_wrap(gss_ctx_id_t ctx, STREAM in)
s_seek(out, 0);
gss_release_buffer(&minor_status, &outbuf);
return out;
}
@ -211,66 +210,58 @@ cssp_gss_unwrap(gss_ctx_id_t ctx, STREAM in)
s_seek(out, 0);
gss_release_buffer(&minor_status, &outbuf);
return out;
}
static STREAM
cssp_encode_tspasswordcreds(char *username, char *password, char *domain)
cssp_encode_tspasswordcreds(const char *username, const char *password, const char *domain)
{
STREAM out, h1, h2;
struct stream tmp = { 0 };
struct stream message = { 0 };
memset(&tmp, 0, sizeof(tmp));
memset(&message, 0, sizeof(message));
s_realloc(&tmp, 512 * 4);
STREAM tmp = s_alloc(512 * 4);
STREAM message = s_alloc(0);
// domainName [0]
s_reset(&tmp);
out_utf16s(&tmp, domain);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, domain);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
// userName [1]
s_reset(&tmp);
out_utf16s(&tmp, username);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, username);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
// password [2]
s_reset(&tmp);
out_utf16s(&tmp, password);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, password);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
// build message
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, message);
// cleanup
xfree(tmp.data);
xfree(message.data);
s_free(tmp);
s_free(message);
return out;
}
@ -279,39 +270,37 @@ cssp_encode_tspasswordcreds(char *username, char *password, char *domain)
#define AT_SIGNATURE 2
static STREAM
cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, char *container,
char *csp)
cssp_encode_tscspdatadetail(unsigned char keyspec, const char *card, const char *reader, const char *container,
const char *csp)
{
STREAM out;
STREAM h1, h2;
struct stream tmp = { 0 };
struct stream message = { 0 };
s_realloc(&tmp, 512 * 4);
STREAM tmp = s_alloc(512 * 4);
STREAM message = s_alloc(0);
// keySpec [0]
s_reset(&tmp);
out_uint8(&tmp, keyspec);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
s_reset(tmp);
out_uint8(tmp, keyspec);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
// cardName [1]
if (card)
{
s_reset(&tmp);
out_utf16s(&tmp, card);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, card);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
@ -319,14 +308,14 @@ cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, cha
// readerName [2]
if (reader)
{
s_reset(&tmp);
out_utf16s(&tmp, reader);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, reader);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
@ -334,14 +323,14 @@ cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, cha
// containerName [3]
if (container)
{
s_reset(&tmp);
out_utf16s(&tmp, container);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, container);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
@ -349,47 +338,45 @@ cssp_encode_tscspdatadetail(unsigned char keyspec, char *card, char *reader, cha
// cspName [4]
if (csp)
{
s_reset(&tmp);
out_utf16s(&tmp, csp);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, csp);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 4, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
s_mark_end(&message);
s_mark_end(message);
// build message
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, message);
// cleanup
free(tmp.data);
free(message.data);
s_free(tmp);
s_free(message);
return out;
}
static STREAM
cssp_encode_tssmartcardcreds(char *username, char *password, char *domain)
cssp_encode_tssmartcardcreds(const char *username, const char *password, const char *domain)
{
STREAM out, h1, h2;
struct stream tmp = { 0 };
struct stream message = { 0 };
s_realloc(&tmp, 512 * 4);
STREAM tmp = s_alloc(512 * 4);
STREAM message = s_alloc(0);
// pin [0]
s_reset(&tmp);
out_utf16s(&tmp, password);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, password);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
@ -397,23 +384,23 @@ cssp_encode_tssmartcardcreds(char *username, char *password, char *domain)
h2 = cssp_encode_tscspdatadetail(AT_KEYEXCHANGE, g_sc_card_name, g_sc_reader_name,
g_sc_container_name, g_sc_csp_name);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
// userHint [2]
if (username && strlen(username))
{
s_reset(&tmp);
out_utf16s(&tmp, username);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, username);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
@ -421,55 +408,54 @@ cssp_encode_tssmartcardcreds(char *username, char *password, char *domain)
// domainHint [3]
if (domain && strlen(domain))
{
s_reset(&tmp);
out_utf16s(&tmp, domain);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, &tmp);
s_reset(tmp);
out_utf16s(tmp, domain);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
s_mark_end(&message);
s_mark_end(message);
// build message
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, message);
// cleanup
free(tmp.data);
free(message.data);
s_free(tmp);
s_free(message);
return out;
}
STREAM
cssp_encode_tscredentials(char *username, char *password, char *domain)
cssp_encode_tscredentials(const char *username, const char *password, const char *domain)
{
STREAM out;
STREAM h1, h2, h3;
struct stream tmp = { 0 };
struct stream message = { 0 };
STREAM tmp = s_alloc(sizeof(uint8));
STREAM message = s_alloc(0);
// credType [0]
s_realloc(&tmp, sizeof(uint8));
s_reset(&tmp);
s_reset(tmp);
if (g_use_password_as_pin == False)
{
out_uint8(&tmp, 1); // TSPasswordCreds
out_uint8(tmp, 1); // TSPasswordCreds
}
else
{
out_uint8(&tmp, 2); // TSSmartCardCreds
out_uint8(tmp, 2); // TSSmartCardCreds
}
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
@ -485,19 +471,19 @@ cssp_encode_tscredentials(char *username, char *password, char *domain)
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, h3);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h3);
s_free(h2);
s_free(h1);
// Construct ASN.1 message
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
out = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, message);
// cleanup
xfree(message.data);
xfree(tmp.data);
s_free(message);
s_free(tmp);
return out;
}
@ -508,22 +494,19 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
STREAM s;
STREAM h1, h2, h3, h4, h5;
struct stream tmp = { 0 };
struct stream message = { 0 };
memset(&message, 0, sizeof(message));
memset(&tmp, 0, sizeof(tmp));
STREAM tmp = s_alloc(0);
STREAM message = s_alloc(0);
// version [0]
s_realloc(&tmp, sizeof(uint8));
s_reset(&tmp);
out_uint8(&tmp, 2);
s_mark_end(&tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, &tmp);
s_realloc(tmp, sizeof(uint8));
s_reset(tmp);
out_uint8(tmp, 2);
s_mark_end(tmp);
h2 = ber_wrap_hdr_data(BER_TAG_INTEGER, tmp);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
@ -535,9 +518,9 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
h3 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h4);
h2 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, h3);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h5);
s_free(h4);
s_free(h3);
@ -551,8 +534,8 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, auth);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 2, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_free(h2);
s_free(h1);
@ -564,17 +547,16 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
h2 = ber_wrap_hdr_data(BER_TAG_OCTET_STRING, pubkey);
h1 = ber_wrap_hdr_data(BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3, h2);
s_realloc(&message, s_length(&message) + s_length(h1));
out_stream(&message, h1);
s_mark_end(&message);
s_realloc(message, s_length(message) + s_length(h1));
out_stream(message, h1);
s_mark_end(message);
s_free(h2);
s_free(h1);
}
s_mark_end(&message);
s_mark_end(message);
// Construct ASN.1 Message
// Todo: can h1 be send directly instead of tcp_init() approach
h1 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, &message);
h1 = ber_wrap_hdr_data(BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED, message);
s = tcp_init(s_length(h1));
out_stream(s, h1);
s_mark_end(s);
@ -584,20 +566,19 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
s_free(s);
// cleanup
xfree(message.data);
xfree(tmp.data);
s_free(message);
s_free(tmp);
return True;
}
STREAM
cssp_read_tsrequest(RD_BOOL pubkey)
{
STREAM s, out;
int length;
int tagval;
struct stream packet;
STREAM packet;
s = tcp_recv(NULL, 4);
@ -677,12 +658,11 @@ cssp_read_tsrequest(RD_BOOL pubkey)
s_seek(out, 0);
}
return out;
}
RD_BOOL
cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
cssp_connect(const char *server, const char *user, const char *domain, const char *password, STREAM s)
{
UNUSED(s);
OM_uint32 actual_time;