From 0582b2659267377f05d1f6dfcf275c61ec6c2926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Moreau?= Date: Tue, 5 Jul 2011 23:18:00 -0400 Subject: [PATCH] libfreerdp-core: adapting NTLMSSP and CredSSP modules to FreeRDP 1.0 --- .gitignore | 4 + cunit/test_freerdp.c | 2 +- cunit/test_gcc.c | 6 +- cunit/test_stream.c | 2 +- cunit/test_transport.c | 4 +- freerdp-ui/test/freerdp.c | 2 +- include/freerdp/utils/stream.h | 152 +++++++++++++++++---------------- libfreerdp-core/CMakeLists.txt | 15 +++- libfreerdp-core/credssp.c | 33 ++++--- libfreerdp-core/credssp.h | 13 ++- libfreerdp-core/crypto.c | 92 ++++++++++++++++++++ libfreerdp-core/crypto.h | 80 +++++++++++++++++ libfreerdp-core/gcc.c | 2 +- libfreerdp-core/ntlmssp.c | 33 ++++--- libfreerdp-core/ntlmssp.h | 12 ++- libfreerdp-core/transport.c | 8 +- libfreerdp-core/transport.h | 4 +- libfreerdp-utils/stream.c | 12 +-- 18 files changed, 336 insertions(+), 140 deletions(-) create mode 100644 libfreerdp-core/crypto.c create mode 100644 libfreerdp-core/crypto.h diff --git a/.gitignore b/.gitignore index c917ab826..5fb272369 100644 --- a/.gitignore +++ b/.gitignore @@ -10,10 +10,14 @@ Makefile # Eclipse *.project *.cproject +*.settings # Doxygen docs/api +# Mac OS X +.DS_Store + # Binaries *.so *.so.* diff --git a/cunit/test_freerdp.c b/cunit/test_freerdp.c index cf974aed6..1d1926e52 100644 --- a/cunit/test_freerdp.c +++ b/cunit/test_freerdp.c @@ -61,7 +61,7 @@ void assert_stream(STREAM* s, uint8* data, int length, const char* func, int lin int actual_length; uint8* actual_data; - actual_data = s->buffer; + actual_data = s->data; actual_length = stream_get_length(s); if (actual_length != length) diff --git a/cunit/test_gcc.c b/cunit/test_gcc.c index 5d2cad0dd..140c6ec04 100644 --- a/cunit/test_gcc.c +++ b/cunit/test_gcc.c @@ -91,9 +91,9 @@ void test_gcc_write_create_conference_request(void) STREAM* s; STREAM user_data; - user_data.buffer = gcc_user_data; - user_data.capacity = sizeof(gcc_user_data); - user_data.ptr = user_data.buffer + user_data.capacity; + user_data.data = gcc_user_data; + user_data.size = sizeof(gcc_user_data); + user_data.p = user_data.data + user_data.size; s = stream_new(sizeof(gcc_create_conference_request_expected)); diff --git a/cunit/test_stream.c b/cunit/test_stream.c index 2eaf28555..ae1a9e256 100644 --- a/cunit/test_stream.c +++ b/cunit/test_stream.c @@ -57,7 +57,7 @@ void test_stream(void) stream_write_uint8(stream, 0xFE); - stream_check_capacity(stream, 14); + stream_check_size(stream, 14); stream_write_uint16(stream, 0x0102); stream_write_uint32(stream, 0x03040506); stream_write_uint64(stream, 0x0708091011121314LL); diff --git a/cunit/test_transport.c b/cunit/test_transport.c index e48b02356..4d3f0a9f9 100644 --- a/cunit/test_transport.c +++ b/cunit/test_transport.c @@ -64,7 +64,7 @@ packet_received(rdpTransport * transport, STREAM * stream, void * extra) uint16 length; length = tpkt_read_header(stream); CU_ASSERT(length == 19); - freerdp_hexdump(stream->buffer, length); + freerdp_hexdump(stream->data, length); test_finished = 1; } @@ -74,7 +74,7 @@ void test_transport(void) STREAM * stream; int r; - transport = transport_new(); + transport = transport_new((rdpSettings*) NULL); transport->recv_callback = packet_received; r = transport_connect(transport, test_server, 3389); diff --git a/freerdp-ui/test/freerdp.c b/freerdp-ui/test/freerdp.c index 5d6a0b730..6a3b4fd61 100644 --- a/freerdp-ui/test/freerdp.c +++ b/freerdp-ui/test/freerdp.c @@ -33,7 +33,7 @@ int main(int argc, char* argv[]) { char* username; char* hostname; - transport = transport_new(); + transport = transport_new((rdpSettings*) NULL); nego = nego_new(transport); if (argc < 3) diff --git a/include/freerdp/utils/stream.h b/include/freerdp/utils/stream.h index e6a9d6055..9c28a3e8e 100644 --- a/include/freerdp/utils/stream.h +++ b/include/freerdp/utils/stream.h @@ -26,118 +26,120 @@ struct _STREAM { - uint8 * ptr; - uint8 * buffer; - int capacity; + int size; + uint8 * p; + uint8 * data; }; typedef struct _STREAM STREAM; STREAM * -stream_new(int capacity); +stream_new(int size); +STREAM * +stream_new_empty(); void stream_free(STREAM * stream); void stream_extend(STREAM * stream); -#define stream_check_capacity(_s,_n) \ - while (_s->ptr - _s->buffer + (_n) > _s->capacity) \ +#define stream_check_size(_s,_n) \ + while (_s->p - _s->data + (_n) > _s->size) \ stream_extend(_s) -#define stream_get_pos(_s) (_s->ptr - _s->buffer) -#define stream_set_pos(_s,_m) _s->ptr = _s->buffer + (_m) -#define stream_seek(_s,_offset) _s->ptr += (_offset) -#define stream_rewind(_s,_offset) _s->ptr -= (_offset) -#define stream_get_mark(_s,_mark) _mark = _s->ptr -#define stream_set_mark(_s,_mark) _s->ptr = _mark -#define stream_get_head(_s) _s->buffer -#define stream_get_tail(_s) _s->ptr -#define stream_get_length(_s) (_s->ptr - _s->buffer) +#define stream_get_pos(_s) (_s->p - _s->data) +#define stream_set_pos(_s,_m) _s->p = _s->data + (_m) +#define stream_seek(_s,_offset) _s->p += (_offset) +#define stream_rewind(_s,_offset) _s->p -= (_offset) +#define stream_get_mark(_s,_mark) _mark = _s->p +#define stream_set_mark(_s,_mark) _s->p = _mark +#define stream_get_head(_s) _s->data +#define stream_get_tail(_s) _s->p +#define stream_get_length(_s) (_s->p - _s->data) -#define stream_read_uint8(_s, _v) do { _v = *_s->ptr++; } while (0) +#define stream_read_uint8(_s, _v) do { _v = *_s->p++; } while (0) #define stream_read_uint16(_s, _v) do { _v = \ - (uint16)(*_s->ptr) + \ - (((uint16)(*(_s->ptr + 1))) << 8); \ - _s->ptr += 2; } while (0) + (uint16)(*_s->p) + \ + (((uint16)(*(_s->p + 1))) << 8); \ + _s->p += 2; } while (0) #define stream_read_uint32(_s, _v) do { _v = \ - (uint32)(*_s->ptr) + \ - (((uint32)(*(_s->ptr + 1))) << 8) + \ - (((uint32)(*(_s->ptr + 2))) << 16) + \ - (((uint32)(*(_s->ptr + 3))) << 24); \ - _s->ptr += 4; } while (0) + (uint32)(*_s->p) + \ + (((uint32)(*(_s->p + 1))) << 8) + \ + (((uint32)(*(_s->p + 2))) << 16) + \ + (((uint32)(*(_s->p + 3))) << 24); \ + _s->p += 4; } while (0) #define stream_read_uint64(_s, _v) do { _v = \ - (uint64)(*_s->ptr) + \ - (((uint64)(*(_s->ptr + 1))) << 8) + \ - (((uint64)(*(_s->ptr + 2))) << 16) + \ - (((uint64)(*(_s->ptr + 3))) << 24) + \ - (((uint64)(*(_s->ptr + 4))) << 32) + \ - (((uint64)(*(_s->ptr + 5))) << 40) + \ - (((uint64)(*(_s->ptr + 6))) << 48) + \ - (((uint64)(*(_s->ptr + 7))) << 56); \ - _s->ptr += 8; } while (0) + (uint64)(*_s->p) + \ + (((uint64)(*(_s->p + 1))) << 8) + \ + (((uint64)(*(_s->p + 2))) << 16) + \ + (((uint64)(*(_s->p + 3))) << 24) + \ + (((uint64)(*(_s->p + 4))) << 32) + \ + (((uint64)(*(_s->p + 5))) << 40) + \ + (((uint64)(*(_s->p + 6))) << 48) + \ + (((uint64)(*(_s->p + 7))) << 56); \ + _s->p += 8; } while (0) #define stream_write_uint8(_s, _v) do { \ - *_s->ptr++ = (uint8)(_v); } while (0) + *_s->p++ = (uint8)(_v); } while (0) #define stream_write_uint16(_s, _v) do { \ - *_s->ptr++ = (_v) & 0xFF; \ - *_s->ptr++ = ((_v) >> 8) & 0xFF; } while (0) + *_s->p++ = (_v) & 0xFF; \ + *_s->p++ = ((_v) >> 8) & 0xFF; } while (0) #define stream_write_uint32(_s, _v) do { \ - *_s->ptr++ = (_v) & 0xFF; \ - *_s->ptr++ = ((_v) >> 8) & 0xFF; \ - *_s->ptr++ = ((_v) >> 16) & 0xFF; \ - *_s->ptr++ = ((_v) >> 24) & 0xFF; } while (0) + *_s->p++ = (_v) & 0xFF; \ + *_s->p++ = ((_v) >> 8) & 0xFF; \ + *_s->p++ = ((_v) >> 16) & 0xFF; \ + *_s->p++ = ((_v) >> 24) & 0xFF; } while (0) #define stream_write_uint64(_s, _v) do { \ - *_s->ptr++ = (_v) & 0xFF; \ - *_s->ptr++ = ((_v) >> 8) & 0xFF; \ - *_s->ptr++ = ((_v) >> 16) & 0xFF; \ - *_s->ptr++ = ((_v) >> 24) & 0xFF; \ - *_s->ptr++ = ((_v) >> 32) & 0xFF; \ - *_s->ptr++ = ((_v) >> 40) & 0xFF; \ - *_s->ptr++ = ((_v) >> 48) & 0xFF; \ - *_s->ptr++ = ((_v) >> 56) & 0xFF; } while (0) + *_s->p++ = (_v) & 0xFF; \ + *_s->p++ = ((_v) >> 8) & 0xFF; \ + *_s->p++ = ((_v) >> 16) & 0xFF; \ + *_s->p++ = ((_v) >> 24) & 0xFF; \ + *_s->p++ = ((_v) >> 32) & 0xFF; \ + *_s->p++ = ((_v) >> 40) & 0xFF; \ + *_s->p++ = ((_v) >> 48) & 0xFF; \ + *_s->p++ = ((_v) >> 56) & 0xFF; } while (0) #define stream_write(_s, _b, _n) do { \ - memcpy(_s->ptr, (_b), (_n)); \ - _s->ptr += (_n); \ + memcpy(_s->p, (_b), (_n)); \ + _s->p += (_n); \ } while (0) #define stream_write_padding(_s, _n) do { \ - memset(_s->ptr, '\0', (_n)); \ - _s->ptr += (_n); \ + memset(_s->p, '\0', (_n)); \ + _s->p += (_n); \ } while (0) -#define stream_peek_uint8(_s, _v) do { _v = *_s->ptr; } while (0) +#define stream_peek_uint8(_s, _v) do { _v = *_s->p; } while (0) #define stream_peek_uint16(_s, _v) do { _v = \ - (uint16)(*_s->ptr) + \ - (((uint16)(*(_s->ptr + 1))) << 8); \ + (uint16)(*_s->p) + \ + (((uint16)(*(_s->p + 1))) << 8); \ } while (0) #define stream_peek_uint32(_s, _v) do { _v = \ - (uint32)(*_s->ptr) + \ - (((uint32)(*(_s->ptr + 1))) << 8) + \ - (((uint32)(*(_s->ptr + 2))) << 16) + \ - (((uint32)(*(_s->ptr + 3))) << 24); \ + (uint32)(*_s->p) + \ + (((uint32)(*(_s->p + 1))) << 8) + \ + (((uint32)(*(_s->p + 2))) << 16) + \ + (((uint32)(*(_s->p + 3))) << 24); \ } while (0) #define stream_peek_uint64(_s, _v) do { _v = \ - (uint64)(*_s->ptr) + \ - (((uint64)(*(_s->ptr + 1))) << 8) + \ - (((uint64)(*(_s->ptr + 2))) << 16) + \ - (((uint64)(*(_s->ptr + 3))) << 24) + \ - (((uint64)(*(_s->ptr + 4))) << 32) + \ - (((uint64)(*(_s->ptr + 5))) << 40) + \ - (((uint64)(*(_s->ptr + 6))) << 48) + \ - (((uint64)(*(_s->ptr + 7))) << 56); \ + (uint64)(*_s->p) + \ + (((uint64)(*(_s->p + 1))) << 8) + \ + (((uint64)(*(_s->p + 2))) << 16) + \ + (((uint64)(*(_s->p + 3))) << 24) + \ + (((uint64)(*(_s->p + 4))) << 32) + \ + (((uint64)(*(_s->p + 5))) << 40) + \ + (((uint64)(*(_s->p + 6))) << 48) + \ + (((uint64)(*(_s->p + 7))) << 56); \ } while (0) #define stream_read_uint16_be(_s, _v) do { _v = \ - (((uint16)(*_s->ptr)) << 8) + \ - (uint16)(*(_s->ptr + 1)); \ - _s->ptr += 2; } while (0) + (((uint16)(*_s->p)) << 8) + \ + (uint16)(*(_s->p + 1)); \ + _s->p += 2; } while (0) #define stream_write_uint16_be(_s, _v) do { \ - *_s->ptr++ = ((_v) >> 8) & 0xFF; \ - *_s->ptr++ = (_v) & 0xFF; } while (0) + *_s->p++ = ((_v) >> 8) & 0xFF; \ + *_s->p++ = (_v) & 0xFF; } while (0) #define stream_copy(_dst, _src, _n) do { \ - memcpy(_dst->ptr, _src->ptr, _n); \ - _dst->ptr += _n; \ - _src->ptr += _n; \ + memcpy(_dst->p, _src->p, _n); \ + _dst->p += _n; \ + _src->p += _n; \ } while (0) #endif /* __STREAM_UTILS_H */ diff --git a/libfreerdp-core/CMakeLists.txt b/libfreerdp-core/CMakeLists.txt index 2cfeb630d..4b40ebff4 100644 --- a/libfreerdp-core/CMakeLists.txt +++ b/libfreerdp-core/CMakeLists.txt @@ -28,10 +28,12 @@ set(LIBFREERDP_CORE_SRCS mcs.h nego.c nego.h -# credssp.c -# credssp.h -# ntlmssp.c -# ntlmssp.h + #crypto.c + #crypto.h + #credssp.c + #credssp.h + #ntlmssp.c + #ntlmssp.h per.c per.h tcp.c @@ -46,9 +48,14 @@ set(LIBFREERDP_CORE_SRCS transport.h ) +include_directories(../libfreerdp-asn1) + add_library(freerdp-core SHARED ${LIBFREERDP_CORE_SRCS}) +target_link_libraries(freerdp-core z) target_link_libraries(freerdp-core ssl) +target_link_libraries(freerdp-core crypto) +target_link_libraries(freerdp-core freerdp-asn1) target_link_libraries(freerdp-core freerdp-utils) install(TARGETS freerdp-core DESTINATION lib) diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index 6097d5483..ddb8c29d4 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -17,7 +17,6 @@ * limitations under the License. */ -#include "stream.h" #ifndef _WIN32 #include #endif @@ -30,8 +29,6 @@ #include #include "ntlmssp.h" -#include -#include #include "credssp.h" @@ -50,7 +47,7 @@ asn1_write(const void *buffer, size_t size, void *fd) void credssp_ntlmssp_init(rdpCredssp *credssp) { NTLMSSP *ntlmssp = credssp->ntlmssp; - rdpSettings *settings = credssp->net->rdp->settings; + rdpSettings *settings = credssp->transport->settings; ntlmssp_set_password(ntlmssp, settings->password); ntlmssp_set_username(ntlmssp, settings->username); @@ -81,15 +78,17 @@ void credssp_ntlmssp_init(rdpCredssp *credssp) int credssp_get_public_key(rdpCredssp *credssp) { - CryptoCert cert; int ret; + CryptoCert cert; + + cert = tls_get_certificate(credssp->transport->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"); return 0; } + ret = crypto_cert_get_public_key(cert, &credssp->public_key); crypto_cert_free(cert); @@ -105,7 +104,7 @@ int credssp_get_public_key(rdpCredssp *credssp) int credssp_authenticate(rdpCredssp *credssp) { NTLMSSP *ntlmssp = credssp->ntlmssp; - STREAM s = xmalloc(sizeof(struct stream)); + STREAM* s = stream_new_empty(); uint8* negoTokenBuffer = (uint8*) xmalloc(2048); credssp_ntlmssp_init(credssp); @@ -114,10 +113,10 @@ int credssp_authenticate(rdpCredssp *credssp) return 0; /* NTLMSSP NEGOTIATE MESSAGE */ - s->p = s->end = s->data = negoTokenBuffer; + s->p = s->data = negoTokenBuffer; ntlmssp_send(ntlmssp, s); credssp->negoToken.data = s->data; - credssp->negoToken.length = s->end - s->data; + credssp->negoToken.length = s->p - s->data; credssp_send(credssp, &credssp->negoToken, NULL, NULL); /* NTLMSSP CHALLENGE MESSAGE */ @@ -125,18 +124,18 @@ int credssp_authenticate(rdpCredssp *credssp) return -1; s->p = s->data = credssp->negoToken.data; - s->end = s->p + credssp->negoToken.length; + s->p + credssp->negoToken.length; ntlmssp_recv(ntlmssp, s); datablob_free(&credssp->negoToken); /* NTLMSSP AUTHENTICATE MESSAGE */ - s->p = s->end = s->data = negoTokenBuffer; + s->p = s->data = negoTokenBuffer; ntlmssp_send(ntlmssp, s); /* The last NTLMSSP message is sent with the encrypted public key */ credssp->negoToken.data = s->data; - credssp->negoToken.length = s->end - s->data; + credssp->negoToken.length = s->p - s->data; credssp_encrypt_public_key(credssp, &credssp->pubKeyAuth); credssp_send(credssp, &credssp->negoToken, &credssp->pubKeyAuth, NULL); @@ -388,7 +387,7 @@ void credssp_send(rdpCredssp *credssp, DATABLOB *negoToken, DATABLOB *pubKeyAuth if (enc_rval.encoded != -1) { - tls_write(credssp->net->tls, buffer, size); + tls_write(credssp->transport->tls, buffer, size); } asn_DEF_TSRequest.free_struct(&asn_DEF_TSRequest, ts_request, 0); @@ -414,7 +413,7 @@ int credssp_recv(rdpCredssp *credssp, DATABLOB *negoToken, DATABLOB *pubKeyAuth, TSRequest_t *ts_request = 0; recv_buffer = xmalloc(size); - bytes_read = tls_read(credssp->net->tls, recv_buffer, size); + bytes_read = tls_read(credssp->transport->tls, recv_buffer, size); if (bytes_read < 0) return -1; @@ -490,12 +489,12 @@ void credssp_current_time(uint8* timestamp) /** * Create new CredSSP state machine. - * @param sec + * @param transport * @return new CredSSP state machine. */ rdpCredssp * -credssp_new(struct rdp_network * net) +credssp_new(rdpTransport * transport) { rdpCredssp * self; @@ -503,7 +502,7 @@ credssp_new(struct rdp_network * net) if (self != NULL) { memset(self, 0, sizeof(rdpCredssp)); - self->net = net; + self->transport = transport; self->send_seq_num = 0; self->ntlmssp = ntlmssp_new(); } diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h index fdb49f9b2..f56adaa92 100644 --- a/libfreerdp-core/credssp.h +++ b/libfreerdp-core/credssp.h @@ -20,7 +20,14 @@ #ifndef __CREDSSP_H #define __CREDSSP_H -#include "network.h" +#include "tls.h" +#include "crypto.h" +#include "transport.h" +#include +#include +#include +#include + #include "ntlmssp.h" struct rdp_credssp @@ -33,7 +40,7 @@ struct rdp_credssp DATABLOB ts_credentials; CryptoRc4 rc4_seal_state; struct _NTLMSSP *ntlmssp; - struct rdp_network * net; + struct rdp_transport * transport; }; typedef struct rdp_credssp rdpCredssp; @@ -50,7 +57,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(struct rdp_network * net); +rdpCredssp* credssp_new(rdpTransport * transport); void credssp_free(rdpCredssp *credssp); #endif /* __CREDSSP_H */ diff --git a/libfreerdp-core/crypto.c b/libfreerdp-core/crypto.c new file mode 100644 index 000000000..5f2709440 --- /dev/null +++ b/libfreerdp-core/crypto.c @@ -0,0 +1,92 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Cryptographic Abstraction Layer + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 "crypto.h" + +CryptoSha1 crypto_sha1_init(void) +{ + CryptoSha1 sha1 = xmalloc(sizeof(*sha1)); + SHA1_Init(&sha1->sha_ctx); + return sha1; +} + +void crypto_sha1_update(CryptoSha1 sha1, uint8 * data, uint32 length) +{ + SHA1_Update(&sha1->sha_ctx, data, length); +} + +void crypto_sha1_final(CryptoSha1 sha1, uint8 * out_data) +{ + SHA1_Final(out_data, &sha1->sha_ctx); + xfree(sha1); +} + +CryptoMd5 crypto_md5_init(void) +{ + CryptoMd5 md5 = xmalloc(sizeof(*md5)); + MD5_Init(&md5->md5_ctx); + return md5; +} + +void crypto_md5_update(CryptoMd5 md5, uint8 * data, uint32 length) +{ + MD5_Update(&md5->md5_ctx, data, length); +} + +void crypto_md5_final(CryptoMd5 md5, uint8 * out_data) +{ + MD5_Final(out_data, &md5->md5_ctx); + xfree(md5); +} + +CryptoRc4 crypto_rc4_init(uint8 * key, uint32 length) +{ + CryptoRc4 rc4 = xmalloc(sizeof(*rc4)); + RC4_set_key(&rc4->rc4_key, length, key); + return rc4; +} + +void crypto_rc4(CryptoRc4 rc4, uint32 length, uint8 * in_data, uint8 * out_data) +{ + RC4(&rc4->rc4_key, length, in_data, out_data); +} + +void crypto_rc4_free(CryptoRc4 rc4) +{ + xfree(rc4); +} + +CryptoCert crypto_cert_read(uint8 * data, uint32 length) +{ + CryptoCert cert = xmalloc(sizeof(*cert)); + /* this will move the data pointer but we don't care, we don't use it again */ + cert->px509 = d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, length); + return cert; +} + +void crypto_cert_free(CryptoCert cert) +{ + X509_free(cert->px509); + xfree(cert); +} + +boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert) +{ + return True; /* FIXME: do the actual verification */ +} diff --git a/libfreerdp-core/crypto.h b/libfreerdp-core/crypto.h new file mode 100644 index 000000000..734d876fc --- /dev/null +++ b/libfreerdp-core/crypto.h @@ -0,0 +1,80 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * Cryptographic Abstraction Layer + * + * Copyright 2011 Marc-Andre Moreau + * + * 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 __CRYPTO_H +#define __CRYPTO_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f) +#define D2I_X509_CONST const +#else +#define D2I_X509_CONST +#endif + +#include + +struct crypto_sha1_struct +{ + SHA_CTX sha_ctx; +}; + +struct crypto_md5_struct +{ + MD5_CTX md5_ctx; +}; + +struct crypto_rc4_struct +{ + RC4_KEY rc4_key; +}; + +struct crypto_cert_struct +{ + X509 * px509; +}; + +typedef struct crypto_sha1_struct * CryptoSha1; +CryptoSha1 crypto_sha1_init(void); +void crypto_sha1_update(CryptoSha1 sha1, uint8 * data, uint32 length); +void crypto_sha1_final(CryptoSha1 sha1, uint8 * out_data); + +typedef struct crypto_md5_struct * CryptoMd5; +CryptoMd5 crypto_md5_init(void); +void crypto_md5_update(CryptoMd5 md5, uint8 * data, uint32 length); +void crypto_md5_final(CryptoMd5 md5, uint8 * out_data); + +typedef struct crypto_rc4_struct * CryptoRc4; +CryptoRc4 crypto_rc4_init(uint8 * key, uint32 length); +void crypto_rc4(CryptoRc4 rc4, uint32 length, uint8 * in_data, uint8 * out_data); +void crypto_rc4_free(CryptoRc4 rc4); + +typedef struct crypto_cert_struct * CryptoCert; +CryptoCert crypto_cert_read(uint8 * data, uint32 length); +void crypto_cert_free(CryptoCert cert); +boolean crypto_cert_verify(CryptoCert server_cert, CryptoCert cacert); + +#endif /* __CRYPTO_H */ diff --git a/libfreerdp-core/gcc.c b/libfreerdp-core/gcc.c index 5293b6c02..96675aa2d 100644 --- a/libfreerdp-core/gcc.c +++ b/libfreerdp-core/gcc.c @@ -131,7 +131,7 @@ gcc_write_create_conference_request(STREAM* s, STREAM* user_data) per_write_octet_string(s, "Duca", 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */ /* userData::value (OCTET_STRING) */ - per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of client data blocks */ + per_write_octet_string(s, user_data->data, stream_get_length(user_data), 0); /* array of client data blocks */ } /** diff --git a/libfreerdp-core/ntlmssp.c b/libfreerdp-core/ntlmssp.c index 0d956c10c..b0584d3e6 100644 --- a/libfreerdp-core/ntlmssp.c +++ b/libfreerdp-core/ntlmssp.c @@ -596,7 +596,7 @@ void ntlmssp_compute_ntlm_v2_response(NTLMSSP *ntlmssp) * @param flags */ -void ntlmssp_input_negotiate_flags(STREAM s, uint32 *flags) +void ntlmssp_input_negotiate_flags(STREAM* s, uint32 *flags) { uint8* p; uint8 tmp; @@ -627,7 +627,7 @@ void ntlmssp_input_negotiate_flags(STREAM s, uint32 *flags) * @param flags */ -void ntlmssp_output_negotiate_flags(STREAM s, uint32 flags) +void ntlmssp_output_negotiate_flags(STREAM* s, uint32 flags) { uint8* p; uint8 tmp; @@ -709,7 +709,7 @@ static void ntlmssp_print_negotiate_flags(uint32 flags) static void ntlmssp_output_restriction_encoding(NTLMSSP *ntlmssp) { AV_PAIR *restrictions = &ntlmssp->av_pairs->Restrictions; - STREAM s = xmalloc(sizeof(struct stream)); + STREAM* s = stream_new_empty(); uint8 machineID[32] = "\x3A\x15\x8E\xA6\x75\x82\xD8\xF7\x3E\x06\xFA\x7A\xB4\xDF\xFD\x43" @@ -720,7 +720,6 @@ static void ntlmssp_output_restriction_encoding(NTLMSSP *ntlmssp) s->data = restrictions->value; s->size = restrictions->length; - s->end = s->data + s->size; s->p = s->data; out_uint32_le(s, 48); /* Size */ @@ -744,7 +743,7 @@ static void ntlmssp_output_restriction_encoding(NTLMSSP *ntlmssp) void ntlmssp_populate_av_pairs(NTLMSSP *ntlmssp) { - STREAM s; + STREAM* s; DATABLOB target_info; AV_PAIRS *av_pairs = ntlmssp->av_pairs; @@ -754,12 +753,12 @@ void ntlmssp_populate_av_pairs(NTLMSSP *ntlmssp) /* Restriction_Encoding */ ntlmssp_output_restriction_encoding(ntlmssp); - s = xmalloc(sizeof(struct stream)); + s = stream_new_empty(); s->data = xmalloc(ntlmssp->target_info.length + 512); s->p = s->data; ntlmssp_output_av_pairs(ntlmssp, s); - datablob_alloc(&target_info, s->end - s->data); + datablob_alloc(&target_info, s->p - s->data); memcpy(target_info.data, s->data, target_info.length); ntlmssp->target_info.data = target_info.data; @@ -773,7 +772,7 @@ void ntlmssp_populate_av_pairs(NTLMSSP *ntlmssp) * @param s */ -void ntlmssp_input_av_pairs(NTLMSSP *ntlmssp, STREAM s) +void ntlmssp_input_av_pairs(NTLMSSP *ntlmssp, STREAM* s) { AV_ID AvId; uint16 AvLen; @@ -871,7 +870,7 @@ void ntlmssp_input_av_pairs(NTLMSSP *ntlmssp, STREAM s) * @param s */ -void ntlmssp_output_av_pairs(NTLMSSP *ntlmssp, STREAM s) +void ntlmssp_output_av_pairs(NTLMSSP *ntlmssp, STREAM* s) { AV_PAIRS *av_pairs = ntlmssp->av_pairs; @@ -1000,7 +999,7 @@ void ntlmssp_free_av_pairs(NTLMSSP *ntlmssp) * @param s */ -static void ntlmssp_output_version(STREAM s) +static void ntlmssp_output_version(STREAM* s) { /* The following version information was observed with Windows 7 */ @@ -1131,7 +1130,7 @@ int ntlmssp_decrypt_message(NTLMSSP *ntlmssp, DATABLOB *encrypted_msg, DATABLOB * @param s */ -void ntlmssp_send_negotiate_message(NTLMSSP *ntlmssp, STREAM s) +void ntlmssp_send_negotiate_message(NTLMSSP *ntlmssp, STREAM* s) { int length; uint32 negotiateFlags = 0; @@ -1194,7 +1193,7 @@ void ntlmssp_send_negotiate_message(NTLMSSP *ntlmssp, STREAM s) s_mark_end(s); - length = s->end - s->data; + length = s->p - s->data; datablob_alloc(&ntlmssp->negotiate_message, length); memcpy(ntlmssp->negotiate_message.data, s->data, length); @@ -1214,7 +1213,7 @@ void ntlmssp_send_negotiate_message(NTLMSSP *ntlmssp, STREAM s) * @param s */ -void ntlmssp_recv_challenge_message(NTLMSSP *ntlmssp, STREAM s) +void ntlmssp_recv_challenge_message(NTLMSSP *ntlmssp, STREAM* s) { uint8* p; int length; @@ -1388,7 +1387,7 @@ void ntlmssp_recv_challenge_message(NTLMSSP *ntlmssp, STREAM s) * @param s */ -void ntlmssp_send_authenticate_message(NTLMSSP *ntlmssp, STREAM s) +void ntlmssp_send_authenticate_message(NTLMSSP *ntlmssp, STREAM* s) { int length; uint32 negotiateFlags = 0; @@ -1584,7 +1583,7 @@ void ntlmssp_send_authenticate_message(NTLMSSP *ntlmssp, STREAM s) printf("\n"); #endif - length = s->end - s->data; + length = s->p - s->data; datablob_alloc(&ntlmssp->authenticate_message, length); memcpy(ntlmssp->authenticate_message.data, s->data, length); @@ -1613,7 +1612,7 @@ void ntlmssp_send_authenticate_message(NTLMSSP *ntlmssp, STREAM s) * @return */ -int ntlmssp_send(NTLMSSP *ntlmssp, STREAM s) +int ntlmssp_send(NTLMSSP *ntlmssp, STREAM* s) { if (ntlmssp->state == NTLMSSP_STATE_INITIAL) ntlmssp->state = NTLMSSP_STATE_NEGOTIATE; @@ -1633,7 +1632,7 @@ int ntlmssp_send(NTLMSSP *ntlmssp, STREAM s) * @return */ -int ntlmssp_recv(NTLMSSP *ntlmssp, STREAM s) +int ntlmssp_recv(NTLMSSP *ntlmssp, STREAM* s) { char signature[8]; /* Signature, "NTLMSSP" */ uint32 messageType; /* MessageType */ diff --git a/libfreerdp-core/ntlmssp.h b/libfreerdp-core/ntlmssp.h index febb67f6a..aa6aaf7d0 100644 --- a/libfreerdp-core/ntlmssp.h +++ b/libfreerdp-core/ntlmssp.h @@ -22,8 +22,10 @@ #include "credssp.h" +#include #include #include +#include struct _AV_PAIR { @@ -138,8 +140,8 @@ void ntlmssp_compute_lm_v2_response(NTLMSSP *ntlmssp); void ntlmssp_compute_ntlm_v2_response(NTLMSSP *ntlmssp); void ntlmssp_populate_av_pairs(NTLMSSP *ntlmssp); -void ntlmssp_input_av_pairs(NTLMSSP *ntlmssp, STREAM s); -void ntlmssp_output_av_pairs(NTLMSSP *ntlmssp, STREAM s); +void ntlmssp_input_av_pairs(NTLMSSP *ntlmssp, STREAM* s); +void ntlmssp_output_av_pairs(NTLMSSP *ntlmssp, STREAM* s); void ntlmssp_free_av_pairs(NTLMSSP *ntlmssp); void ntlmssp_compute_message_integrity_check(NTLMSSP *ntlmssp); @@ -147,13 +149,15 @@ void ntlmssp_compute_message_integrity_check(NTLMSSP *ntlmssp); void ntlmssp_encrypt_message(NTLMSSP *ntlmssp, DATABLOB *msg, DATABLOB *encrypted_msg, uint8* signature); int ntlmssp_decrypt_message(NTLMSSP *ntlmssp, DATABLOB *encrypted_msg, DATABLOB *msg, uint8* signature); -int ntlmssp_recv(NTLMSSP *ntlmssp, STREAM s); -int ntlmssp_send(NTLMSSP *ntlmssp, STREAM s); +int ntlmssp_recv(NTLMSSP *ntlmssp, STREAM* s); +int ntlmssp_send(NTLMSSP *ntlmssp, STREAM* s); NTLMSSP* ntlmssp_new(); void ntlmssp_init(NTLMSSP *ntlmssp); void ntlmssp_free(NTLMSSP *ntlmssp); +#define WITH_DEBUG_NLA + #ifdef WITH_DEBUG_NLA #define DEBUG_NLA(fmt, ...) DEBUG_CLASS(NLA, fmt, ## __VA_ARGS__) #else diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index 6c11428dc..71ab2844c 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -171,9 +171,9 @@ transport_recv_tcp(rdpTransport * transport) { int bytes; - stream_check_capacity(transport->recv_buffer, BUFFER_SIZE); + stream_check_size(transport->recv_buffer, BUFFER_SIZE); - bytes = recv(transport->tcp->sockfd, transport->recv_buffer->ptr, BUFFER_SIZE, 0); + bytes = recv(transport->tcp->sockfd, transport->recv_buffer->p, BUFFER_SIZE, 0); if (bytes == -1) { @@ -242,7 +242,7 @@ transport_check_fds(rdpTransport * transport) if (pos > length) { stream_set_pos(received, length); - stream_check_capacity(transport->recv_buffer, pos - length); + stream_check_size(transport->recv_buffer, pos - length); stream_copy(transport->recv_buffer, received, pos - length); } @@ -264,7 +264,7 @@ transport_init(rdpTransport * transport) } rdpTransport * -transport_new(void) +transport_new(rdpSettings * settings) { rdpTransport * transport; diff --git a/libfreerdp-core/transport.h b/libfreerdp-core/transport.h index 8e6d68a36..12f274798 100644 --- a/libfreerdp-core/transport.h +++ b/libfreerdp-core/transport.h @@ -24,6 +24,7 @@ #include "tls.h" #include +#include #include #include @@ -50,10 +51,11 @@ struct rdp_transport STREAM * recv_buffer; PacketReceivedCallback recv_callback; void* recv_extra; + struct rdp_settings * settings; }; rdpTransport * -transport_new(void); +transport_new(rdpSettings * settings); void transport_free(rdpTransport * transport); boolean diff --git a/libfreerdp-utils/stream.c b/libfreerdp-utils/stream.c index 3d83cd0d1..a5bc1736d 100644 --- a/libfreerdp-utils/stream.c +++ b/libfreerdp-utils/stream.c @@ -33,9 +33,9 @@ stream_new(int capacity) if (stream != NULL) { capacity = capacity > 0 ? capacity : 0x400; - stream->buffer = (uint8 *) xmalloc(capacity); - stream->ptr = stream->buffer; - stream->capacity = capacity; + stream->data = (uint8 *) xmalloc(capacity); + stream->p = stream->data; + stream->size = capacity; } return stream; @@ -46,7 +46,7 @@ stream_free(STREAM * stream) { if (stream != NULL) { - xfree(stream->buffer); + xfree(stream->data); xfree(stream); } } @@ -57,7 +57,7 @@ stream_extend(STREAM * stream) int pos; pos = stream_get_pos(stream); - stream->capacity <<= 1; - stream->buffer = (uint8 *) realloc(stream->buffer, stream->capacity); + stream->size <<= 1; + stream->data = (uint8 *) realloc(stream->data, stream->size); stream_set_pos(stream, pos); }