mirror of
https://github.com/curl/curl.git
synced 2025-03-19 15:40:42 +08:00
sspi: Refactored socks_sspi and schannel to use same error message functions
Moved the error constant switch to curl_sspi.c and added two new helper functions to curl_sspi.[ch] which either return the constant or a fully translated message representing the SSPI security status. Updated socks_sspi.c and curl_schannel.c to use the new functions.
This commit is contained in:
parent
15ca80c831
commit
f858bb0d1f
@ -89,6 +89,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) {
|
||||
SCHANNEL_CRED schannel_cred;
|
||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||
curl_schannel_cred *old_cred = NULL;
|
||||
char *sspi_msg = NULL;
|
||||
struct in_addr addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
@ -156,11 +157,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) {
|
||||
&connssl->cred->cred_handle, &connssl->cred->time_stamp);
|
||||
|
||||
if(sspi_status != SEC_E_OK) {
|
||||
sspi_msg = Curl_sspi_status_msg(sspi_status);
|
||||
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
|
||||
failf(data, "schannel: SNI or certificate check failed\n");
|
||||
failf(data, "schannel: SNI or certificate check failed: %s\n",
|
||||
sspi_msg);
|
||||
else
|
||||
failf(data, "schannel: AcquireCredentialsHandleA failed: %d\n",
|
||||
sspi_status);
|
||||
failf(data, "schannel: AcquireCredentialsHandleA failed: %s\n",
|
||||
sspi_msg);
|
||||
free(sspi_msg);
|
||||
free(connssl->cred);
|
||||
connssl->cred = NULL;
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -196,11 +200,14 @@ schannel_connect_step1(struct connectdata *conn, int sockindex) {
|
||||
&outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
|
||||
|
||||
if(sspi_status != SEC_I_CONTINUE_NEEDED) {
|
||||
sspi_msg = Curl_sspi_status_msg(sspi_status);
|
||||
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
|
||||
failf(data, "schannel: SNI or certificate check failed\n");
|
||||
failf(data, "schannel: SNI or certificate check failed: %s\n",
|
||||
sspi_msg);
|
||||
else
|
||||
failf(data, "schannel: initial InitializeSecurityContextA failed: %d\n",
|
||||
sspi_status);
|
||||
failf(data, "schannel: initial InitializeSecurityContextA failed: %s\n",
|
||||
sspi_msg);
|
||||
free(sspi_msg);
|
||||
free(connssl->ctxt);
|
||||
connssl->ctxt = NULL;
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
@ -236,6 +243,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) {
|
||||
SecBuffer inbuf[2];
|
||||
SecBufferDesc inbuf_desc;
|
||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||
char *sspi_msg = NULL;
|
||||
|
||||
infof(data, "schannel: connecting to %s:%d (step 2/3)\n",
|
||||
conn->host.name, conn->remote_port);
|
||||
@ -320,8 +328,7 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) {
|
||||
/* check if the handshake was incomplete */
|
||||
if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
|
||||
connssl->connecting_state = ssl_connect_2_reading;
|
||||
infof(data, "schannel: received incomplete message, need more data: %d\n",
|
||||
sspi_status);
|
||||
infof(data, "schannel: received incomplete message, need more data\n");
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -350,11 +357,14 @@ schannel_connect_step2(struct connectdata *conn, int sockindex) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
sspi_msg = Curl_sspi_status_msg(sspi_status);
|
||||
if(sspi_status == SEC_E_WRONG_PRINCIPAL)
|
||||
failf(data, "schannel: SNI or certificate check failed\n");
|
||||
failf(data, "schannel: SNI or certificate check failed: %s\n",
|
||||
sspi_msg);
|
||||
else
|
||||
failf(data, "schannel: next InitializeSecurityContextA failed: %d\n",
|
||||
sspi_status);
|
||||
failf(data, "schannel: next InitializeSecurityContextA failed: %s\n",
|
||||
sspi_msg);
|
||||
free(sspi_msg);
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
@ -653,6 +663,7 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
SecBuffer inbuf[4];
|
||||
SecBufferDesc inbuf_desc;
|
||||
SECURITY_STATUS sspi_status = SEC_E_OK;
|
||||
char *sspi_msg = NULL;
|
||||
|
||||
infof(data, "schannel: client wants to read %d\n", len);
|
||||
*err = CURLE_OK;
|
||||
@ -853,7 +864,9 @@ schannel_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* check if something went wrong and we need to return an error */
|
||||
if(ret < 0 && sspi_status != SEC_E_OK) {
|
||||
infof(data, "schannel: failed to read data from server\n");
|
||||
sspi_msg = Curl_sspi_status_msg(sspi_status);
|
||||
infof(data, "schannel: failed to read data from server: %s\n", sspi_msg);
|
||||
free(sspi_msg);
|
||||
*err = CURLE_RECV_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
149
lib/curl_sspi.c
149
lib/curl_sspi.c
@ -118,4 +118,153 @@ Curl_sspi_global_cleanup(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Curl_sspi_status(SECURIY_STATUS status)
|
||||
*
|
||||
* This function returns a string representing an SSPI status.
|
||||
* It will in any case return a usable string pointer which needs to be freed.
|
||||
*/
|
||||
char*
|
||||
Curl_sspi_status(SECURITY_STATUS status)
|
||||
{
|
||||
const char* status_const;
|
||||
|
||||
switch(status) {
|
||||
case SEC_I_COMPLETE_AND_CONTINUE:
|
||||
status_const = "SEC_I_COMPLETE_AND_CONTINUE";
|
||||
break;
|
||||
case SEC_I_COMPLETE_NEEDED:
|
||||
status_const = "SEC_I_COMPLETE_NEEDED";
|
||||
break;
|
||||
case SEC_I_CONTINUE_NEEDED:
|
||||
status_const = "SEC_I_CONTINUE_NEEDED";
|
||||
break;
|
||||
case SEC_I_CONTEXT_EXPIRED:
|
||||
status_const = "SEC_I_CONTEXT_EXPIRED";
|
||||
break;
|
||||
case SEC_I_INCOMPLETE_CREDENTIALS:
|
||||
status_const = "SEC_I_INCOMPLETE_CREDENTIALS";
|
||||
break;
|
||||
case SEC_I_RENEGOTIATE:
|
||||
status_const = "SEC_I_RENEGOTIATE";
|
||||
break;
|
||||
case SEC_E_BUFFER_TOO_SMALL:
|
||||
status_const = "SEC_E_BUFFER_TOO_SMALL";
|
||||
break;
|
||||
case SEC_E_CONTEXT_EXPIRED:
|
||||
status_const = "SEC_E_CONTEXT_EXPIRED";
|
||||
break;
|
||||
case SEC_E_CRYPTO_SYSTEM_INVALID:
|
||||
status_const = "SEC_E_CRYPTO_SYSTEM_INVALID";
|
||||
break;
|
||||
case SEC_E_INCOMPLETE_MESSAGE:
|
||||
status_const = "SEC_E_INCOMPLETE_MESSAGE";
|
||||
break;
|
||||
case SEC_E_INSUFFICIENT_MEMORY:
|
||||
status_const = "SEC_E_INSUFFICIENT_MEMORY";
|
||||
break;
|
||||
case SEC_E_INTERNAL_ERROR:
|
||||
status_const = "SEC_E_INTERNAL_ERROR";
|
||||
break;
|
||||
case SEC_E_INVALID_HANDLE:
|
||||
status_const = "SEC_E_INVALID_HANDLE";
|
||||
break;
|
||||
case SEC_E_INVALID_TOKEN:
|
||||
status_const = "SEC_E_INVALID_TOKEN";
|
||||
break;
|
||||
case SEC_E_LOGON_DENIED:
|
||||
status_const = "SEC_E_LOGON_DENIED";
|
||||
break;
|
||||
case SEC_E_MESSAGE_ALTERED:
|
||||
status_const = "SEC_E_MESSAGE_ALTERED";
|
||||
break;
|
||||
case SEC_E_NO_AUTHENTICATING_AUTHORITY:
|
||||
status_const = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
|
||||
break;
|
||||
case SEC_E_NO_CREDENTIALS:
|
||||
status_const = "SEC_E_NO_CREDENTIALS";
|
||||
break;
|
||||
case SEC_E_NOT_OWNER:
|
||||
status_const = "SEC_E_NOT_OWNER";
|
||||
break;
|
||||
case SEC_E_OK:
|
||||
status_const = "SEC_E_OK";
|
||||
break;
|
||||
case SEC_E_OUT_OF_SEQUENCE:
|
||||
status_const = "SEC_E_OUT_OF_SEQUENCE";
|
||||
break;
|
||||
case SEC_E_QOP_NOT_SUPPORTED:
|
||||
status_const = "SEC_E_QOP_NOT_SUPPORTED";
|
||||
break;
|
||||
case SEC_E_SECPKG_NOT_FOUND:
|
||||
status_const = "SEC_E_SECPKG_NOT_FOUND";
|
||||
break;
|
||||
case SEC_E_TARGET_UNKNOWN:
|
||||
status_const = "SEC_E_TARGET_UNKNOWN";
|
||||
break;
|
||||
case SEC_E_UNKNOWN_CREDENTIALS:
|
||||
status_const = "SEC_E_UNKNOWN_CREDENTIALS";
|
||||
break;
|
||||
case SEC_E_UNSUPPORTED_FUNCTION:
|
||||
status_const = "SEC_E_UNSUPPORTED_FUNCTION";
|
||||
break;
|
||||
case SEC_E_WRONG_PRINCIPAL:
|
||||
status_const = "SEC_E_WRONG_PRINCIPAL";
|
||||
break;
|
||||
default:
|
||||
status_const = "Unknown error";
|
||||
}
|
||||
|
||||
return curl_maprintf("%s (0x%08X)", status_const, status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sspi_status_msg(SECURITY_STATUS status)
|
||||
*
|
||||
* This function returns a message representing an SSPI status.
|
||||
* It will in any case return a usable string pointer which needs to be freed.
|
||||
*/
|
||||
|
||||
char*
|
||||
Curl_sspi_status_msg(SECURITY_STATUS status)
|
||||
{
|
||||
LPSTR format_msg = NULL;
|
||||
char *status_msg = NULL, *status_const = NULL;
|
||||
int status_len = 0;
|
||||
|
||||
status_len = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, status, 0, (LPTSTR)&format_msg, 0, NULL);
|
||||
|
||||
if(status_len > 0 && format_msg) {
|
||||
status_msg = strdup(format_msg);
|
||||
LocalFree(format_msg);
|
||||
|
||||
/* remove trailing CR+LF */
|
||||
if(status_len > 0) {
|
||||
if(status_msg[status_len-1] == '\n') {
|
||||
status_msg[status_len-1] = '\0';
|
||||
if(status_len > 1) {
|
||||
if(status_msg[status_len-2] == '\r') {
|
||||
status_msg[status_len-2] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_const = Curl_sspi_status(status);
|
||||
if(status_msg) {
|
||||
status_msg = curl_maprintf("%s [%s]", status_msg, status_const);
|
||||
free(status_const);
|
||||
}
|
||||
else {
|
||||
status_msg = status_const;
|
||||
}
|
||||
|
||||
return status_msg;
|
||||
}
|
||||
|
||||
#endif /* USE_WINDOWS_SSPI */
|
||||
|
@ -63,6 +63,8 @@
|
||||
|
||||
CURLcode Curl_sspi_global_init(void);
|
||||
void Curl_sspi_global_cleanup(void);
|
||||
char* Curl_sspi_status(SECURITY_STATUS status);
|
||||
char* Curl_sspi_status_msg(SECURITY_STATUS status);
|
||||
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
|
||||
|
@ -53,98 +53,16 @@ static int check_sspi_err(struct SessionHandle *data,
|
||||
SECURITY_STATUS minor_status,
|
||||
const char* function)
|
||||
{
|
||||
const char *txt;
|
||||
char *sspi_msg = NULL;
|
||||
(void)minor_status;
|
||||
|
||||
if(major_status != SEC_E_OK &&
|
||||
major_status != SEC_I_COMPLETE_AND_CONTINUE &&
|
||||
major_status != SEC_I_COMPLETE_NEEDED &&
|
||||
major_status != SEC_I_CONTINUE_NEEDED) {
|
||||
failf(data, "SSPI error: %s failed: %d\n", function, major_status);
|
||||
switch (major_status) {
|
||||
case SEC_I_COMPLETE_AND_CONTINUE:
|
||||
txt="SEC_I_COMPLETE_AND_CONTINUE";
|
||||
break;
|
||||
case SEC_I_COMPLETE_NEEDED:
|
||||
txt="SEC_I_COMPLETE_NEEDED";
|
||||
break;
|
||||
case SEC_I_CONTINUE_NEEDED:
|
||||
txt="SEC_I_CONTINUE_NEEDED";
|
||||
break;
|
||||
case SEC_I_CONTEXT_EXPIRED:
|
||||
txt="SEC_I_CONTEXT_EXPIRED";
|
||||
break;
|
||||
case SEC_I_INCOMPLETE_CREDENTIALS:
|
||||
txt="SEC_I_INCOMPLETE_CREDENTIALS";
|
||||
break;
|
||||
case SEC_I_RENEGOTIATE:
|
||||
txt="SEC_I_RENEGOTIATE";
|
||||
break;
|
||||
case SEC_E_BUFFER_TOO_SMALL:
|
||||
txt="SEC_E_BUFFER_TOO_SMALL";
|
||||
break;
|
||||
case SEC_E_CONTEXT_EXPIRED:
|
||||
txt="SEC_E_CONTEXT_EXPIRED";
|
||||
break;
|
||||
case SEC_E_CRYPTO_SYSTEM_INVALID:
|
||||
txt="SEC_E_CRYPTO_SYSTEM_INVALID";
|
||||
break;
|
||||
case SEC_E_INCOMPLETE_MESSAGE:
|
||||
txt="SEC_E_INCOMPLETE_MESSAGE";
|
||||
break;
|
||||
case SEC_E_INSUFFICIENT_MEMORY:
|
||||
txt="SEC_E_INSUFFICIENT_MEMORY";
|
||||
break;
|
||||
case SEC_E_INTERNAL_ERROR:
|
||||
txt="SEC_E_INTERNAL_ERROR";
|
||||
break;
|
||||
case SEC_E_INVALID_HANDLE:
|
||||
txt="SEC_E_INVALID_HANDLE";
|
||||
break;
|
||||
case SEC_E_INVALID_TOKEN:
|
||||
txt="SEC_E_INVALID_TOKEN";
|
||||
break;
|
||||
case SEC_E_LOGON_DENIED:
|
||||
txt="SEC_E_LOGON_DENIED";
|
||||
break;
|
||||
case SEC_E_MESSAGE_ALTERED:
|
||||
txt="SEC_E_MESSAGE_ALTERED";
|
||||
break;
|
||||
case SEC_E_NO_AUTHENTICATING_AUTHORITY:
|
||||
txt="SEC_E_NO_AUTHENTICATING_AUTHORITY";
|
||||
break;
|
||||
case SEC_E_NO_CREDENTIALS:
|
||||
txt="SEC_E_NO_CREDENTIALS";
|
||||
break;
|
||||
case SEC_E_NOT_OWNER:
|
||||
txt="SEC_E_NOT_OWNER";
|
||||
break;
|
||||
case SEC_E_OUT_OF_SEQUENCE:
|
||||
txt="SEC_E_OUT_OF_SEQUENCE";
|
||||
break;
|
||||
case SEC_E_QOP_NOT_SUPPORTED:
|
||||
txt="SEC_E_QOP_NOT_SUPPORTED";
|
||||
break;
|
||||
case SEC_E_SECPKG_NOT_FOUND:
|
||||
txt="SEC_E_SECPKG_NOT_FOUND";
|
||||
break;
|
||||
case SEC_E_TARGET_UNKNOWN:
|
||||
txt="SEC_E_TARGET_UNKNOWN";
|
||||
break;
|
||||
case SEC_E_UNKNOWN_CREDENTIALS:
|
||||
txt="SEC_E_UNKNOWN_CREDENTIALS";
|
||||
break;
|
||||
case SEC_E_UNSUPPORTED_FUNCTION:
|
||||
txt="SEC_E_UNSUPPORTED_FUNCTION";
|
||||
break;
|
||||
case SEC_E_WRONG_PRINCIPAL:
|
||||
txt="SEC_E_WRONG_PRINCIPAL";
|
||||
break;
|
||||
default:
|
||||
txt="Unknown error";
|
||||
|
||||
}
|
||||
failf(data, "SSPI error: %s failed: %s\n", function, txt);
|
||||
sspi_msg = Curl_sspi_status_msg(major_status);
|
||||
failf(data, "SSPI error: %s failed: %s\n", function, sspi_msg);
|
||||
free(sspi_msg);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user