KyleSanderson / serf

Automatically exported from code.google.com/p/serf
Apache License 2.0
0 stars 0 forks source link

Allow passing different credentials for Negotiate-NTLM proxy authorization #139

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

1. In a computer that is not part of the domain of the proxy, nor have the user 
connected;
2. Try issuing any serf command;
3. The authorization will fail as it will use the current logged in user 
credentials.

What is the expected output? What do you see instead?

Using the current credentials the authorization is supposed to always fail. In 
this case I would suggest allowing a configuration switch or prompting the user 
for the correct credentials. The form could be domain\user and password.

What version of the product are you using? On what operating system?

serf 1.3.2 (from TortoiseSVN 1.8.4, Build 24972 - 32 Bit 
Subversion 1.8.5, -release)

Please provide any additional information below.

Unfortunately, as a contractor, my development machine can not be part of the 
domain but I have credentials to access the proxy. Thats how I connect to the 
internet.

It would be very nice if this change could also be coordinated with the 
subversion/tortoise team to receive this information from then, solving a long 
lasting issue for subversion windows users that use these authorizations on 
their proxies.

Current workaroud:

Use another authorization proxy (ex: NTLMaps) or, in my case, if I connect 
using Firefox, it requests my credentials and the authorization seens to be 
keeped for a while. During this time I can access the subversion server through 
the proxy.

Original issue reported on code.google.com by vladlo...@gmail.com on 13 Jan 2014 at 8:11

GoogleCodeExporter commented 9 years ago
Hi.

if your proxy offers both Negotiate, NTLM and Digest or Basic authentication, 
svn+serf should:
- try Negotiate first
- if that fails, try NTLM
- if that fails, try Digest/Basic
This has been tested and works, so it's not clear to me why that doesn't work 
for you.

Since you seem to be able to compile serf on Windows, can you try build serf 
with AUTH_VERBOSE, CONN_VERBOSE and SOCK_VERBOSE set to 1 (in serf_private.h). 
Then run:
> test/serf_get-p proxy:port url

That should log what authn scheme's your proxy offers and how serf tries them.

Please post the results here, replace all private data by xxx.

Lieven

Original comment by lieven.govaerts@gmail.com on 13 Jan 2014 at 8:37

GoogleCodeExporter commented 9 years ago
Another workaround is:

Control Panel -> Network Passwords
-> Add a Windows Credential
Provide server name, user name and password. (Probably for the real server, not 
a DNS alias).

This will cache the credentials.

Sometimes it works to access a network share on the server. (This will store 
the credentials and/or activate the credentials.).

Original comment by bhuijben on 13 Jan 2014 at 8:38

GoogleCodeExporter commented 9 years ago
Hello Lieven,

my proxy only has Negotiate and NTLM authentication, as demonstrated by this 
header returned on the first connection attempt on a Fiddler section:

HTTP/1.1 407 Proxy Authorization Required
Date: Tue, 14 Jan 2014 20:06:07 GMT
Proxy-Connection: keep-alive
Via: 1.1 localhost.localdomain
Cache-Control: no-store
Content-Type: text/html
Content-Language: en
Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
Content-Length: 667
Proxy-Support: Session-Based-Authentication

Serf tries first Negotiate and, when it fails, NTLM. I can see from the message 
returned by the proxy that the problem is the credentials used in both cases:

Error Detail: <BR><PRE>[2014/01/14 18:06:07.549822,  3] 
utils/ntlm_auth.c:600(winbind_pw_check)
  Login for user [VLADLOPES]\[Administrator]@[VLADLOPES] failed due to [No such user]

As you see, I am on a machine that is called VLADLOPES with user Administrator.

I have tried the workaround you suggested but with no success. It seems to me 
that the credentials stored in this are only for windows network access.

Firefox, for instance, prompts for the credentials when the current logged user 
fails - after both Negotiate and NTLM - and then it tries again with the new 
credentials and finally it can authenticate.

If you want, I can send you both the serf attempt and the Firefox so you can 
check that this is what happening.

My suggestion is still to try with the current logged credentials and if that 
fails:
  - Prompt the user for the correct credentials or
  - Allow a parameter to be passed or read from a configuration file (with the problem of keeping the password in plain text).

Vladimir

Original comment by vladlo...@gmail.com on 14 Jan 2014 at 8:20

GoogleCodeExporter commented 9 years ago
Okay now I see. Both GSSAPI and SSPI implementations of the SPNEGO/NTLM authn 
providers in serf take the user's default credentials. So if these creds don't 
give you access to the server resources, and the server doesn't provide Basic 
authentication to fall back to, you're out of luck.

On Windows with SSPI requiring and using a specific username & password would 
be possible for both NTLM and Kerberos. 
On *nix the required gss_acquire_cred_with_password() is at first sight not 
standardised.  

This topic requires a bit of design in serf:
- how do we fallback from Negotiate/Kerberos/NTLM with default credentials to 
asking the application for username/password
- can we use the existing serf_credentials_callback_t also for these authn 
schemes?
- can we make this transparant to the application, or do we need to add an 
extra config?

Maybe one of the Windows guys can have a look?
L.

Original comment by lieven.govaerts@gmail.com on 14 Jan 2014 at 11:01

GoogleCodeExporter commented 9 years ago
Hello,

I had some time to check this issue and have a partial solution. This solution 
would work for the SSPI implementation. Anyway, this issue probably happens 
more often with Windows users, so I think it has a chance to make it through 
even without the linux implementation that, as state before, is not 
standardised.

First of I would like to clarify that I am not a C programmer. I took some 
class a long time ago and in no way I can claim that I know it. But I also 
think that I can contributte in some way here, so a gave it a shot. I expect 
this patch to be criticized by more experts mainly:
 - I did everything on Windows. I tried to remove every change on the patch that related to only the line ending;
 - I don't know when to use/not use const;
 - I used the examples from the serf code to get my ideas done, there are probably better ways to do most everything.

This patch has this limitations:
 - It will only work for Windows users;
 - It will only work when authenticating to a proxy server;
 - It was made with subversion in mind. For instance, the only way to provide the domain is in the form domain\username, a common way to do on Windows, as subversion only have one field, username.

I don't know how to extend this to other scenarios but would be pleased if 
someone could check the patch and point me to the right directions.

How it works:
 - There is a new way to set the username and password on the serf context;
 - If they were not set and serf can not authenticate because of bad credentials, them serf will ask for this information with a current provided callback and retry all schemes with this new information.

Subversion scenario:
 - Subversion has a way to provide the proxy username and password on it servers config file. The libsvn_ra_serf already has access to this information and just would have to call the new serf_config_proxy_username_password function. In this case, serf would use this information to try the authentication;
 - If the user haven't provided this information, we would use the context credential to get it from the user.

I made a change on the serf_get to test this patch:
 - If the username and password is provided in the arguments, then we call the configuration function;
 - Otherwise when it fails it will ask the user to enter this information.

Vladimir

Ps: When I update today with the latest version (2303) to test with this, I 
couldn't compile it anymore because of a missing parenthesis on ssl_buckets.c. 
I am including this change on another patch here, totally unrelated to this 
issue.

Original comment by vladlo...@gmail.com on 6 Feb 2014 at 9:27

Attachments:

GoogleCodeExporter commented 9 years ago
Looking into this patch, trying unix implementation + alternative method to 
avoid adding a new creds API.

Original comment by lieven.govaerts@gmail.com on 9 Feb 2014 at 4:09

GoogleCodeExporter commented 9 years ago
Hello Vladimir,

I've used saved credentials workaround many times and it always worked. You 
should use login name with domain like user@domain and the same host name that 
you're using to access server.

Lieven, regarding option to ask credentials: it's very important to make sure 
that clients (Subversion for example) doesn't save very secure Active Directory 
credentials on disk. There is requirements for Windows certified environments 
that's Active Directory credentials never asked except logon screen. So I 
prefer to make option to ask credentials for NTLM/Negotiate and making it 
disabled by default.

---
Ivan

Original comment by chemodax@gmail.com on 10 Feb 2014 at 9:32

GoogleCodeExporter commented 9 years ago
Hello Ivan,

I have tried the workaround and it didn't work. I have tested it on Windows XP 
SP3. Does the machine has to be a part of the domain you are trying to access? 
Maybe if you access something on the domain (eg. shared folder), the next time 
this cached credentials will be used for the connection. The problem is that I 
don't have access to the domain, only to the proxy. The proxy is the only 
resource I can use...

Regarding the credentials saved on subversion's server file, I only proposed 
this because it already has this option for proxy connection. The fact that the 
user that access the proxy is the same that have access to Active Directory is 
something to be concerned of. If the user don't want to store this on file she 
can always opt leaving it blank and being asked if the default credentials 
doesn't work.

Original comment by vladlo...@gmail.com on 10 Feb 2014 at 10:48

GoogleCodeExporter commented 9 years ago
Ivan, I'm not entirely sure what you mean concerning Windows certified 
applications: if a server integrates with AD and only offers Basic 
authentication, the client has no other option than to ask the user for 
username/password no?

Anyways, my idea was to add a new authn scheme "NegotiateWithUser". The authn 
scheme shares most of its code with the SSPI or GSSAPI implementations, except 
for requesting the username. Benefit of this approach is that we 
(theoretically) can use the existing credentials callback, and that we already 
have a mechanism to enable/disable authn scheme's via serf_config_authn_types.
Disadvantage is that the serf_credentials_callback_t type was copied from 
Subversion and isn't designed really well, so I think this is the time to 
update it and create a serf_credentials_callback_2_t.

Original comment by lieven.govaerts@gmail.com on 10 Feb 2014 at 12:08

GoogleCodeExporter commented 9 years ago
Lieven,

just for you to know, in my proxy case, the authn scheme that works with 
credentials is NTLM. The Negotiate still fails. If you follow the approach you 
are suggesting I would like to ask you to also add a NTLMWithUser authn scheme. 
The idea behind the patch I sent was to go to all schemes again because, for 
instance, the Negotiate could also work with the new credentials.

Original comment by vladlo...@gmail.com on 10 Feb 2014 at 1:32