libfreerdp-core: refactoring of licensing code, refactoring of connection sequence

This commit is contained in:
Marc-André Moreau 2011-07-17 23:16:31 -04:00
parent 3f9a8521b8
commit 1a2dc6f3d9
15 changed files with 294 additions and 102 deletions

2
.gitignore vendored
View File

@ -24,4 +24,4 @@ docs/api
*.so.*
*.dylib
cunit/test_freerdp
freerdp-ui/test/freerdp-test
client/test/freerdp-test

View File

@ -88,4 +88,5 @@ add_subdirectory(libfreerdp-gdi)
add_subdirectory(libfreerdp-chanman)
add_subdirectory(libfreerdp-core)
add_subdirectory(channels)
add_subdirectory(freerdp-ui)
add_subdirectory(client)

View File

@ -1,5 +1,5 @@
# FreeRDP: A Remote Desktop Protocol Client
# FreeRDP User Interfaces
# FreeRDP Client User Interfaces
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>

208
client/test/freerdp.c Normal file
View File

@ -0,0 +1,208 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Test UI
*
* Copyright 2010 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 <stdio.h>
#include <string.h>
#include "connection.h"
#include <freerdp/settings.h>
#include <freerdp/utils/memory.h>
#define PARAM_EQUALS(_param) (strcmp(_param, argv[*i]) == 0)
#define CHECK_VALUE_PRESENT(_msg) do { \
*i = *i + 1; \
if (*i == argc) \
{ printf(_msg "\n"); return False; } \
} while(0)
#define STRING_COPY(_str) do { \
settings->_str = (uint8*) xmalloc(strlen(argv[*i])); \
memcpy(settings->_str, argv[*i], strlen(argv[*i])); \
settings->_str[strlen(argv[*i])] = '\0'; \
} while(0)
boolean freerdp_process_params(int argc, char* argv[], rdpSettings* settings, int* i)
{
char* p;
if (argc < *i + 1)
{
if (*i == 1)
printf("no parameters specified.\n");
return False;
}
while (*i < argc)
{
if (PARAM_EQUALS("-a"))
{
CHECK_VALUE_PRESENT("missing server depth");
settings->color_depth = atoi(argv[*i]);
}
else if (strcmp("-u", argv[*i]) == 0)
{
CHECK_VALUE_PRESENT("missing username");
STRING_COPY(username);
}
else if (PARAM_EQUALS("-p"))
{
CHECK_VALUE_PRESENT("missing password");
STRING_COPY(password);
}
else if (PARAM_EQUALS("-d"))
{
CHECK_VALUE_PRESENT("missing domain");
STRING_COPY(domain);
}
else if (PARAM_EQUALS("-g"))
{
CHECK_VALUE_PRESENT("missing screen dimensions");
settings->width = strtol(argv[*i], &p, 10);
if (*p == 'x')
settings->height = strtol(p + 1, &p, 10);
if ((settings->width < 16) || (settings->height < 16) ||
(settings->width > 4096) || (settings->height > 4096))
{
printf("invalid screen dimensions\n");
return False;
}
}
else if (PARAM_EQUALS("-n"))
{
CHECK_VALUE_PRESENT("missing hostname");
STRING_COPY(hostname);
}
else if (PARAM_EQUALS("-o"))
{
settings->console_audio = True;
}
else if (PARAM_EQUALS("-0"))
{
settings->console_session = True;
}
else if (PARAM_EQUALS("-z"))
{
settings->compression = True;
}
else if (PARAM_EQUALS("--sec"))
{
CHECK_VALUE_PRESENT("missing protocol security");
if (PARAM_EQUALS("rdp")) /* Standard RDP */
{
settings->rdp_security = 1;
settings->tls_security = 0;
settings->nla_security = 0;
}
else if (PARAM_EQUALS("tls")) /* TLS */
{
settings->rdp_security = 0;
settings->tls_security = 1;
settings->nla_security = 0;
}
else if (PARAM_EQUALS("nla")) /* NLA */
{
settings->rdp_security = 0;
settings->tls_security = 0;
settings->nla_security = 1;
}
else
{
printf("unknown protocol security\n");
return False;
}
}
else if (PARAM_EQUALS("-h") || PARAM_EQUALS("--help"))
{
printf("help\n");
return False;
}
else if (argv[*i][0] != '-')
{
if (argv[*i][0] == '[' && (p = strchr(argv[*i], ']'))
&& (p[1] == 0 || (p[1] == ':' && !strchr(p + 2, ':'))))
{
/* Either "[...]" or "[...]:..." with at most one : after the brackets */
settings->hostname = (uint8*) xmalloc(strlen(argv[*i] + 1));
strncpy(settings->hostname, argv[*i] + 1, strlen(argv[*i] + 1));
if ((p = strchr(settings->hostname, ']')))
{
*p = 0;
if (p[1] == ':')
settings->port = (uint16) atoi(p + 2);
}
}
else
{
/* Port number is cut off and used if exactly one : in the string */
settings->hostname = (uint8*) xmalloc(strlen(argv[*i]));
strncpy(settings->hostname, argv[*i], strlen(argv[*i]));
if ((p = strchr(settings->hostname, ':')) && !strchr(p + 1, ':'))
{
*p = 0;
settings->port = (uint16) atoi(p + 1);
}
}
/*
* server hostname is the last argument for the current session.
* arguments followed will be parsed for the next session.
*/
*i = *i + 1;
return True;
}
*i = *i + 1;
}
return True;
}
int main(int argc, char* argv[])
{
rdpRdp* rdp;
int index = 1;
rdpSettings* settings;
rdp = rdp_new();
settings = rdp->settings;
if (freerdp_process_params(argc, argv, settings, &index) != True)
{
printf("failed to process parameters.\n");
return 0;
}
printf("hostname:%s username:%s password:%s\n",
settings->hostname, settings->username, settings->password);
rdp_client_connect(rdp);
return 0;
}

View File

@ -1,60 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* FreeRDP Test UI
*
* Copyright 2010 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 <stdio.h>
#include <string.h>
#include "connection.h"
#include <freerdp/settings.h>
#include <freerdp/utils/memory.h>
int main(int argc, char* argv[])
{
rdpRdp* rdp;
rdpSettings* settings;
rdp = rdp_new();
settings = rdp->settings;
if (argc < 4)
{
printf("Usage: freerdp-test <hostname> <username>\n");
return 0;
}
settings->hostname = (uint8*) xmalloc(strlen(argv[1]));
memcpy(settings->hostname, argv[1], strlen(argv[1]));
settings->hostname[strlen(argv[1])] = '\0';
settings->username = (uint8*) xmalloc(strlen(argv[2]));
memcpy(settings->username, argv[2], strlen(argv[2]));
settings->username[strlen(argv[2])] = '\0';
settings->password = (uint8*) xmalloc(strlen(argv[3]));
memcpy(settings->password, argv[3], strlen(argv[3]));
settings->password[strlen(argv[3])] = '\0';
printf("hostname: %s username: %s password: %s\n",
settings->hostname, settings->username, settings->password);
rdp_client_connect(rdp);
return 0;
}

View File

@ -20,28 +20,6 @@
#ifndef __FREERDP_CONSTANTS
#define __FREERDP_CONSTANTS
/**
* Protocol Security Negotiation Protocols
*/
enum RDP_NEG_PROTOCOLS
{
PROTOCOL_RDP = 0x00000000,
PROTOCOL_TLS = 0x00000001,
PROTOCOL_NLA = 0x00000002
};
/**
* Protocol Security Negotiation Failure Codes
*/
enum RDP_NEG_FAILURE_FAILURECODES
{
SSL_REQUIRED_BY_SERVER = 0x00000001,
SSL_NOT_ALLOWED_BY_SERVER = 0x00000002,
SSL_CERT_NOT_ON_SERVER = 0x00000003,
INCONSISTENT_FLAGS = 0x00000004,
HYBRID_REQUIRED_BY_SERVER = 0x00000005
};
/**
* Static Virtual Channel Flags
*/

View File

@ -118,6 +118,7 @@ struct rdp_settings
BLOB server_random;
BLOB server_certificate;
boolean console_audio;
boolean console_session;
uint32 redirected_session_id;
@ -164,7 +165,6 @@ struct rdp_settings
int bitmap_compression;
int desktop_save;
int polygon_ellipse_orders;
int console_audio;
int off_screen_bitmaps;
int triblt;
int new_cursors;

View File

@ -55,7 +55,7 @@
* @param rdp RDP module
*/
void rdp_client_connect(rdpRdp* rdp)
boolean rdp_client_connect(rdpRdp* rdp)
{
rdp->settings->autologon = 1;
@ -63,18 +63,26 @@ void rdp_client_connect(rdpRdp* rdp)
nego_set_target(rdp->nego, rdp->settings->hostname, 3389);
nego_set_cookie(rdp->nego, rdp->settings->username);
nego_set_protocols(rdp->nego, 1, 1, 1);
nego_connect(rdp->nego);
transport_connect_nla(rdp->transport);
if (nego_connect(rdp->nego) == False)
{
printf("Error: protocol security negotiation failure\n");
return False;
}
if (rdp->nego->selected_protocol & PROTOCOL_NLA)
transport_connect_nla(rdp->transport);
else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
transport_connect_tls(rdp->transport);
else if (rdp->nego->selected_protocol & PROTOCOL_RDP)
transport_connect_rdp(rdp->transport);
mcs_connect(rdp->mcs);
rdp_send_client_info(rdp);
rdp_recv(rdp);
rdp_recv(rdp);
rdp_recv(rdp);
rdp_recv(rdp);
rdp_recv(rdp);
license_connect(rdp->license);
return True;
}

View File

@ -30,6 +30,6 @@
#include <freerdp/settings.h>
#include <freerdp/utils/memory.h>
void rdp_client_connect(rdpRdp* rdp);
boolean rdp_client_connect(rdpRdp* rdp);
#endif /* __CONNECTION_H */

View File

@ -45,6 +45,33 @@ uint8 state_transitions[][32] =
"ST_RESEND_LAST_MESSAGE"
};
/**
* Perform licensing phase of connection sequence.\n
* @param license license module
* @return
*/
boolean license_connect(rdpLicense* license)
{
while (1)
{
rdp_recv(license->rdp);
if (license->state == LICENSE_STATE_COMPLETED)
{
printf("license connection sequence completed.\n");
return True;
}
else if (license->state == LICENSE_STATE_ABORTED)
{
printf("license connection sequence aborted.\n");
return False;
}
}
return False;
}
/**
* Read a licensing preamble.\n
* @msdn{cc240480}

View File

@ -156,6 +156,8 @@ struct rdp_license
SCOPE_LIST* scope_list;
};
boolean license_connect(rdpLicense* license);
void license_send(rdpLicense* license, STREAM* s, uint8 type);
void license_recv(rdpLicense* license, STREAM* s);
STREAM* license_send_stream_init(rdpLicense* license);

View File

@ -50,7 +50,7 @@ char PROTOCOL_SECURITY_STRINGS[3][4] =
* @return
*/
int nego_connect(rdpNego* nego)
boolean nego_connect(rdpNego* nego)
{
if (nego->state == NEGO_STATE_INITIAL)
{
@ -74,7 +74,7 @@ int nego_connect(rdpNego* nego)
{
DEBUG_NEGO("Protocol Security Negotiation Failure");
nego->state = NEGO_STATE_FINAL;
return 0;
return False;
}
}
while (nego->state != NEGO_STATE_FINAL);
@ -84,7 +84,7 @@ int nego_connect(rdpNego* nego)
/* update settings with negotiated protocol security */
nego->transport->settings->selected_protocol = nego->selected_protocol;
return 1;
return True;
}
/**

View File

@ -26,6 +26,24 @@
#include <freerdp/utils/debug.h>
#include <freerdp/utils/stream.h>
/* Protocol Security Negotiation Protocols */
enum RDP_NEG_PROTOCOLS
{
PROTOCOL_RDP = 0x00000000,
PROTOCOL_TLS = 0x00000001,
PROTOCOL_NLA = 0x00000002
};
/* Protocol Security Negotiation Failure Codes */
enum RDP_NEG_FAILURE_FAILURECODES
{
SSL_REQUIRED_BY_SERVER = 0x00000001,
SSL_NOT_ALLOWED_BY_SERVER = 0x00000002,
SSL_CERT_NOT_ON_SERVER = 0x00000003,
INCONSISTENT_FLAGS = 0x00000004,
HYBRID_REQUIRED_BY_SERVER = 0x00000005
};
enum _NEGO_STATE
{
NEGO_STATE_INITIAL,
@ -65,7 +83,7 @@ struct rdp_nego
};
typedef struct rdp_nego rdpNego;
int nego_connect(rdpNego* nego);
boolean nego_connect(rdpNego* nego);
void nego_attempt_nla(rdpNego* nego);
void nego_attempt_tls(rdpNego* nego);

View File

@ -40,12 +40,22 @@ boolean tls_connect(rdpTls* tls)
return False;
}
do
while (1)
{
/* SSL_WANT_READ errors are normal, just try again if it happens */
connection_status = SSL_connect(tls->ssl);
/*
* SSL_WANT_READ and SSL_WANT_WRITE errors are normal,
* just try again if it happens
*/
if (connection_status == SSL_ERROR_WANT_READ)
continue;
else if (connection_status == SSL_ERROR_WANT_WRITE)
continue;
else
break;
}
while (SSL_get_error(tls->ssl, connection_status) == SSL_ERROR_WANT_READ);
if (connection_status < 0)
{