mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: adapting NTLMSSP and CredSSP modules to FreeRDP 1.0
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -10,10 +10,14 @@ Makefile
|
||||
# Eclipse
|
||||
*.project
|
||||
*.cproject
|
||||
*.settings
|
||||
|
||||
# Doxygen
|
||||
docs/api
|
||||
|
||||
# Mac OS X
|
||||
.DS_Store
|
||||
|
||||
# Binaries
|
||||
*.so
|
||||
*.so.*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "stream.h"
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@@ -30,8 +29,6 @@
|
||||
|
||||
#include <time.h>
|
||||
#include "ntlmssp.h"
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,14 @@
|
||||
#ifndef __CREDSSP_H
|
||||
#define __CREDSSP_H
|
||||
|
||||
#include "network.h"
|
||||
#include "tls.h"
|
||||
#include "crypto.h"
|
||||
#include "transport.h"
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
#include <freerdp/utils/datablob.h>
|
||||
|
||||
#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 */
|
||||
|
||||
92
libfreerdp-core/crypto.c
Normal file
92
libfreerdp-core/crypto.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Cryptographic 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 "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 */
|
||||
}
|
||||
80
libfreerdp-core/crypto.h
Normal file
80
libfreerdp-core/crypto.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Cryptographic 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 __CRYPTO_H
|
||||
#define __CRYPTO_H
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f)
|
||||
#define D2I_X509_CONST const
|
||||
#else
|
||||
#define D2I_X509_CONST
|
||||
#endif
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
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 */
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
|
||||
#include "credssp.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/utils/unicode.h>
|
||||
#include <freerdp/utils/datablob.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "tls.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/types/base.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user