Return STREAM objects from data generating functions
Use a consistent style of returning a new STREAM object from functions that output data, rather than requiring an existing structure to be passed in. This generally makes the memory management more straight forward and allows us to do more proper bounds checking of everything. This also adds some new STREAM macros to make it easier to manage them without poking around in the internal structure.
This commit is contained in:
parent
655c3d56df
commit
489c43f382
179
cssp.c
179
cssp.c
@ -139,13 +139,14 @@ cssp_gss_get_service_name(char *server, gss_name_t * name)
|
||||
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
cssp_gss_wrap(gss_ctx_id_t ctx, STREAM in, STREAM out)
|
||||
static STREAM
|
||||
cssp_gss_wrap(gss_ctx_id_t ctx, STREAM in)
|
||||
{
|
||||
int conf_state;
|
||||
OM_uint32 major_status;
|
||||
OM_uint32 minor_status;
|
||||
gss_buffer_desc inbuf, outbuf;
|
||||
STREAM out;
|
||||
|
||||
inbuf.value = in->data;
|
||||
inbuf.length = s_length(in);
|
||||
@ -157,35 +158,36 @@ cssp_gss_wrap(gss_ctx_id_t ctx, STREAM in, STREAM out)
|
||||
{
|
||||
cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to encrypt and sign message",
|
||||
major_status, minor_status);
|
||||
return False;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!conf_state)
|
||||
{
|
||||
logger(Core, Error,
|
||||
"cssp_gss_wrap(), GSS Confidentiality failed, no encryption of message performed.");
|
||||
return False;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// write enc data to out stream
|
||||
out->data = out->p = xmalloc(outbuf.length);
|
||||
out->size = outbuf.length;
|
||||
out = s_alloc(outbuf.length);
|
||||
out_uint8a(out, outbuf.value, outbuf.length);
|
||||
s_mark_end(out);
|
||||
s_seek(out, 0);
|
||||
|
||||
gss_release_buffer(&minor_status, &outbuf);
|
||||
|
||||
return True;
|
||||
return out;
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
cssp_gss_unwrap(gss_ctx_id_t ctx, STREAM in, STREAM out)
|
||||
static STREAM
|
||||
cssp_gss_unwrap(gss_ctx_id_t ctx, STREAM in)
|
||||
{
|
||||
OM_uint32 major_status;
|
||||
OM_uint32 minor_status;
|
||||
gss_qop_t qop_state;
|
||||
gss_buffer_desc inbuf, outbuf;
|
||||
int conf_state;
|
||||
STREAM out;
|
||||
|
||||
inbuf.value = in->data;
|
||||
inbuf.length = s_length(in);
|
||||
@ -196,17 +198,17 @@ cssp_gss_unwrap(gss_ctx_id_t ctx, STREAM in, STREAM out)
|
||||
{
|
||||
cssp_gss_report_error(GSS_C_GSS_CODE, "Failed to decrypt message",
|
||||
major_status, minor_status);
|
||||
return False;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->data = out->p = xmalloc(outbuf.length);
|
||||
out->size = outbuf.length;
|
||||
out = s_alloc(outbuf.length);
|
||||
out_uint8a(out, outbuf.value, outbuf.length);
|
||||
s_mark_end(out);
|
||||
s_seek(out, 0);
|
||||
|
||||
gss_release_buffer(&minor_status, &outbuf);
|
||||
|
||||
return True;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@ -585,10 +587,10 @@ cssp_send_tsrequest(STREAM token, STREAM auth, STREAM pubkey)
|
||||
}
|
||||
|
||||
|
||||
RD_BOOL
|
||||
cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
STREAM
|
||||
cssp_read_tsrequest(RD_BOOL pubkey)
|
||||
{
|
||||
STREAM s;
|
||||
STREAM s, out;
|
||||
int length;
|
||||
int tagval;
|
||||
struct stream packet;
|
||||
@ -596,7 +598,7 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
s = tcp_recv(NULL, 4);
|
||||
|
||||
if (s == NULL)
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
// verify ASN.1 header
|
||||
if (s->p[0] != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
|
||||
@ -604,7 +606,7 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
logger(Protocol, Error,
|
||||
"cssp_read_tsrequest(), expected BER_TAG_SEQUENCE|BER_TAG_CONSTRUCTED, got %x",
|
||||
s->p[0]);
|
||||
return False;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// peek at first 4 bytes to get full message length
|
||||
@ -615,7 +617,7 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
else if (s->p[1] == 0x82)
|
||||
length = (s->p[2] << 8) | s->p[3];
|
||||
else
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
// receive the remainings of message
|
||||
s = tcp_recv(s, length);
|
||||
@ -624,12 +626,12 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
// parse the response and into nego token
|
||||
if (!ber_in_header(s, &tagval, &length) ||
|
||||
tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
// version [0]
|
||||
if (!ber_in_header(s, &tagval, &length) ||
|
||||
tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0))
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
if (!s_check_rem(s, length))
|
||||
{
|
||||
@ -639,23 +641,23 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
in_uint8s(s, length);
|
||||
|
||||
// negoToken [1]
|
||||
if (token)
|
||||
if (!pubkey)
|
||||
{
|
||||
if (!ber_in_header(s, &tagval, &length)
|
||||
|| tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 1))
|
||||
return False;
|
||||
return NULL;
|
||||
if (!ber_in_header(s, &tagval, &length)
|
||||
|| tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
|
||||
return False;
|
||||
return NULL;
|
||||
if (!ber_in_header(s, &tagval, &length)
|
||||
|| tagval != (BER_TAG_SEQUENCE | BER_TAG_CONSTRUCTED))
|
||||
return False;
|
||||
return NULL;
|
||||
if (!ber_in_header(s, &tagval, &length)
|
||||
|| tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 0))
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
if (!ber_in_header(s, &tagval, &length) || tagval != BER_TAG_OCTET_STRING)
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
if (!s_check_rem(s, length))
|
||||
{
|
||||
@ -663,29 +665,29 @@ cssp_read_tsrequest(STREAM token, STREAM pubkey)
|
||||
&packet);
|
||||
}
|
||||
|
||||
s_realloc(token, length);
|
||||
s_reset(token);
|
||||
out_uint8a(token, s->p, length);
|
||||
s_mark_end(token);
|
||||
out = s_alloc(length);
|
||||
out_uint8a(out, s->p, length);
|
||||
s_mark_end(out);
|
||||
s_seek(out, 0);
|
||||
}
|
||||
|
||||
// pubKey [3]
|
||||
if (pubkey)
|
||||
else
|
||||
{
|
||||
if (!ber_in_header(s, &tagval, &length)
|
||||
|| tagval != (BER_TAG_CTXT_SPECIFIC | BER_TAG_CONSTRUCTED | 3))
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
if (!ber_in_header(s, &tagval, &length) || tagval != BER_TAG_OCTET_STRING)
|
||||
return False;
|
||||
return NULL;
|
||||
|
||||
pubkey->data = pubkey->p = s->p;
|
||||
pubkey->end = pubkey->data + length;
|
||||
pubkey->size = length;
|
||||
out = s_alloc(length);
|
||||
out_uint8a(out, s->p, length);
|
||||
s_mark_end(out);
|
||||
s_seek(out, 0);
|
||||
}
|
||||
|
||||
|
||||
return True;
|
||||
return out;
|
||||
}
|
||||
|
||||
RD_BOOL
|
||||
@ -702,9 +704,14 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
|
||||
gss_OID desired_mech = &_gss_spnego_krb5_mechanism_oid_desc;
|
||||
|
||||
STREAM ts_creds;
|
||||
struct stream token = { 0 };
|
||||
struct stream pubkey = { 0 };
|
||||
struct stream pubkey_cmp = { 0 };
|
||||
STREAM token;
|
||||
STREAM pubkey, pubkey_cmp;
|
||||
unsigned char *pubkey_data;
|
||||
unsigned char *pubkey_cmp_data;
|
||||
unsigned char first_byte;
|
||||
|
||||
RD_BOOL ret;
|
||||
STREAM blob;
|
||||
|
||||
// Verify that system gss support spnego
|
||||
if (!cssp_gss_mech_available(desired_mech))
|
||||
@ -728,16 +735,19 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
|
||||
return False;
|
||||
}
|
||||
|
||||
tcp_tls_get_server_pubkey(&pubkey);
|
||||
pubkey = tcp_tls_get_server_pubkey();
|
||||
if (pubkey == NULL)
|
||||
return False;
|
||||
pubkey_cmp = NULL;
|
||||
|
||||
// Enter the spnego loop
|
||||
OM_uint32 actual_services;
|
||||
gss_OID actual_mech;
|
||||
struct stream blob = { 0 };
|
||||
|
||||
gss_ctx = GSS_C_NO_CONTEXT;
|
||||
cred = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
token = NULL;
|
||||
input_tok.length = 0;
|
||||
output_tok.length = 0;
|
||||
minor_status = 0;
|
||||
@ -758,6 +768,11 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
|
||||
&actual_mech,
|
||||
&output_tok, &actual_services, &actual_time);
|
||||
|
||||
// input_tok might have pointed to token's data,
|
||||
// but it's safe to free it now after the call
|
||||
s_free(token);
|
||||
token = NULL;
|
||||
|
||||
if (GSS_ERROR(major_status))
|
||||
{
|
||||
if (i == 0)
|
||||
@ -782,39 +797,44 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
|
||||
// Send token to server
|
||||
if (output_tok.length != 0)
|
||||
{
|
||||
if (output_tok.length > token.size)
|
||||
s_realloc(&token, output_tok.length);
|
||||
s_reset(&token);
|
||||
token = s_alloc(output_tok.length);
|
||||
out_uint8a(token, output_tok.value, output_tok.length);
|
||||
s_mark_end(token);
|
||||
|
||||
out_uint8a(&token, output_tok.value, output_tok.length);
|
||||
s_mark_end(&token);
|
||||
|
||||
if (!cssp_send_tsrequest(&token, NULL, NULL))
|
||||
goto bail_out;
|
||||
ret = cssp_send_tsrequest(token, NULL, NULL);
|
||||
|
||||
s_free(token);
|
||||
token = NULL;
|
||||
(void) gss_release_buffer(&minor_status, &output_tok);
|
||||
|
||||
if (!ret)
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
// Read token from server
|
||||
if (major_status & GSS_S_CONTINUE_NEEDED)
|
||||
{
|
||||
(void) gss_release_buffer(&minor_status, &input_tok);
|
||||
|
||||
if (!cssp_read_tsrequest(&token, NULL))
|
||||
token = cssp_read_tsrequest(False);
|
||||
if (token == NULL)
|
||||
goto bail_out;
|
||||
|
||||
input_tok.value = token.data;
|
||||
input_tok.length = s_length(&token);
|
||||
input_tok.length = s_length(token);
|
||||
in_uint8p(token, input_tok.value, input_tok.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send encrypted pubkey for verification to server
|
||||
context_established = 1;
|
||||
|
||||
if (!cssp_gss_wrap(gss_ctx, &pubkey, &blob))
|
||||
blob = cssp_gss_wrap(gss_ctx, pubkey);
|
||||
if (blob == NULL)
|
||||
goto bail_out;
|
||||
|
||||
if (!cssp_send_tsrequest(NULL, NULL, &blob))
|
||||
ret = cssp_send_tsrequest(NULL, NULL, blob);
|
||||
|
||||
s_free(blob);
|
||||
|
||||
if (!ret)
|
||||
goto bail_out;
|
||||
|
||||
context_established = 1;
|
||||
@ -825,37 +845,62 @@ cssp_connect(char *server, char *user, char *domain, char *password, STREAM s)
|
||||
}
|
||||
while (!context_established);
|
||||
|
||||
s_free(token);
|
||||
|
||||
// read tsrequest response and decrypt for public key validation
|
||||
if (!cssp_read_tsrequest(NULL, &blob))
|
||||
blob = cssp_read_tsrequest(True);
|
||||
if (blob == NULL)
|
||||
goto bail_out;
|
||||
|
||||
if (!cssp_gss_unwrap(gss_ctx, &blob, &pubkey_cmp))
|
||||
pubkey_cmp = cssp_gss_unwrap(gss_ctx, blob);
|
||||
s_free(blob);
|
||||
if (pubkey_cmp == NULL)
|
||||
goto bail_out;
|
||||
|
||||
pubkey_cmp.data[0] -= 1;
|
||||
// the first byte gets 1 added before being sent by the server
|
||||
// in order to protect against replays of the data sent earlier
|
||||
// by the client
|
||||
in_uint8(pubkey_cmp, first_byte);
|
||||
s_seek(pubkey_cmp, 0);
|
||||
out_uint8(pubkey_cmp, first_byte - 1);
|
||||
s_seek(pubkey_cmp, 0);
|
||||
|
||||
// validate public key
|
||||
if (memcmp(pubkey.data, pubkey_cmp.data, s_length(&pubkey)) != 0)
|
||||
in_uint8p(pubkey, pubkey_data, s_length(pubkey));
|
||||
in_uint8p(pubkey_cmp, pubkey_cmp_data, s_length(pubkey_cmp));
|
||||
if ((s_length(pubkey) != s_length(pubkey_cmp)) ||
|
||||
(memcmp(pubkey_data, pubkey_cmp_data, s_length(pubkey)) != 0))
|
||||
{
|
||||
logger(Core, Error,
|
||||
"cssp_connect(), public key mismatch, cannot guarantee integrity of server connection");
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
s_free(pubkey);
|
||||
s_free(pubkey_cmp);
|
||||
|
||||
// Send TSCredentials
|
||||
ts_creds = cssp_encode_tscredentials(user, password, domain);
|
||||
|
||||
if (!cssp_gss_wrap(gss_ctx, ts_creds, &blob))
|
||||
goto bail_out;
|
||||
blob = cssp_gss_wrap(gss_ctx, ts_creds);
|
||||
|
||||
s_free(ts_creds);
|
||||
|
||||
if (!cssp_send_tsrequest(NULL, &blob, NULL))
|
||||
if (blob == NULL)
|
||||
goto bail_out;
|
||||
|
||||
ret = cssp_send_tsrequest(NULL, blob, NULL);
|
||||
|
||||
s_free(blob);
|
||||
|
||||
if (!ret)
|
||||
goto bail_out;
|
||||
|
||||
return True;
|
||||
|
||||
bail_out:
|
||||
xfree(token.data);
|
||||
s_free(token);
|
||||
s_free(pubkey);
|
||||
s_free(pubkey_cmp);
|
||||
return False;
|
||||
}
|
||||
|
2
proto.h
2
proto.h
@ -227,7 +227,7 @@ char *tcp_get_address(void);
|
||||
RD_BOOL tcp_is_connected(void);
|
||||
void tcp_reset_state(void);
|
||||
RD_BOOL tcp_tls_connect(void);
|
||||
RD_BOOL tcp_tls_get_server_pubkey(STREAM s);
|
||||
STREAM tcp_tls_get_server_pubkey();
|
||||
void tcp_run_ui(RD_BOOL run);
|
||||
|
||||
/* asn.c */
|
||||
|
6
rdpsnd.c
6
rdpsnd.c
@ -641,7 +641,7 @@ rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
|
||||
|
||||
queue_hi = next_hi;
|
||||
|
||||
packet->s = *s;
|
||||
packet->s = s;
|
||||
packet->tick = tick;
|
||||
packet->index = index;
|
||||
|
||||
@ -675,7 +675,7 @@ rdpsnd_queue_clear(void)
|
||||
while (queue_pending != queue_hi)
|
||||
{
|
||||
packet = &packet_queue[queue_pending];
|
||||
xfree(packet->s.data);
|
||||
s_free(packet->s);
|
||||
queue_pending = (queue_pending + 1) % MAX_QUEUE;
|
||||
}
|
||||
|
||||
@ -740,7 +740,7 @@ rdpsnd_queue_complete_pending(void)
|
||||
(packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
|
||||
elapsed /= 1000;
|
||||
|
||||
xfree(packet->s.data);
|
||||
s_free(packet->s);
|
||||
rdpsnd_send_waveconfirm((packet->tick + elapsed) % 65536, packet->index);
|
||||
queue_pending = (queue_pending + 1) % MAX_QUEUE;
|
||||
}
|
||||
|
2
rdpsnd.h
2
rdpsnd.h
@ -19,7 +19,7 @@
|
||||
|
||||
struct audio_packet
|
||||
{
|
||||
struct stream s;
|
||||
STREAM s;
|
||||
uint16 tick;
|
||||
uint8 index;
|
||||
|
||||
|
@ -376,7 +376,7 @@ alsa_play(void)
|
||||
return;
|
||||
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = &packet->s;
|
||||
out = packet->s;
|
||||
|
||||
next_tick = rdpsnd_queue_next_tick();
|
||||
|
||||
|
52
rdpsnd_dsp.c
52
rdpsnd_dsp.c
@ -175,8 +175,8 @@ rdpsnd_dsp_resample_supported(RD_WAVEFORMATEX * format)
|
||||
return True;
|
||||
}
|
||||
|
||||
uint32
|
||||
rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
STREAM
|
||||
rdpsnd_dsp_resample(unsigned char *in, unsigned int size,
|
||||
RD_WAVEFORMATEX * format, RD_BOOL stream_be)
|
||||
{
|
||||
UNUSED(stream_be);
|
||||
@ -190,13 +190,15 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
int innum, outnum;
|
||||
unsigned char *tmpdata = NULL, *tmp = NULL;
|
||||
int samplewidth = format->wBitsPerSample / 8;
|
||||
STREAM out;
|
||||
int outsize = 0;
|
||||
unsigned char *data;
|
||||
int i;
|
||||
|
||||
if ((resample_to_bitspersample == format->wBitsPerSample) &&
|
||||
(resample_to_channels == format->nChannels) &&
|
||||
(resample_to_srate == format->nSamplesPerSec))
|
||||
return 0;
|
||||
return NULL;
|
||||
|
||||
#ifdef B_ENDIAN
|
||||
if (!stream_be)
|
||||
@ -260,7 +262,7 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
{
|
||||
logger(Sound, Warning,
|
||||
"rdpsndp_dsp_resample_set(), no sample rate converter available");
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
outnum = ((float) innum * ((float) resample_to_srate / (float) format->nSamplesPerSec)) + 1;
|
||||
@ -285,8 +287,9 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
xfree(infloat);
|
||||
|
||||
outsize = resample_data.output_frames_gen * resample_to_channels * samplewidth;
|
||||
*out = (unsigned char *) xmalloc(outsize);
|
||||
src_float_to_short_array(outfloat, (short *) *out,
|
||||
out = s_alloc(outsize);
|
||||
out_uint8p(out, data, outsize);
|
||||
src_float_to_short_array(outfloat, (short *) data,
|
||||
resample_data.output_frames_gen * resample_to_channels);
|
||||
xfree(outfloat);
|
||||
|
||||
@ -302,8 +305,9 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
outnum = (innum * ratio1k) / 1000;
|
||||
|
||||
outsize = outnum * samplewidth;
|
||||
*out = (unsigned char *) xmalloc(outsize);
|
||||
bzero(*out, outsize);
|
||||
out = s_alloc(outsize);
|
||||
out_uint8p(out, data, outsize);
|
||||
bzero(data, outsize);
|
||||
|
||||
for (i = 0; i < outsize / (resample_to_channels * samplewidth); i++)
|
||||
{
|
||||
@ -331,7 +335,7 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
|
||||
cval1 += (sint8) (cval2 * part) / 100;
|
||||
|
||||
memcpy(*out + (i * resample_to_channels * samplewidth) +
|
||||
memcpy(data + (i * resample_to_channels * samplewidth) +
|
||||
(samplewidth * j), &cval1, samplewidth);
|
||||
}
|
||||
}
|
||||
@ -349,14 +353,14 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
|
||||
sval1 += (sint16) (sval2 * part) / 100;
|
||||
|
||||
memcpy(*out + (i * resample_to_channels * samplewidth) +
|
||||
memcpy(data + (i * resample_to_channels * samplewidth) +
|
||||
(samplewidth * j), &sval1, samplewidth);
|
||||
}
|
||||
}
|
||||
#else /* Nearest neighbor search */
|
||||
for (j = 0; j < resample_to_channels; j++)
|
||||
{
|
||||
memcpy(*out + (i * resample_to_channels * samplewidth) + (samplewidth * j),
|
||||
memcpy(out + (i * resample_to_channels * samplewidth) + (samplewidth * j),
|
||||
in + (source * resample_to_channels * samplewidth) +
|
||||
(samplewidth * j), samplewidth);
|
||||
}
|
||||
@ -378,7 +382,7 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
{
|
||||
for (i = 0; i < outsize; i++)
|
||||
{
|
||||
*out[i] = *out[i * 2];
|
||||
data[i] = data[i * 2];
|
||||
}
|
||||
outsize /= 2;
|
||||
}
|
||||
@ -386,16 +390,17 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
||||
|
||||
#ifdef B_ENDIAN
|
||||
if (!stream_be)
|
||||
rdpsnd_dsp_swapbytes(*out, outsize, format);
|
||||
rdpsnd_dsp_swapbytes(data, outsize, format);
|
||||
#endif
|
||||
return outsize;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
STREAM
|
||||
rdpsnd_dsp_process(unsigned char *data, unsigned int size, struct audio_driver * current_driver,
|
||||
RD_WAVEFORMATEX * format)
|
||||
{
|
||||
static struct stream out;
|
||||
STREAM out;
|
||||
RD_BOOL stream_be = False;
|
||||
|
||||
/* softvol and byteswap do not change the amount of data they
|
||||
@ -411,20 +416,19 @@ rdpsnd_dsp_process(unsigned char *data, unsigned int size, struct audio_driver *
|
||||
}
|
||||
#endif
|
||||
|
||||
out.data = NULL;
|
||||
out = NULL;
|
||||
|
||||
if (current_driver->need_resampling)
|
||||
out.size = rdpsnd_dsp_resample(&out.data, data, size, format, stream_be);
|
||||
out = rdpsnd_dsp_resample(data, size, format, stream_be);
|
||||
|
||||
if (out.data == NULL)
|
||||
if (out == NULL)
|
||||
{
|
||||
out.data = (unsigned char *) xmalloc(size);
|
||||
memcpy(out.data, data, size);
|
||||
out.size = size;
|
||||
out = s_alloc(size);
|
||||
out_uint8a(out, data, size);
|
||||
}
|
||||
|
||||
out.p = out.data;
|
||||
out.end = out.p + out.size;
|
||||
s_mark_end(out);
|
||||
s_seek(out, 0);
|
||||
|
||||
return &out;
|
||||
return out;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ libao_play(void)
|
||||
return;
|
||||
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = &packet->s;
|
||||
out = packet->s;
|
||||
|
||||
next_tick = rdpsnd_queue_next_tick();
|
||||
|
||||
|
@ -410,7 +410,7 @@ oss_play(void)
|
||||
return;
|
||||
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = &packet->s;
|
||||
out = packet->s;
|
||||
|
||||
len = s_remaining(out);
|
||||
|
||||
|
@ -1154,7 +1154,7 @@ pulse_play(void)
|
||||
do
|
||||
{
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = &packet->s;
|
||||
out = packet->s;
|
||||
|
||||
ti = pa_stream_get_timing_info(playback_stream);
|
||||
if (ti == NULL)
|
||||
|
@ -254,7 +254,7 @@ sgi_play(void)
|
||||
return;
|
||||
|
||||
packet = rdpsnd_queue_current_packet();
|
||||
out = (STREAM) (void *) &(packet->s);
|
||||
out = packet->s;
|
||||
|
||||
len = s_remaining(out);
|
||||
|
||||
|
15
stream.c
15
stream.c
@ -37,6 +37,19 @@ s_alloc(unsigned int size)
|
||||
return s;
|
||||
}
|
||||
|
||||
STREAM
|
||||
s_inherit(unsigned char *data, unsigned int size)
|
||||
{
|
||||
STREAM s;
|
||||
|
||||
s = xmalloc(sizeof(struct stream));
|
||||
memset(s, 0, sizeof(struct stream));
|
||||
s->p = s->data = data;
|
||||
s->size = size;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
s_realloc(STREAM s, unsigned int size)
|
||||
{
|
||||
@ -71,6 +84,8 @@ s_reset(STREAM s)
|
||||
void
|
||||
s_free(STREAM s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return;
|
||||
free(s->data);
|
||||
free(s);
|
||||
}
|
||||
|
6
stream.h
6
stream.h
@ -43,6 +43,8 @@ typedef struct stream
|
||||
|
||||
/* Return a newly allocated STREAM object of the specified size */
|
||||
STREAM s_alloc(unsigned int size);
|
||||
/* Wrap an existing buffer in a STREAM object, transferring ownership */
|
||||
STREAM s_inherit(unsigned char *data, unsigned int size);
|
||||
/* Resize an existing STREAM object, keeping all data and offsets intact */
|
||||
void s_realloc(STREAM s, unsigned int size);
|
||||
/* Free STREAM object and its associated buffer */
|
||||
@ -60,6 +62,10 @@ size_t in_ansi_string(STREAM s, char *string, size_t len);
|
||||
#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
|
||||
#define s_pop_layer(s,h) (s)->p = (s)->h;
|
||||
#define s_mark_end(s) (s)->end = (s)->p;
|
||||
/* Return current read offset in the STREAM */
|
||||
#define s_tell(s) (size_t)((s)->p - (s)->data)
|
||||
/* Set current read offset in the STREAM */
|
||||
#define s_seek(s,o) (s)->p = (s)->data; s_assert_r(s,o); (s)->p += o;
|
||||
/* Returns number of bytes that can still be read from STREAM */
|
||||
#define s_remaining(s) (size_t)((s)->end - (s)->p)
|
||||
#define s_check_rem(s,n) (((s)->p <= (s)->end) && ((size_t)n <= s_remaining(s)))
|
||||
|
18
tcp.c
18
tcp.c
@ -399,8 +399,8 @@ fail:
|
||||
}
|
||||
|
||||
/* Get public key from server of TLS 1.x connection */
|
||||
RD_BOOL
|
||||
tcp_tls_get_server_pubkey(STREAM s)
|
||||
STREAM
|
||||
tcp_tls_get_server_pubkey()
|
||||
{
|
||||
int ret;
|
||||
unsigned int list_size;
|
||||
@ -413,8 +413,7 @@ tcp_tls_get_server_pubkey(STREAM s)
|
||||
int pk_size;
|
||||
uint8_t pk_data[1024];
|
||||
|
||||
s->data = s->p = NULL;
|
||||
s->size = 0;
|
||||
STREAM s = NULL;
|
||||
|
||||
cert_list = gnutls_certificate_get_peers(g_tls_session, &list_size);
|
||||
|
||||
@ -466,11 +465,10 @@ tcp_tls_get_server_pubkey(STREAM s)
|
||||
goto out;
|
||||
}
|
||||
|
||||
s->size = pk_size;
|
||||
s->data = s->p = xmalloc(s->size);
|
||||
memcpy((void *)s->data, (void *)pk_data, pk_size);
|
||||
s->p = s->data;
|
||||
s->end = s->p + s->size;
|
||||
s = s_alloc(pk_size);
|
||||
out_uint8a(s, pk_data, pk_size);
|
||||
s_mark_end(s);
|
||||
s_seek(s, 0);
|
||||
|
||||
out:
|
||||
if ((e.size != 0) && (e.data)) {
|
||||
@ -481,7 +479,7 @@ out:
|
||||
free(m.data);
|
||||
}
|
||||
|
||||
return (s->size != 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Helper function to determine if rdesktop should resolve hostnames again or not */
|
||||
|
Loading…
Reference in New Issue
Block a user