Added context-specific error management.

Added error codes to replace connectErrorCode.
This commit is contained in:
Benoît LeBlanc 2014-03-20 18:19:54 -04:00
parent 27c753f80c
commit d1b9565f51
10 changed files with 117 additions and 3 deletions

View File

@ -176,6 +176,29 @@ FREERDP_API extern int connectErrorCode;
#define INSUFFICIENTPRIVILEGESERROR ERRORSTART + 10
#define CANCELEDBYUSER ERRORSTART + 11
/**
* These error codes are used with rdp_context.LastError
*/
#define FREERDP_ERROR_SUCCESS 0x00000000
#define FREERDP_ERROR_ERRORSTART 0x00010000
#define FREERDP_ERROR_CANCELLED FREERDP_ERROR_ERRORSTART + 0x00000001
/* connect error codes */
#define FREERDP_ERROR_PRE_CONNECT_FAILED FREERDP_ERROR_ERRORSTART + 0x00001001
#define FREERDP_ERROR_UNDEFINED_CONNECT_ERROR FREERDP_ERROR_ERRORSTART + 0x00001002
#define FREERDP_ERROR_POST_CONNECT_FAILED FREERDP_ERROR_ERRORSTART + 0x00001003
#define FREERDP_ERROR_DNS_ERROR FREERDP_ERROR_ERRORSTART + 0x00001004
#define FREERDP_ERROR_DNS_NAME_NOT_FOUND FREERDP_ERROR_ERRORSTART + 0x00001005
#define FREERDP_ERROR_CONNECT_FAILED FREERDP_ERROR_ERRORSTART + 0x00001006
#define FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR FREERDP_ERROR_ERRORSTART + 0x00001007
#define FREERDP_ERROR_TLS_CONNECT_FAILED FREERDP_ERROR_ERRORSTART + 0x00001008
#define FREERDP_ERROR_AUTHENTICATION_FAILED FREERDP_ERROR_ERRORSTART + 0x00001009
#define FREERDP_ERROR_INSUFFICIENT_PRIVILEGES FREERDP_ERROR_ERRORSTART + 0x0000100A
#ifdef __cplusplus
}
#endif

View File

@ -85,7 +85,9 @@ struct rdp_context
This field is used only on the server side. */
ALIGN64 BOOL ServerMode; /**< (offset 2) true when context is in server mode */
UINT64 paddingA[16 - 3]; /* 3 */
ALIGN64 UINT32 LastError; /* 3 */
UINT64 paddingA[16 - 4]; /* 4 */
ALIGN64 int argc; /**< (offset 16)
Number of arguments given to the program at launch time.
@ -247,6 +249,9 @@ FREERDP_API void freerdp_free(freerdp* instance);
FREERDP_API BOOL freerdp_focus_required(freerdp* instance);
FREERDP_API UINT32 freerdp_get_last_error(rdpContext* context);
FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError);
#ifdef __cplusplus
}
#endif

View File

@ -268,6 +268,12 @@ BOOL rdp_client_connect(rdpRdp* rdp)
{
connectErrorCode = MCSCONNECTINITIALERROR;
}
if (!freerdp_get_last_error(rdp->context))
{
freerdp_set_last_error(rdp->context, FREERDP_ERROR_MCS_CONNECT_INITIAL_ERROR);
}
fprintf(stderr, "Error: unable to send MCS Connect Initial\n");
return FALSE;
}

View File

@ -65,6 +65,7 @@ BOOL freerdp_connect(freerdp* instance)
/* We always set the return code to 0 before we start the connect sequence*/
connectErrorCode = 0;
freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);
rdp = instance->context->rdp;
settings = instance->settings;
@ -87,6 +88,12 @@ BOOL freerdp_connect(freerdp* instance)
{
connectErrorCode = PREECONNECTERROR;
}
if (!freerdp_get_last_error(rdp->context))
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED);
}
fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__);
goto freerdp_connect_finally;
@ -124,6 +131,11 @@ BOOL freerdp_connect(freerdp* instance)
connectErrorCode = POSTCONNECTERROR;
}
if (!freerdp_get_last_error(rdp->context))
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED);
}
goto freerdp_connect_finally;
}
@ -177,6 +189,8 @@ BOOL freerdp_connect(freerdp* instance)
if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
{
connectErrorCode = INSUFFICIENTPRIVILEGESERROR;
freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);
}
if (!connectErrorCode)
@ -184,6 +198,16 @@ BOOL freerdp_connect(freerdp* instance)
connectErrorCode = UNDEFINEDCONNECTERROR;
}
if (!freerdp_get_last_error(rdp->context))
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_UNDEFINED_CONNECT_ERROR);
}
if (!freerdp_get_last_error(rdp->context))
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_UNDEFINED_CONNECT_ERROR);
}
SetEvent(rdp->transport->connectedEvent);
freerdp_connect_finally:
@ -496,3 +520,14 @@ void freerdp_free(freerdp* instance)
free(instance);
}
}
FREERDP_API UINT32 freerdp_get_last_error(rdpContext* context)
{
return context->LastError;
}
FREERDP_API void freerdp_set_last_error(rdpContext* context, UINT32 lastError)
{
fprintf(stderr, "freerdp_set_last_error 0x%x\n", lastError);
context->LastError = lastError;
}

View File

@ -142,6 +142,7 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel)
if (!proceed)
{
connectErrorCode = CANCELEDBYUSER;
freerdp_set_last_error(instance->context, FREERDP_ERROR_CANCELLED);
return 0;
}

View File

@ -120,6 +120,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc)
if (!proceed)
{
connectErrorCode = CANCELEDBYUSER;
freerdp_set_last_error(instance->context, FREERDP_ERROR_CANCELLED);
return 0;
}

View File

@ -154,9 +154,17 @@ BOOL rts_connect(rdpRpc* rpc)
http_response_print(http_response);
http_response_free(http_response);
if (!connectErrorCode && http_response->StatusCode == HTTP_STATUS_DENIED)
if (http_response->StatusCode == HTTP_STATUS_DENIED)
{
connectErrorCode = AUTHENTICATIONERROR;
if (!connectErrorCode)
{
connectErrorCode = AUTHENTICATIONERROR;
}
if (!freerdp_get_last_error(((freerdp*)(rpc->settings->instance))->context))
{
freerdp_set_last_error(((freerdp*)(rpc->settings->instance))->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
}
}
return FALSE;

View File

@ -153,6 +153,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp)
if (!proceed)
{
connectErrorCode = CANCELEDBYUSER;
freerdp_set_last_error(instance->context, FREERDP_ERROR_CANCELLED);
return 0;
}

View File

@ -244,6 +244,11 @@ BOOL transport_connect_tls(rdpTransport* transport)
if (!connectErrorCode)
connectErrorCode = TLSCONNECTERROR;
if (!freerdp_get_last_error(((freerdp*)(transport->settings->instance))->context))
{
freerdp_set_last_error(((freerdp*)(transport->settings->instance))->context, FREERDP_ERROR_TLS_CONNECT_FAILED);
}
tls_free(transport->TsgTls);
transport->TsgTls = NULL;
@ -273,6 +278,11 @@ BOOL transport_connect_tls(rdpTransport* transport)
if (!connectErrorCode)
connectErrorCode = TLSCONNECTERROR;
if (!freerdp_get_last_error(((freerdp*)(transport->settings->instance))->context))
{
freerdp_set_last_error(((freerdp*)(transport->settings->instance))->context, FREERDP_ERROR_TLS_CONNECT_FAILED);
}
tls_free(transport->TlsIn);
if (transport->TlsIn == transport->TlsOut)
@ -318,6 +328,11 @@ BOOL transport_connect_nla(rdpTransport* transport)
if (!connectErrorCode)
connectErrorCode = AUTHENTICATIONERROR;
if (!freerdp_get_last_error(instance->context))
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_AUTHENTICATION_FAILED);
}
fprintf(stderr, "Authentication failure, check credentials.\n"
"If credentials are valid, the NTLMSSP implementation may be to blame.\n");

View File

@ -696,6 +696,11 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int po
if (instance->VerifyX509Certificate)
{
status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, 0);
if (status < 0)
{
freerdp_set_last_error(instance->context, FREERDP_ERROR_CANCELLED);
}
}
fprintf(stderr, "VerifyX509Certificate: (length = %d) status: %d\n%s\n",
@ -787,8 +792,15 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int po
tls_print_certificate_name_mismatch_error(hostname, common_name, alt_names, alt_names_count);
if (instance->VerifyCertificate)
{
accept_certificate = instance->VerifyCertificate(instance, subject, issuer, fingerprint);
if (!accept_certificate)
{
freerdp_set_last_error(((freerdp*) tls->settings->instance)->context, FREERDP_ERROR_CANCELLED);
}
}
if (!accept_certificate)
{
/* user did not accept, abort and do not add entry in known_hosts file */
@ -807,8 +819,15 @@ BOOL tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int po
tls_print_certificate_error(hostname, fingerprint, tls->certificate_store->file);
if (instance->VerifyChangedCertificate)
{
accept_certificate = instance->VerifyChangedCertificate(instance, subject, issuer, fingerprint, "");
if (!accept_certificate)
{
freerdp_set_last_error(((freerdp*) tls->settings->instance)->context, FREERDP_ERROR_CANCELLED);
}
}
if (!accept_certificate)
{
/* user did not accept, abort and do not change known_hosts file */