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,212 +20,155 @@
*/
#include "rdesktop.h"
#include <string.h>
#define MAX_CHANNELS 6
#define CHANNEL_CHUNK_LENGTH 1600
#define CHANNEL_FLAG_FIRST 0x01
#define CHANNEL_FLAG_LAST 0x02
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
#define MAX_CHANNELS 6
#define CHANNEL_CHUNK_LENGTH 1600
#define CHANNEL_FLAG_FIRST 0x01
#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.
VCHANNEL *channel_register(const char *name, uint32_t flags, void (*callback) (STREAM)) {
if (g_rdp_version < RDP_V5) {
return NULL;
}
The format of TAG_SRV_CHANNELS seems to be
if (g_num_channels >= MAX_CHANNELS) {
logger(Core, Error, "channel_register(), channel table full, increase MAX_CHANNELS");
return NULL;
}
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");
return NULL;
}
channel = &g_channels[g_num_channels];
channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
strncpy(channel->name, name, 8);
channel->flags = flags;
channel->process = callback;
g_num_channels++;
return channel;
VCHANNEL *channel = &g_channels[g_num_channels];
channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
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)
{
UNUSED(channel);
STREAM s;
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
s_push_layer(s, channel_hdr, 8);
return s;
STREAM channel_init(VCHANNEL *channel, uint32_t length) {
UNUSED(channel);
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;
RD_BOOL inplace;
STREAM chunk;
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. */
thislength = MIN(s_remaining(s), vc_chunk_size);
/* 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) */
flags = 0;
if (length == s_remaining(s)) {
flags |= CHANNEL_FLAG_FIRST;
}
if (s_remaining(s) == thislength) {
flags |= CHANNEL_FLAG_LAST;
}
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) {
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
thislength = MIN(s_remaining(s), vc_chunk_size);
logger(Protocol, Debug, "channel_send_chunk(), sending %d bytes with flags 0x%x",
thislength, flags);
flags = 0;
if (length == s_remaining(s))
{
flags |= CHANNEL_FLAG_FIRST;
}
if (s_remaining(s) == thislength)
{
flags |= CHANNEL_FLAG_LAST;
}
if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
{
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
inplace = (flags & (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST)) == (CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST);
logger(Protocol, Debug, "channel_send_chunk(), sending %d bytes with flags 0x%x",
thislength, flags);
if (inplace) {
s_pop_layer(s, channel_hdr);
chunk = s;
} else {
chunk = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
}
/* first fragment sent in-place */
inplace = False;
if ((flags & (CHANNEL_FLAG_FIRST|CHANNEL_FLAG_LAST)) ==
(CHANNEL_FLAG_FIRST|CHANNEL_FLAG_LAST))
{
inplace = True;
}
out_uint32_le(chunk, length);
out_uint32_le(chunk, flags);
if (!inplace) {
out_uint8stream(chunk, s, thislength);
s_mark_end(chunk);
}
sec_send_to_channel(chunk, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
if (inplace)
{
s_pop_layer(s, channel_hdr);
chunk = s;
}
else
{
chunk = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
}
out_uint32_le(chunk, length);
out_uint32_le(chunk, flags);
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)
{
in_uint8s(s, s_remaining(s));
}
if (!inplace)
{
s_free(chunk);
}
if (inplace) {
in_uint8s(s, s_remaining(s));
} 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);
scard_lock(SCARD_LOCK_CHANNEL);
#endif
s_pop_layer(s, channel_hdr);
in_uint8s(s, 8);
length = s_remaining(s);
s_pop_layer(s, channel_hdr);
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))
{
channel_send_chunk(s, channel, length);
}
while (!s_check_end(s)) {
channel_send_chunk(s, channel, length);
}
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_CHANNEL);
scard_unlock(SCARD_LOCK_CHANNEL);
#endif
}
void
channel_process(STREAM s, uint16 mcs_channel)
{
uint32 length, flags;
uint32 thislength;
VCHANNEL *channel = NULL;
unsigned int i;
STREAM in;
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++)
{
channel = &g_channels[i];
if (channel->mcs_id == mcs_channel)
break;
}
for (i = 0; i < g_num_channels; i++) {
channel = &g_channels[i];
if (channel->mcs_id == mcs_channel) {
break;
}
}
if (i >= g_num_channels)
return;
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 */
channel->process(s);
}
else
{
/* add fragment to defragmentation buffer */
in = &channel->in;
if (flags & CHANNEL_FLAG_FIRST)
{
s_realloc(in, length);
s_reset(in);
}
in_uint32_le(s, length);
in_uint32_le(s, flags);
if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST)) {
channel->process(s);
} else {
in = &channel->in;
if (flags & CHANNEL_FLAG_FIRST) {
s_realloc(in, length);
s_reset(in);
}
thislength = s_remaining(s);
out_uint8stream(in, s, thislength);
thislength = s_remaining(s);
out_uint8stream(in, s, thislength);
if (flags & CHANNEL_FLAG_LAST)
{
s_mark_end(in);
s_seek(in, 0);
channel->process(in);
}
}
if (flags & CHANNEL_FLAG_LAST) {
s_mark_end(in);
s_seek(in, 0);
channel->process(in);
}
}
}

232
cliprdr.c
View File

@ -20,39 +20,41 @@
*/
#include "rdesktop.h"
#include <string.h>
#define CLIPRDR_CONNECT 1
#define CLIPRDR_FORMAT_ANNOUNCE 2
#define CLIPRDR_FORMAT_ACK 3
#define CLIPRDR_DATA_REQUEST 4
#define CLIPRDR_DATA_RESPONSE 5
#define CLIPRDR_CONNECT 1
#define CLIPRDR_FORMAT_ANNOUNCE 2
#define CLIPRDR_FORMAT_ACK 3
#define CLIPRDR_DATA_REQUEST 4
#define CLIPRDR_DATA_RESPONSE 5
#define CLIPRDR_REQUEST 0
#define CLIPRDR_RESPONSE 1
#define CLIPRDR_ERROR 2
#define CLIPRDR_REQUEST 0
#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)
{
STREAM s;
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);
out_uint8a(s, data, length);
out_uint32(s, 0); /* pad? */
s_mark_end(s);
channel_send(s, cliprdr_channel);
s_free(s);
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);
s_free(s);
}
/* Helper which announces our readiness to supply clipboard data
@ -60,135 +62,109 @@ 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));
buf_out_uint32(buffer, format);
cliprdr_send_native_format_announce(buffer, sizeof(buffer));
}
/* Announces our readiness to supply clipboard data in multiple
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)
{
logger(Clipboard, Debug, "cliprdr_send_native_format_announce()");
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)
xfree(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);
last_formats_length = formats_data_length;
}
last_formats = xmalloc(formats_data_length);
memcpy(last_formats, formats_data, formats_data_length);
last_formats_length = formats_data_length;
}
}
void
cliprdr_send_data_request(uint32 format)
{
uint8 buffer[4];
void cliprdr_send_data_request(uint32 format) {
uint8 buffer[4];
logger(Clipboard, Debug, "cliprdr_send_data_request(), format 0x%x", format);
buf_out_uint32(buffer, format);
cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
logger(Clipboard, Debug, "cliprdr_send_data_request(), format 0x%x", format);
buf_out_uint32(buffer, format);
cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
}
void
cliprdr_send_data(uint8 * data, uint32 length)
{
logger(Clipboard, Debug, "cliprdr_send_data(), length %d bytes", length);
cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, 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)
{
uint16 type, status;
uint32 length, format;
uint8 *data;
static void cliprdr_process(STREAM s) {
uint16 type, status;
uint32 length, format;
const uint8 *data;
in_uint16_le(s, type);
in_uint16_le(s, status);
in_uint32_le(s, length);
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)
{
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);
break;
case CLIPRDR_DATA_RESPONSE:
ui_clip_request_failed();
break;
default:
logger(Clipboard, Warning,
"cliprdr_process(), unhandled error (type=%d)", 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);
break;
case CLIPRDR_DATA_RESPONSE:
ui_clip_request_failed();
break;
default:
logger(Clipboard, Warning, "cliprdr_process(), unhandled error (type=%d)", type);
}
return;
}
return;
}
switch (type)
{
case CLIPRDR_CONNECT:
ui_clip_sync();
break;
case CLIPRDR_FORMAT_ANNOUNCE:
in_uint8p(s, data, length);
ui_clip_format_announce(data, length);
cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
return;
case CLIPRDR_FORMAT_ACK:
break;
case CLIPRDR_DATA_REQUEST:
in_uint32_le(s, format);
ui_clip_request_data(format);
break;
case CLIPRDR_DATA_RESPONSE:
in_uint8p(s, data, length);
ui_clip_handle_data(data, length);
break;
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);
}
switch (type) {
case CLIPRDR_CONNECT:
ui_clip_sync();
break;
case CLIPRDR_FORMAT_ANNOUNCE:
in_uint8p(s, data, length);
ui_clip_format_announce(data, length);
cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
return;
case CLIPRDR_FORMAT_ACK:
break;
case CLIPRDR_DATA_REQUEST:
in_uint32_le(s, format);
ui_clip_request_data(format);
break;
case CLIPRDR_DATA_RESPONSE:
in_uint8p(s, data, length);
ui_clip_handle_data(data, length);
break;
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);
}
}
void
cliprdr_set_mode(const char *optarg)
{
ui_clip_set_mode(optarg);
void cliprdr_set_mode(const char *optarg) {
ui_clip_set_mode(optarg);
}
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);
return (cliprdr_channel != NULL);
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);
return (cliprdr_channel != NULL);
}

File diff suppressed because it is too large Load Diff

344
cssp.c
View File

@ -27,7 +27,7 @@ extern char *g_sc_reader_name;
extern char *g_sc_card_name;
extern char *g_sc_container_name;
static gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc =
static gss_OID_desc _gss_spnego_krb5_mechanism_oid_desc =
{ 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
static STREAM
@ -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;
@ -889,7 +869,7 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
return True;
bail_out:
bail_out:
s_free(token);
s_free(pubkey);
s_free(pubkey_cmp);