libfreerdp-core: sending of client info packet

This commit is contained in:
Marc-André Moreau 2011-07-10 12:10:24 -04:00
parent 841800a451
commit a0ff7ce581
11 changed files with 492 additions and 61 deletions

View File

@ -25,27 +25,13 @@
#include <freerdp/settings.h> #include <freerdp/settings.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
rdpMcs* mcs;
rdpNego* nego;
rdpSettings* settings;
rdpTransport* transport;
rdpConnection* connection;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int i; rdpSettings* settings;
char* username; rdpConnection* connection;
char* hostname;
char* password;
uint16 channelId;
settings = settings_new(); settings = settings_new();
transport = transport_new(settings); connection = connection_new(settings);
nego = nego_new(transport);
connection = connection_new();
connection->nego = nego;
connection->settings = settings;
connection->transport = transport;
if (argc < 4) if (argc < 4)
{ {
@ -53,25 +39,20 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
hostname = (char*) xmalloc(strlen(argv[1])); settings->hostname = (uint8*) xmalloc(strlen(argv[1]));
memcpy(hostname, argv[1], strlen(argv[1])); memcpy(settings->hostname, argv[1], strlen(argv[1]));
hostname[strlen(argv[1])] = '\0'; settings->hostname[strlen(argv[1])] = '\0';
username = (char*) xmalloc(strlen(argv[2])); settings->username = (uint8*) xmalloc(strlen(argv[2]));
memcpy(username, argv[2], strlen(argv[2])); memcpy(settings->username, argv[2], strlen(argv[2]));
username[strlen(argv[2])] = '\0'; settings->username[strlen(argv[2])] = '\0';
password = (char*) xmalloc(strlen(argv[3])); settings->password = (uint8*) xmalloc(strlen(argv[3]));
memcpy(password, argv[3], strlen(argv[3])); memcpy(settings->password, argv[3], strlen(argv[3]));
password[strlen(argv[3])] = '\0'; settings->password[strlen(argv[3])] = '\0';
printf("hostname: %s username: %s password: %s\n", printf("hostname: %s username: %s password: %s\n",
hostname, username, password); settings->hostname, settings->username, settings->password);
settings->hostname = hostname;
settings->username = username;
settings->password = password;
settings->domain = NULL;
connection_client_connect(connection); connection_client_connect(connection);

View File

@ -41,6 +41,43 @@
#define ENCRYPTION_56BIT_FLAG 0x00000008 #define ENCRYPTION_56BIT_FLAG 0x00000008
#define ENCRYPTION_FIPS_FLAG 0x00000010 #define ENCRYPTION_FIPS_FLAG 0x00000010
/* Auto Reconnect Version */
#define AUTO_RECONNECT_VERSION_1 0x00000001
/* SYSTEM_TIME */
typedef struct
{
uint16 wYear;
uint16 wMonth;
uint16 wDayOfWeek;
uint16 wDay;
uint16 wHour;
uint16 wMinute;
uint16 wSecond;
uint16 wMilliseconds;
} SYSTEM_TIME;
/* TIME_ZONE_INFORMATION */
typedef struct
{
uint32 bias;
uint8 standardName[32];
SYSTEM_TIME standardDate;
uint32 standardBias;
uint8 daylightName[32];
SYSTEM_TIME daylightDate;
uint32 daylightBias;
} TIME_ZONE_INFORMATION;
/* ARC_CS_PRIVATE_PACKET */
typedef struct
{
uint32 cbLen;
uint32 version;
uint32 logonId;
uint8 securityVerifier[16];
} ARC_CS_PRIVATE_PACKET;
struct rdp_chan struct rdp_chan
{ {
char name[8]; /* ui sets */ char name[8]; /* ui sets */
@ -81,7 +118,7 @@ struct rdp_settings
BLOB server_random; BLOB server_random;
BLOB server_certificate; BLOB server_certificate;
int console_session; boolean console_session;
uint32 redirected_session_id; uint32 redirected_session_id;
int num_channels; int num_channels;
@ -90,24 +127,34 @@ struct rdp_settings
int num_monitors; int num_monitors;
struct rdp_monitor monitors[16]; struct rdp_monitor monitors[16];
struct rdp_ext_set extensions[16];
UNICONV* uniconv; UNICONV* uniconv;
char client_hostname[32]; char client_hostname[32];
char client_product_id[32]; char client_product_id[32];
char* hostname; uint16 port;
char* username; uint8* hostname;
char* password; uint8* username;
char* domain; uint8* password;
uint8* domain;
uint8* shell;
uint8* directory;
uint32 performance_flags;
char shell[256]; boolean autologon;
char directory[256]; boolean compression;
int performance_flags;
int tcp_port_rdp;
int encryption; boolean ipv6;
int tls_security; uint8* ip_address;
int nla_security; uint8* client_dir;
int rdp_security; TIME_ZONE_INFORMATION client_time_zone;
ARC_CS_PRIVATE_PACKET auto_reconnect_cookie;
boolean encryption;
boolean tls_security;
boolean nla_security;
boolean rdp_security;
int remote_app; int remote_app;
char app_name[64]; char app_name[64];
@ -117,18 +164,15 @@ struct rdp_settings
int bitmap_compression; int bitmap_compression;
int desktop_save; int desktop_save;
int polygon_ellipse_orders; int polygon_ellipse_orders;
int autologin;
int console_audio; int console_audio;
int off_screen_bitmaps; int off_screen_bitmaps;
int triblt; int triblt;
int new_cursors; int new_cursors;
int mouse_motion; int mouse_motion;
int bulk_compression;
int rfx_flags; int rfx_flags;
int ui_decode_flags; int ui_decode_flags;
int use_frame_ack; int use_frame_ack;
int software_gdi; int software_gdi;
struct rdp_ext_set extensions[16];
}; };
typedef struct rdp_settings rdpSettings; typedef struct rdp_settings rdpSettings;

View File

@ -42,6 +42,9 @@ void connection_client_connect(rdpConnection* connection)
int i; int i;
uint16 channelId; uint16 channelId;
connection->transport = transport_new(connection->settings);
connection->nego = nego_new(connection->transport);
nego_init(connection->nego); nego_init(connection->nego);
nego_set_target(connection->nego, connection->settings->hostname, 3389); nego_set_target(connection->nego, connection->settings->hostname, 3389);
nego_set_cookie(connection->nego, connection->settings->username); nego_set_cookie(connection->nego, connection->settings->username);
@ -69,15 +72,291 @@ void connection_client_connect(rdpConnection* connection)
mcs_recv_channel_join_confirm(connection->mcs); mcs_recv_channel_join_confirm(connection->mcs);
} }
connection_send_client_info(connection);
mcs_recv(connection->mcs); mcs_recv(connection->mcs);
} }
void connection_write_system_time(STREAM* s, SYSTEM_TIME* system_time)
{
stream_write_uint16(s, system_time->wYear); /* wYear, must be set to 0 */
stream_write_uint16(s, system_time->wMonth); /* wMonth */
stream_write_uint16(s, system_time->wDayOfWeek); /* wDayOfWeek */
stream_write_uint16(s, system_time->wDay); /* wDay */
stream_write_uint16(s, system_time->wHour); /* wHour */
stream_write_uint16(s, system_time->wMinute); /* wMinute */
stream_write_uint16(s, system_time->wSecond); /* wSecond */
stream_write_uint16(s, system_time->wMilliseconds); /* wMilliseconds */
}
void connection_get_client_time_zone(STREAM* s, rdpSettings* settings)
{
time_t t;
struct tm* local_time;
TIME_ZONE_INFORMATION* clientTimeZone;
time(&t);
local_time = localtime(&t);
clientTimeZone = &settings->client_time_zone;
#if defined(sun)
if(local_time->tm_isdst > 0)
clientTimeZone->bias = (uint32) (altzone / 3600);
else
clientTimeZone->bias = (uint32) (timezone / 3600);
#elif defined(HAVE_TM_GMTOFF)
if(local_time->tm_gmtoff >= 0)
clientTimeZone->bias = (uint32) (local_time->tm_gmtoff / 60);
else
clientTimeZone->bias = (uint32) ((-1 * local_time->tm_gmtoff) / 60 + 720);
#else
clientTimeZone->bias = 0;
#endif
if(local_time->tm_isdst > 0)
{
clientTimeZone->standardBias = clientTimeZone->bias - 60;
clientTimeZone->daylightBias = clientTimeZone->bias;
}
else
{
clientTimeZone->standardBias = clientTimeZone->bias;
clientTimeZone->daylightBias = clientTimeZone->bias + 60;
}
strftime(clientTimeZone->standardName, 32, "%Z, Standard Time", local_time);
clientTimeZone->standardName[31] = 0;
strftime(clientTimeZone->daylightName, 32, "%Z, Summer Time", local_time);
clientTimeZone->daylightName[31] = 0;
}
void connection_write_client_time_zone(STREAM* s, rdpSettings* settings)
{
size_t length;
uint8* standardName;
uint8* daylightName;
size_t standardNameLength;
size_t daylightNameLength;
TIME_ZONE_INFORMATION* clientTimeZone;
connection_get_client_time_zone(s, settings);
clientTimeZone = &settings->client_time_zone;
standardName = freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length);
standardNameLength = length;
daylightName = freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length);
daylightNameLength = length;
if (standardNameLength > 62)
standardNameLength = 62;
if (daylightNameLength > 62)
daylightNameLength = 62;
stream_write_uint32(s, clientTimeZone->bias); /* Bias */
/* standardName (64 bytes) */
stream_write(s, standardName, standardNameLength);
stream_write_zero(s, 64 - standardNameLength);
connection_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */
stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */
/* daylightName (64 bytes) */
stream_write(s, daylightName, daylightNameLength);
stream_write_zero(s, 64 - daylightNameLength);
connection_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */
stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */
xfree(standardName);
xfree(daylightName);
}
void connection_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings)
{
ARC_CS_PRIVATE_PACKET* autoReconnectCookie;
autoReconnectCookie = &settings->auto_reconnect_cookie;
stream_write_uint32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
stream_write_uint32(s, autoReconnectCookie->version); /* version (4 bytes) */
stream_write_uint32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
stream_write(s, autoReconnectCookie->securityVerifier, 16); /* SecurityVerifier */
}
void connection_write_extended_info_packet(STREAM* s, rdpSettings* settings)
{
size_t length;
uint16 clientAddressFamily;
uint8* clientAddress;
uint16 cbClientAddress;
uint8* clientDir;
uint16 cbClientDir;
uint16 cbAutoReconnectLen;
clientAddressFamily = settings->ipv6 ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET;
clientAddress = freerdp_uniconv_out(settings->uniconv, settings->ip_address, &length);
cbClientAddress = length;
clientDir = freerdp_uniconv_out(settings->uniconv, settings->client_dir, &length);
cbClientDir = length;
cbAutoReconnectLen = settings->auto_reconnect_cookie.cbLen;
stream_write_uint16(s, clientAddressFamily); /* clientAddressFamily */
stream_write_uint16(s, cbClientAddress + 2); /* cbClientAddress */
if (cbClientAddress > 0)
stream_write(s, clientAddress, cbClientAddress); /* clientAddress */
stream_write_uint16(s, 0);
stream_write_uint16(s, cbClientDir + 2); /* cbClientDir */
if (cbClientDir > 0)
stream_write(s, clientDir, cbClientDir); /* clientDir */
stream_write_uint16(s, 0);
connection_write_client_time_zone(s, settings); /* clientTimeZone */
stream_write_uint32(s, 0); /* clientSessionId, should be set to 0 */
stream_write_uint32(s, settings->performance_flags); /* performanceFlags */
stream_write_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */
if (cbAutoReconnectLen > 0)
connection_write_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */
/* reserved1 (2 bytes) */
/* reserved2 (2 bytes) */
xfree(clientAddress);
xfree(clientDir);
}
void connection_write_info_packet(STREAM* s, rdpSettings* settings)
{
size_t length;
uint32 flags;
uint8* domain;
uint16 cbDomain;
uint8* userName;
uint16 cbUserName;
uint8* password;
uint16 cbPassword;
uint8* alternateShell;
uint16 cbAlternateShell;
uint8* workingDir;
uint16 cbWorkingDir;
flags = INFO_UNICODE |
INFO_LOGONERRORS |
INFO_LOGONNOTIFY |
INFO_ENABLEWINDOWSKEY |
RNS_INFO_AUDIOCAPTURE;
if (settings->autologon)
flags |= INFO_AUTOLOGON;
if (settings->compression)
flags |= INFO_COMPRESSION | PACKET_COMPR_TYPE_64K;
domain = freerdp_uniconv_out(settings->uniconv, settings->domain, &length);
cbDomain = length;
userName = freerdp_uniconv_out(settings->uniconv, settings->username, &length);
cbUserName = length;
password = freerdp_uniconv_out(settings->uniconv, settings->password, &length);
cbPassword = length;
alternateShell = freerdp_uniconv_out(settings->uniconv, settings->shell, &length);
cbAlternateShell = length;
workingDir = freerdp_uniconv_out(settings->uniconv, settings->directory, &length);
cbWorkingDir = length;
stream_write_uint32(s, 0); /* CodePage */
stream_write_uint32(s, flags); /* flags */
stream_write_uint16(s, cbDomain); /* cbDomain */
stream_write_uint16(s, cbUserName); /* cbUserName */
stream_write_uint16(s, cbPassword); /* cbPassword */
stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */
stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */
if (cbDomain > 0)
stream_write(s, domain, cbDomain);
stream_write_uint16(s, 0);
if (cbUserName > 0)
stream_write(s, userName, cbUserName);
stream_write_uint16(s, 0);
if (cbPassword > 0)
stream_write(s, password, cbPassword);
stream_write_uint16(s, 0);
if (cbAlternateShell > 0)
stream_write(s, alternateShell, cbAlternateShell);
stream_write_uint16(s, 0);
if (cbWorkingDir > 0)
stream_write(s, workingDir, cbWorkingDir);
stream_write_uint16(s, 0);
xfree(domain);
xfree(userName);
xfree(password);
xfree(alternateShell);
xfree(workingDir);
if (settings->rdp_version >= 5)
connection_write_extended_info_packet(s, settings); /* extraInfo */
}
void connection_send_client_info(rdpConnection* connection)
{
STREAM* s;
int length;
s = stream_new(1024);
uint8 *bm, *em;
stream_get_mark(s, bm);
stream_seek(s, 15);
/* security header */
stream_write_uint16(s, SEC_INFO_PKT); /* flags */
stream_write_uint16(s, 0); /* flagsHi */
connection_write_info_packet(s, connection->settings);
stream_get_mark(s, em);
length = (em - bm);
stream_set_mark(s, bm);
tpkt_write_header(s, length);
tpdu_write_data(s);
per_write_choice(s, DomainMCSPDU_SendDataRequest << 2);
per_write_integer16(s, connection->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0); /* channelId */
stream_write_uint8(s, 0x70); /* dataPriority + segmentation */
per_write_length(s, length - 15); /* userData (OCTET_STRING) */
stream_set_mark(s, em);
tls_write(connection->transport->tls, s->data, stream_get_length(s));
}
/** /**
* Instantiate new connection module. * Instantiate new connection module.
* @return new connection module * @return new connection module
*/ */
rdpConnection* connection_new() rdpConnection* connection_new(rdpSettings* settings)
{ {
rdpConnection* connection; rdpConnection* connection;
@ -85,7 +364,7 @@ rdpConnection* connection_new()
if (connection != NULL) if (connection != NULL)
{ {
connection->settings = settings;
} }
return connection; return connection;

View File

@ -21,6 +21,7 @@
#define __CONNECTION_H #define __CONNECTION_H
#include "tpkt.h" #include "tpkt.h"
#include "tpdu.h"
#include "nego.h" #include "nego.h"
#include "mcs.h" #include "mcs.h"
#include "transport.h" #include "transport.h"
@ -28,6 +29,48 @@
#include <freerdp/settings.h> #include <freerdp/settings.h>
#include <freerdp/utils/memory.h> #include <freerdp/utils/memory.h>
/* Client Address Family */
#define ADDRESS_FAMILY_INET 0x0002
#define ADDRESS_FAMILY_INET6 0x0017
/* Client Info Packet Flags */
#define INFO_MOUSE 0x00000001
#define INFO_DISABLECTRLALTDEL 0x00000002
#define INFO_AUTOLOGON 0x00000008
#define INFO_UNICODE 0x00000010
#define INFO_MAXIMIZESHELL 0x00000020
#define INFO_LOGONNOTIFY 0x00000040
#define INFO_COMPRESSION 0x00000080
#define INFO_ENABLEWINDOWSKEY 0x00000100
#define INFO_REMOTECONSOLEAUDIO 0x00002000
#define INFO_FORCE_ENCRYPTED_CS_PDU 0x00004000
#define INFO_RAIL 0x00008000
#define INFO_LOGONERRORS 0x00010000
#define INFO_MOUSE_HAS_WHEEL 0x00020000
#define INFO_PASSWORD_IS_SC_PIN 0x00040000
#define INFO_NOAUDIOPLAYBACK 0x00080000
#define INFO_USING_SAVED_CREDS 0x00100000
#define RNS_INFO_AUDIOCAPTURE 0x00200000
#define RNS_INFO_VIDEO_DISABLE 0x00400000
#define CompressionTypeMask 0x00001E00
#define PACKET_COMPR_TYPE_8K 0x00000100
#define PACKET_COMPR_TYPE_64K 0x00000200
#define PACKET_COMPR_TYPE_RDP6 0x00000300
#define PACKET_COMPR_TYPE_RDP61 0x00000400
/* Security Header Flags */
#define SEC_EXCHANGE_PKT 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_RESET_SEQNO 0x0010
#define SEC_IGNORE_SEQNO 0x0020
#define SEC_INFO_PKT 0x0040
#define SEC_LICENSE_PKT 0x0080
#define SEC_LICENSE_ENCRYPT_CS 0x0200
#define SEC_LICENSE_ENCRYPT_SC 0x0200
#define SEC_REDIRECTION_PKT 0x0400
#define SEC_SECURE_CHECKSUM 0x0800
#define SEC_FLAGSHI_VALID 0x8000
struct rdp_connection struct rdp_connection
{ {
struct rdp_mcs* mcs; struct rdp_mcs* mcs;
@ -38,8 +81,17 @@ struct rdp_connection
typedef struct rdp_connection rdpConnection; typedef struct rdp_connection rdpConnection;
void connection_client_connect(rdpConnection* connection); void connection_client_connect(rdpConnection* connection);
void connection_send_client_info(rdpConnection* connection);
rdpConnection* connection_new(); void connection_write_system_time(STREAM* s, SYSTEM_TIME* system_time);
void connection_get_client_time_zone(STREAM* s, rdpSettings* settings);
void connection_write_client_time_zone(STREAM* s, rdpSettings* settings);
void connection_write_info_packet(STREAM* s, rdpSettings* settings);
void connection_write_extended_info_packet(STREAM* s, rdpSettings* settings);
void connection_write_auto_reconnect_cookie(STREAM* s, rdpSettings* settings);
rdpConnection* connection_new(rdpSettings* settings);
void connection_free(rdpConnection* connection); void connection_free(rdpConnection* connection);
#endif /* __CONNECTION_H */ #endif /* __CONNECTION_H */

View File

@ -110,6 +110,30 @@
* channelId ChannelId OPTIONAL * channelId ChannelId OPTIONAL
* } * }
* *
* SendDataRequest ::= [APPLICATION 25] IMPLICIT SEQUENCE
* {
* initiator UserId,
* channelId ChannelId,
* dataPriority DataPriority,
* segmentation Segmentation,
* userData OCTET_STRING
* }
*
* DataPriority ::= CHOICE
* {
* top NULL,
* high NULL,
* medium NULL,
* low NULL,
* ...
* }
*
* Segmentation ::= BIT_STRING
* {
* begin (0),
* end (1)
* } (SIZE(2))
*
*/ */
uint8 callingDomainSelector[1] = "\x01"; uint8 callingDomainSelector[1] = "\x01";
@ -289,7 +313,7 @@ void mcs_send_connect_initial(rdpMcs* mcs)
stream_set_mark(s, bm); stream_set_mark(s, bm);
tpkt_write_header(s, length); tpkt_write_header(s, length);
tpdu_write_data(s, length - 5); tpdu_write_data(s);
stream_set_mark(s, em); stream_set_mark(s, em);
tls_write(mcs->transport->tls, s->data, stream_get_length(s)); tls_write(mcs->transport->tls, s->data, stream_get_length(s));
@ -326,7 +350,7 @@ void mcs_send_erect_domain_request(rdpMcs* mcs)
s = stream_new(length); s = stream_new(length);
tpkt_write_header(s, length); tpkt_write_header(s, length);
tpdu_write_data(s, length - 5); tpdu_write_data(s);
/* DomainMCSPDU, ErectDomainRequest */ /* DomainMCSPDU, ErectDomainRequest */
per_write_choice(s, DomainMCSPDU_ErectDomainRequest << 2); per_write_choice(s, DomainMCSPDU_ErectDomainRequest << 2);
@ -343,7 +367,7 @@ void mcs_send_attach_user_request(rdpMcs* mcs)
s = stream_new(length); s = stream_new(length);
tpkt_write_header(s, length); tpkt_write_header(s, length);
tpdu_write_data(s, length - 5); tpdu_write_data(s);
/* DomainMCSPDU, AttachUserRequest */ /* DomainMCSPDU, AttachUserRequest */
per_write_choice(s, DomainMCSPDU_AttachUserRequest << 2); per_write_choice(s, DomainMCSPDU_AttachUserRequest << 2);
@ -376,7 +400,7 @@ void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id)
s = stream_new(length); s = stream_new(length);
tpkt_write_header(s, length); tpkt_write_header(s, length);
tpdu_write_data(s, length - 5); tpdu_write_data(s);
/* DomainMCSPDU, ChannelJoinRequest*/ /* DomainMCSPDU, ChannelJoinRequest*/
per_write_choice(s, DomainMCSPDU_ChannelJoinRequest << 2); per_write_choice(s, DomainMCSPDU_ChannelJoinRequest << 2);

View File

@ -27,6 +27,7 @@
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
#define MCS_BASE_CHANNEL_ID 1001 #define MCS_BASE_CHANNEL_ID 1001
#define MCS_GLOBAL_CHANNEL_ID 1003
enum MCS_Result enum MCS_Result
{ {

View File

@ -21,6 +21,8 @@
#include <freerdp/settings.h> #include <freerdp/settings.h>
static char client_dll[] = "C:\\Windows\\System32\\mstscax.dll";
rdpSettings* settings_new() rdpSettings* settings_new()
{ {
rdpSettings* settings; rdpSettings* settings;
@ -52,6 +54,9 @@ rdpSettings* settings_new()
ENCRYPTION_40BIT_FLAG | ENCRYPTION_40BIT_FLAG |
ENCRYPTION_128BIT_FLAG; ENCRYPTION_128BIT_FLAG;
settings->client_dir = xmalloc(strlen(client_dll));
strcpy(settings->client_dir, client_dll);
settings->uniconv = freerdp_uniconv_new(); settings->uniconv = freerdp_uniconv_new();
gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1); gethostname(settings->client_hostname, sizeof(settings->client_hostname) - 1);
} }

View File

@ -32,6 +32,30 @@
#include "tcp.h" #include "tcp.h"
static void tcp_get_ip_address(rdpTcp * tcp)
{
uint8* ip;
socklen_t length;
struct sockaddr_in sockaddr;
length = sizeof(sockaddr);
if (getsockname(tcp->sockfd, (struct sockaddr*) &sockaddr, &length) == 0)
{
ip = (uint8*) (&sockaddr.sin_addr);
snprintf(tcp->ip_address, sizeof(tcp->ip_address),
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
else
strncpy(tcp->ip_address, "127.0.0.1", sizeof(tcp->ip_address));
tcp->ip_address[sizeof(tcp->ip_address) - 1] = 0;
tcp->settings->ipv6 = 0;
tcp->settings->ip_address = tcp->ip_address;
}
boolean tcp_connect(rdpTcp* tcp, const char* hostname, int port) boolean tcp_connect(rdpTcp* tcp, const char* hostname, int port)
{ {
int status; int status;
@ -76,6 +100,7 @@ boolean tcp_connect(rdpTcp* tcp, const char* hostname, int port)
} }
tcp->sockfd = sockfd; tcp->sockfd = sockfd;
tcp_get_ip_address(tcp);
return True; return True;
} }
@ -116,13 +141,14 @@ boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking)
return True; return True;
} }
rdpTcp* tcp_new() rdpTcp* tcp_new(rdpSettings* settings)
{ {
rdpTcp* tcp = (rdpTcp*) xzalloc(sizeof(rdpTcp)); rdpTcp* tcp = (rdpTcp*) xzalloc(sizeof(rdpTcp));
if (tcp != NULL) if (tcp != NULL)
{ {
tcp->sockfd = -1; tcp->sockfd = -1;
tcp->settings = settings;
tcp->connect = tcp_connect; tcp->connect = tcp_connect;
tcp->disconnect = tcp_disconnect; tcp->disconnect = tcp_disconnect;
tcp->set_blocking_mode = tcp_set_blocking_mode; tcp->set_blocking_mode = tcp_set_blocking_mode;

View File

@ -22,6 +22,7 @@
#define __TCP_H #define __TCP_H
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/settings.h>
#include <freerdp/utils/stream.h> #include <freerdp/utils/stream.h>
typedef struct rdp_tcp rdpTcp; typedef struct rdp_tcp rdpTcp;
@ -32,6 +33,8 @@ typedef boolean (*TcpSetBlockingMode) (rdpTcp* tcp, boolean blocking);
struct rdp_tcp struct rdp_tcp
{ {
int sockfd; int sockfd;
uint8 ip_address[32];
struct rdp_settings* settings;
TcpConnect connect; TcpConnect connect;
TcpDisconnect disconnect; TcpDisconnect disconnect;
TcpSetBlockingMode set_blocking_mode; TcpSetBlockingMode set_blocking_mode;
@ -41,7 +44,7 @@ boolean tcp_connect(rdpTcp* tcp, const char* hostname, int port);
boolean tcp_disconnect(rdpTcp* tcp); boolean tcp_disconnect(rdpTcp* tcp);
boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking); boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking);
rdpTcp* tcp_new(); rdpTcp* tcp_new(rdpSettings* settings);
void tcp_free(rdpTcp* tcp); void tcp_free(rdpTcp* tcp);
#endif /* __TCP_H */ #endif /* __TCP_H */

View File

@ -271,7 +271,7 @@ rdpTransport* transport_new(rdpSettings* settings)
if (transport != NULL) if (transport != NULL)
{ {
transport->tcp = tcp_new(); transport->tcp = tcp_new(settings);
transport->settings = settings; transport->settings = settings;
/* a small 0.1ms delay when transport is blocking. */ /* a small 0.1ms delay when transport is blocking. */

View File

@ -70,8 +70,23 @@ char* freerdp_uniconv_in(UNICONV *uniconv, unsigned char* pin, size_t in_len)
char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len) char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len)
{ {
size_t ibl = strlen(str), obl = 2 * ibl; /* FIXME: worst case */ size_t ibl;
char *pin = str, *pout0 = xmalloc(obl + 2), *pout = pout0; size_t obl;
char* pin;
char* pout;
char* pout0;
if (str == NULL)
{
*pout_len = 0;
return NULL;
}
ibl = strlen(str);
obl = 2 * ibl;
pin = str;
pout0 = xmalloc(obl + 2);
pout = pout0;
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
if (iconv(uniconv->out_iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) if (iconv(uniconv->out_iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
@ -101,6 +116,7 @@ char* freerdp_uniconv_out(UNICONV *uniconv, char *str, size_t *pout_len)
*pout_len = pout - pout0; *pout_len = pout - pout0;
*pout++ = 0; /* Add extra double zero termination */ *pout++ = 0; /* Add extra double zero termination */
*pout = 0; *pout = 0;
return pout0; return pout0;
} }