gsocks5proxy: Return G_IO_ERROR_PROXY_NEED_AUTH if anonymous auth fails

If a username and password are specified by the caller, `GSocks5Proxy`
tells the server that it supports anonymous *and* username/password
authentication, and the server can choose which it prefers.

Otherwise, `GSocks5Proxy` only says that it supports anonymous
authentication. If that’s not acceptable to the server, the code was
previously returning `G_IO_ERROR_PROXY_AUTH_FAILED`. That error code
doesn’t indicate to the caller that authentication might succeed were
they to provide a username and password.

Change the error handling to make that clearer. A fuller solution would
be to expose more of the method negotiation in the `GSocks5Proxy` API,
so that the caller can specify ahead of time which authentication
methods they want to use. That can follow in issue #2059 though.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Fixes: #1988
This commit is contained in:
Philip Withnall 2020-03-10 11:31:37 +00:00
parent 68e18c6ec8
commit 4ca89d7807

View File

@ -170,8 +170,22 @@ parse_nego_reply (const guint8 *data,
*must_auth = TRUE;
break;
case SOCKS5_AUTH_GSSAPI:
case SOCKS5_AUTH_NO_ACCEPT:
if (!has_auth)
{
/* The server has said it accepts none of our authentication methods,
* but given the slightly odd implementation of set_nego_msg(), we
* actually only gave it the choice of %SOCKS5_AUTH_NONE, since the
* caller specified no username or password.
* Return %G_IO_ERROR_PROXY_NEED_AUTH so the caller knows that if
* they specify a username and password and try again, authentication
* might succeed (since well send %SOCKS5_AUTH_USR_PASS next time). */
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH,
_("The SOCKSv5 proxy requires authentication."));
return FALSE;
}
G_GNUC_FALLTHROUGH;
case SOCKS5_AUTH_GSSAPI:
default:
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED,
_("The SOCKSv5 proxy requires an authentication "