Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRDP/FreeRDP-old.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Moreau <marcandre.moreau@gmail.com>2011-06-29 04:35:30 +0400
committerMarc-André Moreau <marcandre.moreau@gmail.com>2011-06-29 04:35:30 +0400
commit2b95558d55cc08e240b8ef64f4e6b441711bbea8 (patch)
tree1874b9912658888c7eeea3b08e0e587ff0c5ef0c
parent7c3facc4d18745350b7151e2402c92131b802cd4 (diff)
libfreerdp-core: started network abstraction layer, started decoupling secure.c from the rest
-rw-r--r--dbg.txt0
-rw-r--r--libfreerdp-core/Makefile.am1
-rw-r--r--libfreerdp-core/asn1.c2
-rw-r--r--libfreerdp-core/chan.c10
-rw-r--r--libfreerdp-core/chan.h1
-rw-r--r--libfreerdp-core/credssp.c12
-rw-r--r--libfreerdp-core/credssp.h8
-rw-r--r--libfreerdp-core/freerdp.c10
-rw-r--r--libfreerdp-core/iso.c44
-rw-r--r--libfreerdp-core/iso.h7
-rw-r--r--libfreerdp-core/license.c26
-rw-r--r--libfreerdp-core/license.h5
-rw-r--r--libfreerdp-core/mcs.c39
-rw-r--r--libfreerdp-core/mcs.h5
-rw-r--r--libfreerdp-core/network.c286
-rw-r--r--libfreerdp-core/network.h69
-rw-r--r--libfreerdp-core/rdp.c20
-rw-r--r--libfreerdp-core/rdp.h5
-rw-r--r--libfreerdp-core/secure.c183
-rw-r--r--libfreerdp-core/secure.h11
-rw-r--r--libfreerdp-core/tcp.c127
-rw-r--r--libfreerdp-core/tcp.h9
22 files changed, 527 insertions, 353 deletions
diff --git a/dbg.txt b/dbg.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dbg.txt
diff --git a/libfreerdp-core/Makefile.am b/libfreerdp-core/Makefile.am
index c443f53..b8ba907 100644
--- a/libfreerdp-core/Makefile.am
+++ b/libfreerdp-core/Makefile.am
@@ -23,6 +23,7 @@ libfreerdp_core_la_SOURCES = \
rail.c rail.h \
rdp.c rdp.h \
secure.c secure.h \
+ network.c network.h \
crypto.h \
tcp.c tcp.h \
nego.c nego.h \
diff --git a/libfreerdp-core/asn1.c b/libfreerdp-core/asn1.c
index 58a953c..e1896d6 100644
--- a/libfreerdp-core/asn1.c
+++ b/libfreerdp-core/asn1.c
@@ -42,7 +42,7 @@ ber_parse_header(rdpMcs * mcs, STREAM s, int tagval, int *length)
if (tag != tagval)
{
- ui_error(mcs->sec->rdp->inst, "expected tag %d, got %d\n", tagval, tag);
+ ui_error(mcs->net->rdp->inst, "expected tag %d, got %d\n", tagval, tag);
return False;
}
diff --git a/libfreerdp-core/chan.c b/libfreerdp-core/chan.c
index a0bbec4..5e94bdd 100644
--- a/libfreerdp-core/chan.c
+++ b/libfreerdp-core/chan.c
@@ -38,11 +38,11 @@ vchan_send(rdpChannels * chan, int mcs_id, char * data, int total_length)
rdpSet * settings;
struct rdp_chan * channel;
- settings = chan->mcs->sec->rdp->settings;
+ settings = chan->mcs->net->rdp->settings;
chan_index = (mcs_id - MCS_GLOBAL_CHANNEL) - 1;
if ((chan_index < 0) || (chan_index >= settings->num_channels))
{
- ui_error(chan->mcs->sec->rdp->inst, "error\n");
+ ui_error(chan->mcs->net->rdp->inst, "error\n");
return 0;
}
channel = &(settings->channels[chan_index]);
@@ -61,12 +61,12 @@ vchan_send(rdpChannels * chan, int mcs_id, char * data, int total_length)
{
chan_flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
- s = sec_init(chan->mcs->sec, sec_flags, length + 8);
+ s = sec_init(chan->mcs->net->sec, sec_flags, length + 8);
out_uint32_le(s, total_length);
out_uint32_le(s, chan_flags);
out_uint8p(s, data + sent, length);
s_mark_end(s);
- sec_send_to_channel(chan->mcs->sec, s, sec_flags, mcs_id);
+ sec_send_to_channel(chan->mcs->net->sec, s, sec_flags, mcs_id);
sent += length;
chan_flags = 0;
}
@@ -86,7 +86,7 @@ vchan_process(rdpChannels * chan, STREAM s, int mcs_id)
length = (int) (s->end - s->p);
data = (char *) (s->p);
s->p += length;
- ui_channel_data(chan->mcs->sec->rdp->inst, mcs_id, data, length, flags, total_length);
+ ui_channel_data(chan->mcs->net->sec->rdp->inst, mcs_id, data, length, flags, total_length);
}
rdpChannels *
diff --git a/libfreerdp-core/chan.h b/libfreerdp-core/chan.h
index 867b7b3..e2391e2 100644
--- a/libfreerdp-core/chan.h
+++ b/libfreerdp-core/chan.h
@@ -21,6 +21,7 @@
#define __CHAN_H
#include "mcs.h"
+#include "network.h"
struct rdp_channels
{
diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c
index 86e60d5..0e627ec 100644
--- a/libfreerdp-core/credssp.c
+++ b/libfreerdp-core/credssp.c
@@ -58,7 +58,7 @@ asn1_write(const void *buffer, size_t size, void *fd)
void credssp_ntlmssp_init(rdpCredssp *credssp)
{
NTLMSSP *ntlmssp = credssp->ntlmssp;
- rdpSet *settings = credssp->sec->rdp->settings;
+ rdpSet *settings = credssp->net->rdp->settings;
ntlmssp_set_password(ntlmssp, settings->password);
ntlmssp_set_username(ntlmssp, settings->username);
@@ -92,7 +92,7 @@ int credssp_get_public_key(rdpCredssp *credssp)
CryptoCert cert;
int ret;
- cert = tls_get_certificate(credssp->sec->tls);
+ cert = tls_get_certificate(credssp->net->tls);
if (cert == NULL)
{
printf("credssp_get_public_key: tls_get_certificate failed to return the server certificate.\n");
@@ -396,7 +396,7 @@ void credssp_send(rdpCredssp *credssp, DATABLOB *negoToken, DATABLOB *pubKeyAuth
if (enc_rval.encoded != -1)
{
- tls_write(credssp->sec->tls, buffer, size);
+ tls_write(credssp->net->tls, buffer, size);
}
asn_DEF_TSRequest.free_struct(&asn_DEF_TSRequest, ts_request, 0);
@@ -422,7 +422,7 @@ int credssp_recv(rdpCredssp *credssp, DATABLOB *negoToken, DATABLOB *pubKeyAuth,
TSRequest_t *ts_request = 0;
recv_buffer = xmalloc(size);
- bytes_read = tls_read(credssp->sec->tls, recv_buffer, size);
+ bytes_read = tls_read(credssp->net->tls, recv_buffer, size);
if (bytes_read < 0)
return -1;
@@ -503,7 +503,7 @@ void credssp_current_time(uint8* timestamp)
*/
rdpCredssp *
-credssp_new(struct rdp_sec * sec)
+credssp_new(struct rdp_network * net)
{
rdpCredssp * self;
@@ -511,7 +511,7 @@ credssp_new(struct rdp_sec * sec)
if (self != NULL)
{
memset(self, 0, sizeof(rdpCredssp));
- self->sec = sec;
+ self->net = net;
self->send_seq_num = 0;
self->ntlmssp = ntlmssp_new();
}
diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h
index 2ed888e..8d8b6e4 100644
--- a/libfreerdp-core/credssp.h
+++ b/libfreerdp-core/credssp.h
@@ -20,7 +20,7 @@
#ifndef __CREDSSP_H
#define __CREDSSP_H
-#include "secure.h"
+#include "network.h"
#include "ntlmssp.h"
struct rdp_credssp
@@ -33,7 +33,7 @@ struct rdp_credssp
DATABLOB ts_credentials;
CryptoRc4 rc4_seal_state;
struct _NTLMSSP *ntlmssp;
- struct rdp_sec * sec;
+ struct rdp_network * net;
};
typedef struct rdp_credssp rdpCredssp;
@@ -50,7 +50,7 @@ void credssp_encode_ts_credentials(rdpCredssp *credssp);
void credssp_current_time(uint8* timestamp);
void credssp_rc4k(uint8* key, int length, uint8* plaintext, uint8* ciphertext);
-rdpCredssp* credssp_new(rdpSec *sec);
+rdpCredssp* credssp_new(struct rdp_network * net);
void credssp_free(rdpCredssp *credssp);
-#endif // __CREDSSP_H
+#endif /* __CREDSSP_H */
diff --git a/libfreerdp-core/freerdp.c b/libfreerdp-core/freerdp.c
index 8f4ef3d..0ee77a6 100644
--- a/libfreerdp-core/freerdp.c
+++ b/libfreerdp-core/freerdp.c
@@ -450,9 +450,9 @@ l_rdp_get_fds(rdpInst * inst, void ** read_fds, int * read_count,
rdp = RDP_FROM_INST(inst);
#ifdef _WIN32
- read_fds[*read_count] = (void *) (rdp->sec->mcs->iso->tcp->wsa_event);
+ read_fds[*read_count] = (void *) (rdp->net->tcp->wsa_event);
#else
- read_fds[*read_count] = (void *)(long) (rdp->sec->mcs->iso->tcp->sock);
+ read_fds[*read_count] = (void *)(long) (rdp->net->tcp->sock);
#endif
(*read_count)++;
return 0;
@@ -468,10 +468,10 @@ l_rdp_check_fds(rdpInst * inst)
rdp = RDP_FROM_INST(inst);
#ifdef _WIN32
- WSAResetEvent(rdp->sec->mcs->iso->tcp->wsa_event);
+ WSAResetEvent(rdp->net->tcp->wsa_event);
#endif
rv = 0;
- if (tcp_can_recv(rdp->sec->mcs->iso->tcp->sock, 0))
+ if (tcp_can_recv(rdp->net->tcp->sock, 0))
{
if (!rdp_loop(rdp, &deactivated))
{
@@ -532,7 +532,7 @@ l_rdp_channel_data(rdpInst * inst, int chan_id, char * data, int data_size)
rdpChannels * chan;
rdp = RDP_FROM_INST(inst);
- chan = rdp->sec->mcs->chan;
+ chan = rdp->net->mcs->chan;
return vchan_send(chan, chan_id, data, data_size);
}
diff --git a/libfreerdp-core/iso.c b/libfreerdp-core/iso.c
index 238b80c..9cd8f73 100644
--- a/libfreerdp-core/iso.c
+++ b/libfreerdp-core/iso.c
@@ -80,7 +80,7 @@ x224_send_dst_src_class(rdpIso * iso, uint8 code)
out_uint8(s, 0); /* class */
s_mark_end(s);
- tcp_send(iso->tcp, s);
+ network_send(iso->net, s);
}
/* Output and send X.224 Connection Request TPDU with routing for username */
@@ -93,9 +93,9 @@ x224_send_connection_request(rdpIso * iso)
cookie_length = strlen(iso->cookie);
- if (iso->mcs->sec->rdp->redirect_routingtoken)
+ if (iso->net->rdp->redirect_routingtoken)
/* routingToken */
- length += iso->mcs->sec->rdp->redirect_routingtoken_len;
+ length += iso->net->rdp->redirect_routingtoken_len;
else
/* cookie */
length += 19 + cookie_length;
@@ -115,10 +115,10 @@ x224_send_connection_request(rdpIso * iso)
out_uint16_le(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
- if (iso->mcs->sec->rdp->redirect_routingtoken)
+ if (iso->net->rdp->redirect_routingtoken)
{
/* routingToken */
- out_uint8p(s, iso->mcs->sec->rdp->redirect_routingtoken, iso->mcs->sec->rdp->redirect_routingtoken_len);
+ out_uint8p(s, iso->net->rdp->redirect_routingtoken, iso->net->rdp->redirect_routingtoken_len);
}
else
{
@@ -138,7 +138,7 @@ x224_send_connection_request(rdpIso * iso)
}
s_mark_end(s);
- tcp_send(iso->tcp, s);
+ network_send(iso->net, s);
}
/* Receive an X.224 TPDU */
@@ -149,7 +149,7 @@ x224_recv(rdpIso * iso, STREAM s, int length, uint8 * pcode)
uint8 code;
uint8 subcode;
- s = tcp_recv(iso->tcp, s, length - 4);
+ s = network_recv(iso->net, s, length - 4);
if (s == NULL)
return NULL;
@@ -217,7 +217,7 @@ tpkt_recv(rdpIso * iso, uint8 * pcode, isoRecvType * ptype)
STREAM s;
int length;
- s = tcp_recv(iso->tcp, NULL, 4);
+ s = network_recv(iso->net, NULL, 4);
if (s == NULL)
return NULL;
@@ -250,7 +250,7 @@ tpkt_recv(rdpIso * iso, uint8 * pcode, isoRecvType * ptype)
next_be(s, length);
}
- s = tcp_recv(iso->tcp, s, length - 4);
+ s = network_recv(iso->net, s, length - 4);
return s;
}
return NULL; /* Fast-Path not allowed */
@@ -300,7 +300,7 @@ iso_send(rdpIso * iso, STREAM s)
out_uint8(s, X224_TPDU_DATA); /* code */
out_uint8(s, 0x80); /* eot */
- tcp_send(iso->tcp, s);
+ network_send(iso->net, s);
}
/* Send an fast path data PDU */
@@ -335,7 +335,7 @@ iso_fp_send(rdpIso * iso, STREAM s, uint32 flags)
out_uint8(s, len);
}
- tcp_send(iso->tcp, s);
+ network_send(iso->net, s);
}
/* Receive ISO transport data packet
@@ -355,7 +355,7 @@ iso_recv(rdpIso * iso, isoRecvType * ptype)
(*ptype == ISO_RECV_X224) &&
(code != X224_TPDU_DATA))
{
- ui_error(iso->mcs->sec->rdp->inst, "expected X224_TPDU_DATA, got 0x%x\n", code);
+ ui_error(iso->net->rdp->inst, "expected X224_TPDU_DATA, got 0x%x\n", code);
return NULL;
}
@@ -366,8 +366,14 @@ iso_recv(rdpIso * iso, isoRecvType * ptype)
RD_BOOL
iso_connect(rdpIso * iso, char *server, char *username, int port)
{
- if (strlen(iso->mcs->sec->rdp->settings->domain) > 0)
- iso->cookie = iso->mcs->sec->rdp->settings->domain;
+ if (iso->net == NULL)
+ printf("iso->net\n");
+
+ if (iso->net->rdp == NULL)
+ printf("iso->net->rdp\n");
+
+ if (strlen(iso->net->rdp->settings->domain) > 0)
+ iso->cookie = iso->net->rdp->settings->domain;
else
iso->cookie = username;
@@ -376,6 +382,7 @@ iso_connect(rdpIso * iso, char *server, char *username, int port)
iso->nego->tcp_connected = 0;
nego_init(iso->nego);
+
if (nego_connect(iso->nego) > 0)
{
return True;
@@ -393,14 +400,14 @@ iso_disconnect(rdpIso * iso)
{
x224_send_dst_src_class(iso, X224_TPDU_DISCONNECT_REQUEST);
#ifndef DISABLE_TLS
- if (iso->mcs->sec->tls)
- tls_disconnect(iso->mcs->sec->tls);
+ if (iso->net->tls)
+ tls_disconnect(iso->net->tls);
#endif
tcp_disconnect(iso->tcp);
}
rdpIso *
-iso_new(struct rdp_mcs *mcs)
+iso_new(struct rdp_network * net)
{
rdpIso *self;
@@ -409,7 +416,8 @@ iso_new(struct rdp_mcs *mcs)
if (self != NULL)
{
memset(self, 0, sizeof(rdpIso));
- self->mcs = mcs;
+ self->net = net;
+ self->mcs = net->mcs;
self->tcp = tcp_new(self);
self->nego = nego_new(self);
}
diff --git a/libfreerdp-core/iso.h b/libfreerdp-core/iso.h
index 148b687..ac52c8a 100644
--- a/libfreerdp-core/iso.h
+++ b/libfreerdp-core/iso.h
@@ -18,6 +18,8 @@
*/
#include <freerdp/types/ui.h>
+
+#include "network.h"
#include "stream.h"
#include "nego.h"
@@ -28,8 +30,9 @@ struct rdp_iso
{
char* cookie;
struct _NEGO * nego;
- struct rdp_mcs * mcs;
struct rdp_tcp * tcp;
+ struct rdp_mcs * mcs;
+ struct rdp_network * net;
};
typedef struct rdp_iso rdpIso;
@@ -60,7 +63,7 @@ iso_connect(rdpIso * iso, char * server, char * username, int port);
void
iso_disconnect(rdpIso * iso);
rdpIso *
-iso_new(struct rdp_mcs * mcs);
+iso_new(struct rdp_network * net);
void
iso_free(rdpIso * iso);
diff --git a/libfreerdp-core/license.c b/libfreerdp-core/license.c
index 2863757..20ce159 100644
--- a/libfreerdp-core/license.c
+++ b/libfreerdp-core/license.c
@@ -49,7 +49,7 @@ static void
license_generate_hwid(rdpLicense * license, uint8 * hwid)
{
buf_out_uint32(hwid, 2);
- strncpy((char *) (hwid + 4), license->sec->rdp->settings->hostname, LICENSE_HWID_SIZE - 4);
+ strncpy((char *) (hwid + 4), license->net->rdp->settings->hostname, LICENSE_HWID_SIZE - 4);
}
/* Send a Licensing packet with Client License Information */
@@ -63,7 +63,7 @@ license_present(rdpLicense * license, uint8 * client_random, uint8 * rsa_data,
license_size + LICENSE_HWID_SIZE + LICENSE_SIGNATURE_SIZE;
STREAM s;
- s = sec_init(license->sec, sec_flags, length + 4);
+ s = sec_init(license->net->sec, sec_flags, length + 4);
/* Licensing Preamble (LICENSE_PREAMBLE) */
out_uint8(s, LICENSE_INFO); /* bMsgType LICENSE_INFO */
@@ -96,7 +96,7 @@ license_present(rdpLicense * license, uint8 * client_random, uint8 * rsa_data,
out_uint8p(s, signature, LICENSE_SIGNATURE_SIZE); /* MACData */
s_mark_end(s);
- sec_send(license->sec, s, sec_flags);
+ sec_send(license->net->sec, s, sec_flags);
}
/* Send a Licensing packet with Client New License Request */
@@ -109,7 +109,7 @@ license_send_request(rdpLicense * license, uint8 * client_random, uint8 * rsa_da
uint16 length = 128 + userlen + hostlen;
STREAM s;
- s = sec_init(license->sec, sec_flags, length + 2);
+ s = sec_init(license->net->sec, sec_flags, length + 2);
/* Licensing Preamble (LICENSE_PREAMBLE) */
out_uint8(s, NEW_LICENSE_REQUEST); /* NEW_LICENSE_REQUEST */
@@ -139,7 +139,7 @@ license_send_request(rdpLicense * license, uint8 * client_random, uint8 * rsa_da
out_uint8p(s, host, hostlen);
s_mark_end(s);
- sec_send(license->sec, s, sec_flags);
+ sec_send(license->net->sec, s, sec_flags);
}
/* Process a Server License Request packet */
@@ -208,8 +208,8 @@ license_process_request(rdpLicense * license, STREAM s)
}
license_send_request(license, null_data, null_data,
- license->sec->rdp->settings->username,
- license->sec->rdp->settings->hostname);
+ license->net->rdp->settings->username,
+ license->net->rdp->settings->hostname);
}
/* Send a Licensing packet with Platform Challenge Response */
@@ -220,7 +220,7 @@ license_send_authresp(rdpLicense * license, uint8 * token, uint8 * crypt_hwid, u
uint16 length = 58;
STREAM s;
- s = sec_init(license->sec, sec_flags, length + 2);
+ s = sec_init(license->net->sec, sec_flags, length + 2);
/* Licensing Preamble (LICENSE_PREAMBLE) */
out_uint8(s, PLATFORM_CHALLENGE_RESPONSE); /* PLATFORM_CHALLENGE_RESPONSE */
@@ -240,7 +240,7 @@ license_send_authresp(rdpLicense * license, uint8 * token, uint8 * crypt_hwid, u
out_uint8p(s, signature, LICENSE_SIGNATURE_SIZE); /* MACData */
s_mark_end(s);
- sec_send(license->sec, s, sec_flags);
+ sec_send(license->net->sec, s, sec_flags);
}
/* Parse a Server Platform Challenge packet */
@@ -256,7 +256,7 @@ license_parse_authreq(rdpLicense * license, STREAM s, uint8 ** token, uint8 ** s
in_uint16_le(s, tokenlen); /* wBlobLen */
if (tokenlen != LICENSE_TOKEN_SIZE)
{
- ui_error(license->sec->rdp->inst, "token len %d\n", tokenlen);
+ ui_error(license->net->rdp->inst, "token len %d\n", tokenlen);
return False;
}
in_uint8p(s, *token, tokenlen); /* RC4-encrypted challenge data */
@@ -396,14 +396,14 @@ license_process(rdpLicense * license, STREAM s)
break;
default:
- ui_unimpl(license->sec->rdp->inst, "Unknown license tag 0x%x", tag);
+ ui_unimpl(license->net->rdp->inst, "Unknown license tag 0x%x", tag);
}
s->p = license_start + wMsgSize; /* FIXME: Shouldn't be necessary if parsed properly */
ASSERT(s->p <= s->end);
}
rdpLicense *
-license_new(struct rdp_sec *sec)
+license_new(struct rdp_network * net)
{
rdpLicense *self;
@@ -411,7 +411,7 @@ license_new(struct rdp_sec *sec)
if (self != NULL)
{
memset(self, 0, sizeof(rdpLicense));
- self->sec = sec;
+ self->net = net;
}
return self;
}
diff --git a/libfreerdp-core/license.h b/libfreerdp-core/license.h
index 3b2e525..35df3f0 100644
--- a/libfreerdp-core/license.h
+++ b/libfreerdp-core/license.h
@@ -21,12 +21,13 @@
#define __LICENSE_H
#include "stream.h"
+#include "network.h"
#include <freerdp/types/ui.h>
#include <freerdp/utils/debug.h>
struct rdp_license
{
- struct rdp_sec * sec;
+ struct rdp_network * net;
uint8 license_key[16];
uint8 license_sign_key[16];
RD_BOOL license_issued;
@@ -36,7 +37,7 @@ typedef struct rdp_license rdpLicense;
void
license_process(rdpLicense * license, STREAM s);
rdpLicense *
-license_new(struct rdp_sec * secure);
+license_new(struct rdp_network * net);
void
license_free(rdpLicense * license);
diff --git a/libfreerdp-core/mcs.c b/libfreerdp-core/mcs.c
index f1a2715..fb49173 100644
--- a/libfreerdp-core/mcs.c
+++ b/libfreerdp-core/mcs.c
@@ -69,7 +69,7 @@ mcs_send_connect_initial(rdpMcs * mcs)
gccCCrq.p = gccCCrq.data = (uint8 *) xmalloc(gccCCrq.size);
gccCCrq.end = gccCCrq.data + gccCCrq.size;
- sec_out_gcc_conference_create_request(mcs->sec, &gccCCrq);
+ sec_out_gcc_conference_create_request(mcs->net->sec, &gccCCrq);
gccCCrq_length = gccCCrq.end - gccCCrq.data;
length = 9 + 3 * 34 + 4 + gccCCrq_length;
@@ -115,7 +115,7 @@ mcs_recv_connect_response(rdpMcs * mcs)
in_uint8(s, result);
if (result != 0)
{
- ui_error(mcs->sec->rdp->inst, "MCS connect: %d\n", result);
+ ui_error(mcs->net->rdp->inst, "MCS connect: %d\n", result);
return False;
}
@@ -125,7 +125,7 @@ mcs_recv_connect_response(rdpMcs * mcs)
ber_parse_header(mcs, s, BER_TAG_OCTET_STRING, &length);
- sec_process_mcs_data(mcs->sec, s);
+ sec_process_mcs_data(mcs->net->sec, s);
return s_check_end(s);
}
@@ -173,14 +173,14 @@ mcs_recv_aucf(rdpMcs * mcs, uint16 * mcs_userid)
in_uint8(s, opcode);
if ((opcode >> 2) != T125_DOMAINMCSPDU_AttachUserConfirm)
{
- ui_error(mcs->sec->rdp->inst, "expected AUcf, got %d\n", opcode);
+ ui_error(mcs->net->rdp->inst, "expected AUcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
- ui_error(mcs->sec->rdp->inst, "AUrq: %d\n", result);
+ ui_error(mcs->net->rdp->inst, "AUrq: %d\n", result);
return False;
}
@@ -222,14 +222,14 @@ mcs_recv_cjcf(rdpMcs * mcs)
in_uint8(s, opcode);
if ((opcode >> 2) != T125_DOMAINMCSPDU_ChannelJoinConfirm)
{
- ui_error(mcs->sec->rdp->inst, "expected CJcf, got %d\n", opcode);
+ ui_error(mcs->net->rdp->inst, "expected CJcf, got %d\n", opcode);
return False;
}
in_uint8(s, result);
if (result != 0)
{
- ui_error(mcs->sec->rdp->inst, "CJrq: %d\n", result);
+ ui_error(mcs->net->rdp->inst, "CJrq: %d\n", result);
return False;
}
@@ -321,7 +321,7 @@ mcs_recv(rdpMcs * mcs, isoRecvType * ptype, uint16 * channel)
{
if (pduType != T125_DOMAINMCSPDU_DisconnectProviderUltimatum)
{
- ui_error(mcs->sec->rdp->inst, "expected data, got %d\n", pduType);
+ ui_error(mcs->net->rdp->inst, "expected data, got %d\n", pduType);
}
return NULL;
}
@@ -356,7 +356,7 @@ mcs_connect(rdpMcs * mcs)
mcs_send_connect_initial(mcs);
if (!mcs_recv_connect_response(mcs))
{
- ui_error(mcs->sec->rdp->inst, "invalid mcs_recv_connect_response\n");
+ ui_error(mcs->net->rdp->inst, "invalid mcs_recv_connect_response\n");
goto error;
}
@@ -365,7 +365,7 @@ mcs_connect(rdpMcs * mcs)
mcs_send_aurq(mcs);
if (!mcs_recv_aucf(mcs, &(mcs->mcs_userid)))
{
- ui_error(mcs->sec->rdp->inst, "invalid mcs_recv_aucf\n");
+ ui_error(mcs->net->rdp->inst, "invalid mcs_recv_aucf\n");
goto error;
}
@@ -373,29 +373,29 @@ mcs_connect(rdpMcs * mcs)
if (!mcs_recv_cjcf(mcs))
{
- ui_error(mcs->sec->rdp->inst, "invalid mcs_recv_cjcf\n");
+ ui_error(mcs->net->rdp->inst, "invalid mcs_recv_cjcf\n");
goto error;
}
mcs_send_cjrq(mcs, MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf(mcs))
{
- ui_error(mcs->sec->rdp->inst, "invalid mcs_recv_cjcf\n");
+ ui_error(mcs->net->rdp->inst, "invalid mcs_recv_cjcf\n");
goto error;
}
- settings = mcs->sec->rdp->settings;
+ settings = mcs->net->rdp->settings;
for (i = 0; i < settings->num_channels; i++)
{
mcs_id = settings->channels[i].chan_id;
if (mcs_id >= mcs->mcs_userid + MCS_USERCHANNEL_BASE)
{
- ui_warning(mcs->sec->rdp->inst, "channel %d got id %d >= %d\n", i, mcs_id, mcs->mcs_userid + MCS_USERCHANNEL_BASE);
+ ui_warning(mcs->net->rdp->inst, "channel %d got id %d >= %d\n", i, mcs_id, mcs->mcs_userid + MCS_USERCHANNEL_BASE);
}
mcs_send_cjrq(mcs, mcs_id);
if (!mcs_recv_cjcf(mcs))
{
- ui_error(mcs->sec->rdp->inst, "channel %d id %d invalid mcs_recv_cjcf\n", i, mcs_id);
+ ui_error(mcs->net->rdp->inst, "channel %d id %d invalid mcs_recv_cjcf\n", i, mcs_id);
goto error;
}
}
@@ -414,18 +414,21 @@ mcs_disconnect(rdpMcs * mcs)
}
rdpMcs *
-mcs_new(struct rdp_sec * sec)
+mcs_new(struct rdp_network * net)
{
rdpMcs * self;
self = (rdpMcs *) xmalloc(sizeof(rdpMcs));
+
if (self != NULL)
{
memset(self, 0, sizeof(rdpMcs));
- self->sec = sec;
- self->iso = iso_new(self);
+ self->net = net;
+ self->iso = iso_new(net);
self->chan = vchan_new(self);
+ self->net->iso = self->iso;
}
+
return self;
}
diff --git a/libfreerdp-core/mcs.h b/libfreerdp-core/mcs.h
index 79dc6f5..8313035 100644
--- a/libfreerdp-core/mcs.h
+++ b/libfreerdp-core/mcs.h
@@ -21,13 +21,14 @@
#define __MCS_H
#include "iso.h"
+#include "network.h"
#include <freerdp/utils/debug.h>
struct rdp_mcs
{
- struct rdp_sec * sec;
uint16 mcs_userid;
struct rdp_iso * iso;
+ struct rdp_network * net;
struct rdp_channels * chan;
};
typedef struct rdp_mcs rdpMcs;
@@ -49,7 +50,7 @@ mcs_connect(rdpMcs * mcs);
void
mcs_disconnect(rdpMcs * mcs);
rdpMcs *
-mcs_new(struct rdp_sec * secure);
+mcs_new(struct rdp_network * net);
void
mcs_free(rdpMcs * mcs);
diff --git a/libfreerdp-core/network.c b/libfreerdp-core/network.c
new file mode 100644
index 0000000..abb873c
--- /dev/null
+++ b/libfreerdp-core/network.c
@@ -0,0 +1,286 @@
+/*
+ FreeRDP: A Remote Desktop Protocol client.
+ Network Transport Abstraction Layer
+
+ Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <freerdp/utils/memory.h>
+
+#include "network.h"
+
+#ifndef DISABLE_TLS
+
+/* verify SSL/TLS connection integrity. 2 checks are carried out. First make sure that the
+ * certificate is assigned to the server we're connected to, and second make sure that the
+ * certificate is signed by a trusted certification authority
+ */
+
+RD_BOOL
+network_verify_tls(rdpNetwork * net)
+{
+ char * issuer;
+ char * subject;
+ char * fingerprint;
+ CryptoCert cert;
+ RD_BOOL verified = False;
+
+#ifdef _WIN32
+ /*
+ * TODO: FIX ME! This is really bad, I know...
+ * There appears to be a buffer overflow only
+ * on Windows that affects this part of the code.
+ * Skipping it is a workaround, but it's obviously
+ * not a permanent "solution".
+ */
+ return True;
+#endif
+
+ cert = tls_get_certificate(net->tls);
+
+ if (!cert)
+ {
+ goto exit;
+ }
+
+ subject = crypto_cert_get_subject(cert);
+ issuer = crypto_cert_get_issuer(cert);
+ fingerprint = crypto_cert_get_fingerprint(cert);
+
+ verified = tls_verify(net->tls, net->server);
+
+ if (verified != False)
+ verified = crypto_cert_verify_peer_identity(cert, net->server);
+
+ verified = ui_check_certificate(net->rdp->inst, fingerprint, subject, issuer, verified);
+
+ xfree(fingerprint);
+ xfree(subject);
+ xfree(issuer);
+
+exit:
+ if (cert)
+ {
+ crypto_cert_free(cert);
+ cert = NULL;
+ }
+
+ return verified;
+}
+#endif
+
+RD_BOOL
+network_connect(rdpNetwork * net, char* server, char* username, int port)
+{
+ NEGO *nego = net->iso->nego;
+
+ net->port = port;
+ net->server = server;
+ net->username = username;
+ net->license->license_issued = 0;
+
+ if (net->rdp->settings->nla_security)
+ nego->enabled_protocols[PROTOCOL_NLA] = 1;
+ if (net->rdp->settings->tls_security)
+ nego->enabled_protocols[PROTOCOL_TLS] = 1;
+ if (net->rdp->settings->rdp_security)
+ nego->enabled_protocols[PROTOCOL_RDP] = 1;
+
+ if (!iso_connect(net->iso, net->server, net->username, net->port))
+ return False;
+
+#ifndef DISABLE_TLS
+ if(nego->selected_protocol & PROTOCOL_NLA)
+ {
+ /* TLS with NLA was successfully negotiated */
+
+ RD_BOOL status = 1;
+ printf("TLS encryption with NLA negotiated\n");
+ net->tls = tls_new();
+
+ if (!tls_connect(net->tls, net->tcp->sock))
+ return False;
+
+ if (!network_verify_tls(net))
+ return False;
+
+ net->sec->tls_connected = 1;
+ net->rdp->settings->encryption = 0;
+
+ if (!net->rdp->settings->autologin)
+ if (!ui_authenticate(net->rdp->inst))
+ return False;
+
+ net->credssp = credssp_new(net);
+
+ if (credssp_authenticate(net->credssp) < 0)
+ {
+ printf("Authentication failure, check credentials.\n"
+ "If credentials are valid, the NTLMSSP implementation may be to blame.\n");
+ credssp_free(net->credssp);
+ return 0;
+ }
+
+ credssp_free(net->credssp);
+
+ status = mcs_connect(net->mcs);
+ return status;
+ }
+ else if(nego->selected_protocol & PROTOCOL_TLS)
+ {
+ /* TLS without NLA was successfully negotiated */
+ RD_BOOL success;
+ printf("TLS encryption negotiated\n");
+ net->tls = tls_new();
+
+ if (!tls_connect(net->tls, net->tcp->sock))
+ return False;
+
+ if (!network_verify_tls(net))
+ return False;
+
+ net->sec->tls_connected = 1;
+ net->rdp->settings->encryption = 0;
+
+ success = mcs_connect(net->mcs);
+
+ return success;
+ }
+ else
+#endif
+ {
+ RD_BOOL success;
+
+ printf("Standard RDP encryption negotiated\n");
+
+ success = mcs_connect(net->mcs);
+
+ if (success && net->rdp->settings->encryption)
+ sec_establish_key(net->sec);
+
+ return success;
+ }
+
+ return 0;
+}
+
+void
+network_send(rdpNetwork * net, STREAM s)
+{
+#ifndef DISABLE_TLS
+ if (net->sec->tls_connected)
+ {
+ tls_write(net->tls, (char*) s->data, s->end - s->data);
+ }
+ else
+#endif
+ {
+ tcp_write(net->tcp, s);
+ }
+}
+
+STREAM
+network_recv(rdpNetwork * net, STREAM s, uint32 length)
+{
+ int rcvd = 0;
+ uint32 p_offset;
+ uint32 new_length;
+ uint32 end_offset;
+
+ if (s == NULL)
+ {
+ /* read into "new" stream */
+ if (length > net->in.size)
+ {
+ net->in.data = (uint8 *) xrealloc(net->in.data, length);
+ net->in.size = length;
+ }
+
+ net->in.end = net->in.p = net->in.data;
+ s = &(net->in);
+ }
+ else
+ {
+ /* append to existing stream */
+ new_length = (s->end - s->data) + length;
+ if (new_length > s->size)
+ {
+ p_offset = s->p - s->data;
+ end_offset = s->end - s->data;
+ s->data = (uint8 *) xrealloc(s->data, new_length);
+ s->size = new_length;
+ s->p = s->data + p_offset;
+ s->end = s->data + end_offset;
+ }
+ }
+
+ while (length > 0)
+ {
+#ifndef DISABLE_TLS
+ if (net->sec->tls_connected)
+ {
+ rcvd = tls_read(net->tls, (char*) s->end, length);
+
+ if (rcvd < 0)
+ return NULL;
+ }
+ else
+#endif
+ {
+ rcvd = tcp_read(net->tcp, (char*) s->end, length);
+ }
+
+ s->end += rcvd;
+ length -= rcvd;
+ }
+
+ return s;
+}
+
+rdpNetwork*
+network_new(rdpRdp * rdp)
+{
+ rdpNetwork * self;
+
+ self = (rdpNetwork *) xmalloc(sizeof(rdpNetwork));
+
+ if (self != NULL)
+ {
+ memset(self, 0, sizeof(rdpNetwork));
+ self->rdp = rdp;
+ self->mcs = mcs_new(self);
+ self->iso = iso_new(self);
+ self->license = license_new(self);
+
+ self->in.size = 4096;
+ self->in.data = (uint8 *) xmalloc(self->in.size);
+
+ self->out.size = 4096;
+ self->out.data = (uint8 *) xmalloc(self->out.size);
+ }
+
+ return self;
+}
+
+void
+network_free(rdpNetwork * net)
+{
+ if (net != NULL)
+ {
+ xfree(net->in.data);
+ xfree(net->out.data);
+ xfree(net);
+ }
+}
diff --git a/libfreerdp-core/network.h b/libfreerdp-core/network.h
new file mode 100644
index 0000000..52fbf7c
--- /dev/null
+++ b/libfreerdp-core/network.h
@@ -0,0 +1,69 @@
+/*
+ FreeRDP: A Remote Desktop Protocol client.
+ Network Transport Abstraction Layer
+
+ Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef __NETWORK_H
+#define __NETWORK_H
+
+#include <freerdp/freerdp.h>
+#include <freerdp/types/ui.h>
+
+#include "tcp.h"
+#include "tls.h"
+#include "iso.h"
+#include "mcs.h"
+#include "rdp.h"
+#include "secure.h"
+#include "stream.h"
+#include "credssp.h"
+#include "license.h"
+
+struct rdp_network
+{
+ int port;
+ char* server;
+ char* username;
+ struct stream in;
+ struct stream out;
+ struct rdp_rdp * rdp;
+ struct rdp_tcp * tcp;
+ struct rdp_sec * sec;
+ struct rdp_tls * tls;
+ struct rdp_iso * iso;
+ struct rdp_mcs * mcs;
+ struct rdp_credssp * credssp;
+ struct rdp_license * license;
+};
+typedef struct rdp_network rdpNetwork;
+
+RD_BOOL
+network_connect(rdpNetwork * net, char* server, char* username, int port);
+
+void
+network_send(rdpNetwork * net, STREAM s);
+
+STREAM
+network_recv(rdpNetwork * net, STREAM s, uint32 length);
+
+rdpNetwork*
+network_new(rdpRdp * rdp);
+
+void
+network_free(rdpNetwork * net);
+
+#endif /* __NETWORK_H */
diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c
index 47b9738..e8c9949 100644
--- a/libfreerdp-core/rdp.c
+++ b/libfreerdp-core/rdp.c
@@ -35,6 +35,7 @@
#include "bitmap.h"
#include "ext.h"
#include "surface.h"
+#include "network.h"
#include <freerdp/freerdp.h>
#include <freerdp/utils/hexdump.h>
@@ -186,7 +187,7 @@ rdp_send_data(rdpRdp * rdp, STREAM s, uint8 data_pdu_type)
/* Share Control Header */
out_uint16_le(s, length); /* totalLength */
out_uint16_le(s, (RDP_PDU_DATA | 0x10)); /* pduType */
- out_uint16_le(s, (rdp->sec->mcs->mcs_userid + 1001)); /* PDUSource */
+ out_uint16_le(s, (rdp->net->mcs->mcs_userid + 1001)); /* PDUSource */
/* Share Data Header */
out_uint32_le(s, rdp->rdp_shareid); /* shareId */
@@ -352,7 +353,7 @@ rdp_send_client_info(rdpRdp * rdp, uint32 flags, char *domain_name,
userName = freerdp_uniconv_out(rdp->uniconv, username, &cbUserName);
alternateShell = freerdp_uniconv_out(rdp->uniconv, shell, &cbAlternateShell);
workingDir = freerdp_uniconv_out(rdp->uniconv, dir, &cbWorkingDir);
- clientAddress = freerdp_uniconv_out(rdp->uniconv, tcp_get_address(rdp->sec->mcs->iso->tcp), &cbClientAddress);
+ clientAddress = freerdp_uniconv_out(rdp->uniconv, tcp_get_address(rdp->net->tcp), &cbClientAddress);
clientDir = freerdp_uniconv_out(rdp->uniconv, dll, &cbClientDir); /* client working directory OR binary name */
length = 8 + (5 * 4) + cbDomain + cbUserName + cbPassword + cbAlternateShell + cbWorkingDir;
@@ -775,7 +776,7 @@ rdp_send_confirm_active(rdpRdp * rdp)
/* share control header */
out_uint16_le(s, length);
out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
- out_uint16_le(s, (rdp->sec->mcs->mcs_userid + 1001));
+ out_uint16_le(s, (rdp->net->mcs->mcs_userid + 1001));
out_uint32_le(s, rdp->rdp_shareid); /* sharedId */
/* originatorId must be set to the server channel ID
@@ -1672,7 +1673,7 @@ rdp_connect(rdpRdp * rdp)
connect_flags |= INFO_REMOTECONSOLEAUDIO;
}
- if (!sec_connect(rdp->sec, rdp->settings->server, rdp->settings->username, rdp->settings->tcp_port_rdp))
+ if (!network_connect(rdp->net, rdp->settings->server, rdp->settings->username, rdp->settings->tcp_port_rdp))
return False;
password_encoded = freerdp_uniconv_out(rdp->uniconv, rdp->settings->password, &password_encoded_len);
@@ -1702,7 +1703,8 @@ rdp_reconnect(rdpRdp * rdp)
sec_disconnect(rdp->sec);
sec_free(rdp->sec);
rdp->sec = sec_new(rdp);
- if (!sec_connect(rdp->sec, server, username, rdp->settings->tcp_port_rdp))
+
+ if (!network_connect(rdp->net, server, username, rdp->settings->tcp_port_rdp))
return False;
domain = rdp->redirect_domain ? rdp->redirect_domain : rdp->settings->domain;
@@ -1714,11 +1716,14 @@ rdp_reconnect(rdpRdp * rdp)
}
else
password = freerdp_uniconv_out(rdp->uniconv, rdp->settings->password, &password_len);
+
rdp_send_client_info(rdp, INFO_NORMALLOGON | INFO_AUTOLOGON,
domain, username, password, password_len,
rdp->settings->shell, rdp->settings->directory);
+
if (!rdp->redirect_password)
xfree(password);
+
return True;
}
@@ -1745,11 +1750,16 @@ rdp_new(struct rdp_set *settings, struct rdp_inst *inst)
self->buffer_size = 2048;
self->buffer = xmalloc(self->buffer_size);
memset(self->buffer, 0, self->buffer_size);
+ self->net = network_new(self);
self->sec = sec_new(self);
self->orders = orders_new(self);
self->pcache = pcache_new(self);
self->cache = cache_new(self);
self->ext = ext_new(self);
+
+ self->net->rdp = self;
+ self->net->sec = self->sec;
+ self->net->tcp = self->net->iso->tcp;
}
return self;
}
diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h
index 6ce5cad..1596776 100644
--- a/libfreerdp-core/rdp.h
+++ b/libfreerdp-core/rdp.h
@@ -65,11 +65,12 @@ struct rdp_rdp
UNICONV *uniconv;
RDPCOMP mppc_dict;
struct rdp_sec * sec;
- struct rdp_set * settings; // RDP settings
+ struct rdp_network * net;
+ struct rdp_set * settings;
struct rdp_orders * orders;
struct rdp_pcache * pcache;
struct rdp_cache * cache;
- struct rdp_app * app; // RemoteApp
+ struct rdp_app * app;
struct rdp_ext * ext;
/* Session Directory redirection */
int redirect;
diff --git a/libfreerdp-core/secure.c b/libfreerdp-core/secure.c
index 7be5cdc..06e1e3e 100644
--- a/libfreerdp-core/secure.c
+++ b/libfreerdp-core/secure.c
@@ -283,7 +283,7 @@ sec_init(rdpSec * sec, uint32 flags, int maxlen)
if (flags)
{
- if (!(sec->license->license_issued))
+ if (!(sec->net->license->license_issued))
hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
else
hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
@@ -291,7 +291,7 @@ sec_init(rdpSec * sec, uint32 flags, int maxlen)
else
hdrlen = 0;
- s = mcs_init(sec->mcs, maxlen + hdrlen);
+ s = mcs_init(sec->net->mcs, maxlen + hdrlen);
s_push_layer(s, sec_hdr, hdrlen);
return s;
@@ -305,7 +305,7 @@ sec_fp_init(rdpSec * sec, uint32 flags, int maxlen)
int hdrlen;
hdrlen = (flags & SEC_ENCRYPT) ? 8 : 0;
- s = mcs_fp_init(sec->mcs, maxlen + hdrlen);
+ s = mcs_fp_init(sec->net->mcs, maxlen + hdrlen);
s_push_layer(s, sec_hdr, hdrlen);
return s;
@@ -321,7 +321,7 @@ sec_send_to_channel(rdpSec * sec, STREAM s, uint32 flags, uint16 channel)
if (flags)
{
/* Basic Security Header */
- if (!(sec->license->license_issued) || (flags & SEC_ENCRYPT))
+ if (!(sec->net->license->license_issued) || (flags & SEC_ENCRYPT))
out_uint32_le(s, flags); /* flags */
if (flags & SEC_ENCRYPT)
@@ -339,7 +339,7 @@ sec_send_to_channel(rdpSec * sec, STREAM s, uint32 flags, uint16 channel)
}
}
- mcs_send_to_channel(sec->mcs, s, channel);
+ mcs_send_to_channel(sec->net->mcs, s, channel);
}
/* Transmit secure transport packet */
@@ -362,11 +362,11 @@ sec_fp_send(rdpSec * sec, STREAM s, uint32 flags)
sec_sign(s->p, 8, sec->sec_sign_key, sec->rc4_key_len, s->p + 8, datalen);
sec_encrypt(sec, s->p + 8, datalen);
}
- mcs_fp_send(sec->mcs, s, flags);
+ mcs_fp_send(sec->net->mcs, s, flags);
}
/* Transfer the client random to the server */
-static void
+void
sec_establish_key(rdpSec * sec)
{
uint32 length = sec->server_public_key_len + SEC_PADDING_SIZE;
@@ -451,7 +451,7 @@ sec_out_client_core_data(rdpSec * sec, rdpSet * settings, STREAM s)
is set in earlyCapabilityFlags */
out_uint8(s, con_type);
out_uint8(s, 0); /* pad1octet */
- out_uint32_le(s, sec->mcs->iso->nego->selected_protocol); /* serverSelectedProtocol */
+ out_uint32_le(s, sec->net->iso->nego->selected_protocol); /* serverSelectedProtocol */
}
static void
@@ -950,7 +950,7 @@ sec_recv(rdpSec * sec, secRecvType * type)
uint32 sec_flags;
isoRecvType iso_type;
- while ((s = mcs_recv(sec->mcs, &iso_type, &channel)) != NULL)
+ while ((s = mcs_recv(sec->net->mcs, &iso_type, &channel)) != NULL)
{
if ((iso_type == ISO_RECV_FAST_PATH) ||
(iso_type == ISO_RECV_FAST_PATH_ENCRYPTED))
@@ -968,7 +968,7 @@ sec_recv(rdpSec * sec, secRecvType * type)
ui_error(sec->rdp->inst, "expected ISO_RECV_X224, got %d\n", iso_type);
return NULL;
}
- if (sec->rdp->settings->encryption || !sec->license->license_issued)
+ if (sec->rdp->settings->encryption || !sec->net->license->license_issued)
{
/* basicSecurityHeader: */
in_uint32_le(s, sec_flags);
@@ -982,7 +982,7 @@ sec_recv(rdpSec * sec, secRecvType * type)
if (sec_flags & SEC_LICENSE_PKT)
{
*type = SEC_RECV_LICENSE;
- license_process(sec->license, s);
+ license_process(sec->net->license, s);
continue;
}
@@ -995,7 +995,7 @@ sec_recv(rdpSec * sec, secRecvType * type)
if (channel != MCS_GLOBAL_CHANNEL)
{
- vchan_process(sec->mcs->chan, s, channel);
+ vchan_process(sec->net->mcs->chan, s, channel);
*type = SEC_RECV_IOCHANNEL;
return s;
}
@@ -1006,161 +1006,11 @@ sec_recv(rdpSec * sec, secRecvType * type)
return NULL;
}
-#ifndef DISABLE_TLS
-
-/* verify SSL/TLS connection integrity. 2 checks are carried out. First make sure that the
- * certificate is assigned to the server we're connected to, and second make sure that the
- * certificate is signed by a trusted certification authority
- */
-
-static RD_BOOL
-sec_verify_tls(rdpSec * sec, const char * server)
-{
- char * issuer;
- char * subject;
- char * fingerprint;
- CryptoCert cert;
- RD_BOOL verified = False;
-
-#ifdef _WIN32
- /*
- * TODO: FIX ME! This is really bad, I know...
- * There appears to be a buffer overflow only
- * on Windows that affects this part of the code.
- * Skipping it is a workaround, but it's obviously
- * not a permanent "solution".
- */
- return True;
-#endif
-
- cert = tls_get_certificate(sec->tls);
-
- if (!cert)
- {
- goto exit;
- }
-
- subject = crypto_cert_get_subject(cert);
- issuer = crypto_cert_get_issuer(cert);
- fingerprint = crypto_cert_get_fingerprint(cert);
-
- verified = tls_verify(sec->tls, server);
-
- if (verified != False)
- verified = crypto_cert_verify_peer_identity(cert, server);
-
- verified = ui_check_certificate(sec->rdp->inst, fingerprint, subject, issuer, verified);
-
- xfree(fingerprint);
- xfree(subject);
- xfree(issuer);
-
-exit:
- if (cert)
- {
- crypto_cert_free(cert);
- cert = NULL;
- }
-
- return verified;
-}
-#endif
-
-/* Establish a secure connection */
-RD_BOOL
-sec_connect(rdpSec * sec, char *server, char *username, int port)
-{
- NEGO *nego = sec->mcs->iso->nego;
-
- sec->license->license_issued = 0;
- if (sec->rdp->settings->nla_security)
- nego->enabled_protocols[PROTOCOL_NLA] = 1;
- if (sec->rdp->settings->tls_security)
- nego->enabled_protocols[PROTOCOL_TLS] = 1;
- if (sec->rdp->settings->rdp_security)
- nego->enabled_protocols[PROTOCOL_RDP] = 1;
-
- if (!iso_connect(sec->mcs->iso, server, username, port))
- return False;
-
-#ifndef DISABLE_TLS
- if(nego->selected_protocol & PROTOCOL_NLA)
- {
- /* TLS with NLA was successfully negotiated */
- RD_BOOL status = 1;
- printf("TLS encryption with NLA negotiated\n");
- sec->tls = tls_new();
- if (!tls_connect(sec->tls, sec->mcs->iso->tcp->sock))
- return False;
- if (!sec_verify_tls(sec, server))
- return False;
- sec->tls_connected = 1;
- sec->rdp->settings->encryption = 0;
-
- if (!sec->rdp->settings->autologin)
- if (!ui_authenticate(sec->rdp->inst))
- return False;
-
- sec->credssp = credssp_new(sec);
-
- if (credssp_authenticate(sec->credssp) < 0)
- {
- printf("Authentication failure, check credentials.\n"
- "If credentials are valid, the NTLMSSP implementation may be to blame.\n");
- credssp_free(sec->credssp);
- return 0;
- }
-
- credssp_free(sec->credssp);
-
- status = mcs_connect(sec->mcs);
- return status;
- }
- else if(nego->selected_protocol & PROTOCOL_TLS)
- {
- /* TLS without NLA was successfully negotiated */
- RD_BOOL success;
- printf("TLS encryption negotiated\n");
- sec->tls = tls_new();
- if (!tls_connect(sec->tls, sec->mcs->iso->tcp->sock))
- return False;
- if (!sec_verify_tls(sec, server))
- return False;
- sec->tls_connected = 1;
- sec->rdp->settings->encryption = 0;
- success = mcs_connect(sec->mcs);
- return success;
- }
- else
-#endif
- {
- RD_BOOL success;
-
- printf("Standard RDP encryption negotiated\n");
-
- success = mcs_connect(sec->mcs);
-
- if (success && sec->rdp->settings->encryption)
- sec_establish_key(sec);
-
- return success;
- }
-
- return 0;
-}
-
/* Disconnect a connection */
void
sec_disconnect(rdpSec * sec)
{
- mcs_disconnect(sec->mcs);
-
-#ifndef DISABLE_TLS
- if (sec->tls)
- tls_free(sec->tls);
- sec->tls = NULL;
- sec->tls_connected = 0;
-#endif
+ mcs_disconnect(sec->net->mcs);
if (sec->rc4_decrypt_key)
crypto_rc4_free(sec->rc4_decrypt_key);
@@ -1180,10 +1030,9 @@ sec_new(struct rdp_rdp * rdp)
{
memset(self, 0, sizeof(rdpSec));
self->rdp = rdp;
- self->mcs = mcs_new(self);
- self->license = license_new(self);
self->rc4_decrypt_key = NULL;
self->rc4_encrypt_key = NULL;
+ self->net = rdp->net;
}
return self;
}
@@ -1193,8 +1042,8 @@ sec_free(rdpSec * sec)
{
if (sec != NULL)
{
- license_free(sec->license);
- mcs_free(sec->mcs);
+ license_free(sec->net->license);
+ mcs_free(sec->net->mcs);
xfree(sec);
}
}
diff --git a/libfreerdp-core/secure.h b/libfreerdp-core/secure.h
index d5973cf..5a44da1 100644
--- a/libfreerdp-core/secure.h
+++ b/libfreerdp-core/secure.h
@@ -51,13 +51,8 @@ struct rdp_sec
/* These values must be available to reset state - Session Directory */
int sec_encrypt_use_count;
int sec_decrypt_use_count;
- struct rdp_mcs * mcs;
- struct rdp_license * license;
int tls_connected;
-#ifndef DISABLE_TLS
- struct rdp_tls * tls;
- struct rdp_credssp * credssp;
-#endif
+ struct rdp_network * net;
};
enum sec_recv_type
@@ -95,8 +90,10 @@ STREAM
sec_recv(rdpSec * sec, secRecvType * type);
void
sec_out_gcc_conference_create_request(rdpSec * sec, STREAM s);
+void
+sec_establish_key(rdpSec * sec);
RD_BOOL
-sec_connect(rdpSec * sec, char *server, char *username, int port);
+sec_verify_tls(rdpSec * sec, const char * server);
void
sec_disconnect(rdpSec * sec);
rdpSec *
diff --git a/libfreerdp-core/tcp.c b/libfreerdp-core/tcp.c
index 035b2c4..2f6ea62 100644
--- a/libfreerdp-core/tcp.c
+++ b/libfreerdp-core/tcp.c
@@ -35,6 +35,7 @@
#include "secure.h"
#include "rdp.h"
#include <freerdp/utils/memory.h>
+#include <freerdp/utils/hexdump.h>
#include "tcp.h"
@@ -141,128 +142,66 @@ tcp_init(rdpTcp * tcp, uint32 minsize)
return result;
}
-/* Send data from stream to tcp socket.
- * Will block until all data has been sent. */
void
-tcp_send(rdpTcp * tcp, STREAM s)
+tcp_write(rdpTcp * tcp, STREAM s)
{
int sent = 0;
int total = 0;
int length = s->end - s->data;
-#ifndef DISABLE_TLS
- if (tcp->iso->mcs->sec->tls_connected)
- {
- tls_write(tcp->iso->mcs->sec->tls, (char*) s->data, length);
- }
- else
-#endif
+ while (total < length)
{
while (total < length)
{
- while (total < length)
+ sent = send(tcp->sock, s->data + total, length - total, MSG_NOSIGNAL);
+ if (sent <= 0)
{
- sent = send(tcp->sock, s->data + total, length - total, MSG_NOSIGNAL);
- if (sent <= 0)
+ if (sent == -1 && TCP_BLOCKS)
{
- if (sent == -1 && TCP_BLOCKS)
- {
- tcp_can_send(tcp->sock, 100);
- sent = 0;
- }
- else
- {
- ui_error(tcp->iso->mcs->sec->rdp->inst, "send: %s\n", TCP_STRERROR);
- return;
- }
+ tcp_can_send(tcp->sock, 100);
+ sent = 0;
+ }
+ else
+ {
+ ui_error(tcp->iso->net->rdp->inst, "send: %s\n", TCP_STRERROR);
+ return;
}
- total += sent;
}
+ total += sent;
}
}
}
-/* Read length bytes from tcp socket to stream and return it.
- * Appends to stream s if specified, otherwise it uses stream from tcp layer.
- * Will block until data available.
- * Returns NULL on error. */
-STREAM
-tcp_recv(rdpTcp * tcp, STREAM s, uint32 length)
+int
+tcp_read(rdpTcp * tcp, char* b, int length)
{
int rcvd = 0;
- uint32 p_offset;
- uint32 new_length;
- uint32 end_offset;
- if (s == NULL)
- {
- /* read into "new" stream */
- if (length > tcp->in.size)
- {
- tcp->in.data = (uint8 *) xrealloc(tcp->in.data, length);
- tcp->in.size = length;
- }
+ if (!ui_select(tcp->iso->mcs->net->sec->rdp->inst, tcp->sock))
+ return -1; /* user quit */
- tcp->in.end = tcp->in.p = tcp->in.data;
- s = &(tcp->in);
- }
- else
- {
- /* append to existing stream */
- new_length = (s->end - s->data) + length;
- if (new_length > s->size)
- {
- p_offset = s->p - s->data;
- end_offset = s->end - s->data;
- s->data = (uint8 *) xrealloc(s->data, new_length);
- s->size = new_length;
- s->p = s->data + p_offset;
- s->end = s->data + end_offset;
- }
- }
+ rcvd = recv(tcp->sock, b, length, 0);
- while (length > 0)
+ if (rcvd < 0)
{
-#ifndef DISABLE_TLS
- if (tcp->iso->mcs->sec->tls_connected)
+ if (rcvd == -1 && TCP_BLOCKS)
{
- rcvd = tls_read(tcp->iso->mcs->sec->tls, (char*) s->end, length);
-
- if (rcvd < 0)
- return NULL;
+ tcp_can_recv(tcp->sock, 1);
+ rcvd = 0;
}
else
-#endif
{
- if (!ui_select(tcp->iso->mcs->sec->rdp->inst, tcp->sock))
- return NULL; /* user quit */
-
- rcvd = recv(tcp->sock, s->end, length, 0);
- if (rcvd < 0)
- {
- if (rcvd == -1 && TCP_BLOCKS)
- {
- tcp_can_recv(tcp->sock, 1);
- rcvd = 0;
- }
- else
- {
- ui_error(tcp->iso->mcs->sec->rdp->inst, "recv: %s\n", TCP_STRERROR);
- return NULL;
- }
- }
- else if (rcvd == 0)
- {
- ui_error(tcp->iso->mcs->sec->rdp->inst, "Connection closed\n");
- return NULL;
- }
+ ui_error(tcp->iso->mcs->net->rdp->inst, "recv: %s\n", TCP_STRERROR);
+ return -1;
}
-
- s->end += rcvd;
- length -= rcvd;
+ }
+ else if (rcvd == 0)
+ {
+ ui_error(tcp->iso->mcs->net->rdp->inst, "Connection closed\n");
+ return -1;
}
- return s;
+ return rcvd;
}
/* Establish a connection on the TCP layer */
@@ -289,7 +228,7 @@ tcp_connect(rdpTcp * tcp, char * server, int port)
if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res)))
{
- ui_error(tcp->iso->mcs->sec->rdp->inst, "getaddrinfo: %s\n", gai_strerror(n));
+ ui_error(tcp->iso->mcs->net->sec->rdp->inst, "getaddrinfo: %s\n", gai_strerror(n));
return False;
}
@@ -311,7 +250,7 @@ tcp_connect(rdpTcp * tcp, char * server, int port)
if (sock == -1)
{
- ui_error(tcp->iso->mcs->sec->rdp->inst, "%s: unable to connect\n", server);
+ ui_error(tcp->iso->mcs->net->sec->rdp->inst, "%s: unable to connect\n", server);
return False;
}
diff --git a/libfreerdp-core/tcp.h b/libfreerdp-core/tcp.h
index e5f2d69..1af3cf7 100644
--- a/libfreerdp-core/tcp.h
+++ b/libfreerdp-core/tcp.h
@@ -28,16 +28,21 @@ struct rdp_tcp
{
int sock;
struct rdp_iso * iso;
- struct stream in;
- struct stream out;
int tcp_port_rdp;
char ipaddr[32];
+ struct stream in;
+ struct stream out;
#ifdef _WIN32
WSAEVENT wsa_event;
#endif
};
typedef struct rdp_tcp rdpTcp;
+void
+tcp_write(rdpTcp * tcp, STREAM s);
+int
+tcp_read(rdpTcp * tcp, char* b, int length);
+
RD_BOOL
tcp_can_send(int sck, int millis);
RD_BOOL