More digest authentication work ...basically functional now.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23093 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-06-20 16:42:08 +00:00
parent 2338be734c
commit 237c7c418a
4 changed files with 88 additions and 15 deletions

View file

@ -6,6 +6,8 @@
* Source/GSHTTPURLHandle.m: use GSHTTPAuthentication * Source/GSHTTPURLHandle.m: use GSHTTPAuthentication
Change class name to something more intuitive and add class methods Change class name to something more intuitive and add class methods
for mapping domains/URLs to protection space objects. for mapping domains/URLs to protection space objects.
Update code to used cache protection space info to put digest
authorisation in place without waiting for challenge.
2006-06-19 Richard Frith-Macdonald <rfm@gnu.org> 2006-06-19 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -18,7 +18,8 @@
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/ */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64

View file

@ -145,7 +145,7 @@ static GSMimeParser *mimeParser = nil;
{ {
method = NSURLAuthenticationMethodHTTPBasic; method = NSURLAuthenticationMethodHTTPBasic;
} }
else if ([sc scanString: @"Digest" intoString: 0] == NO) else if ([sc scanString: @"Digest" intoString: 0] == YES)
{ {
method = NSURLAuthenticationMethodHTTPDigest; method = NSURLAuthenticationMethodHTTPDigest;
} }
@ -171,10 +171,14 @@ static GSMimeParser *mimeParser = nil;
{ {
realm = val; realm = val;
} }
if ([sc scanString: @"," intoString: 0] == NO)
{
break; // No more in list.
}
} }
if (realm == nil) if (realm == nil)
{ {
return nil; // No real to authenticate in return nil; // No realm to authenticate in
} }
/* /*
@ -240,10 +244,11 @@ static GSMimeParser *mimeParser = nil;
while (count-- > 0) while (count-- > 0)
{ {
NSString *key = [keys objectAtIndex: count]; NSString *key = [keys objectAtIndex: count];
unsigned kl = [key length];
if (found == nil || [key length] > [found length]) if (found == nil || kl > [found length])
{ {
if ([path hasPrefix: key] == YES) if (kl == 0 || [path hasPrefix: key] == YES)
{ {
found = key; found = key;
} }
@ -278,18 +283,20 @@ static GSMimeParser *mimeParser = nil;
while ((domain = [e nextObject]) != nil) while ((domain = [e nextObject]) != nil)
{ {
NSURL *u; NSURL *u;
NSString *path;
NSNumber *port; NSNumber *port;
NSString *scheme; NSString *scheme;
NSString *server; NSString *server;
NSMutableDictionary *sDict; NSMutableDictionary *sDict;
u = [NSURL URLWithString: domain]; u = [NSURL URLWithString: domain];
if (u == nil) scheme = [u scheme];
if (scheme == nil)
{ {
u = [NSURL URLWithString: domain relativeToURL: base]; u = [NSURL URLWithString: domain relativeToURL: base];
scheme = [u scheme];
} }
port = [u port]; port = [u port];
scheme = [u scheme];
if ([port intValue] == 80 && [scheme isEqualToString: @"http"]) if ([port intValue] == 80 && [scheme isEqualToString: @"http"])
{ {
port = nil; port = nil;
@ -298,6 +305,11 @@ static GSMimeParser *mimeParser = nil;
{ {
port = nil; port = nil;
} }
path = [u path];
if (path == nil)
{
path = @"";
}
if ([port intValue] == 0) if ([port intValue] == 0)
{ {
server = [NSString stringWithFormat: @"%@://%@", server = [NSString stringWithFormat: @"%@://%@",

View file

@ -419,8 +419,65 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
{ {
if ([u user] != nil) if ([u user] != nil)
{ {
NSString *auth; NSString *auth = nil;
NSURLProtectionSpace *space;
/*
* If the URL we are loading is in a digest authentication space
* we try to create an authorization header using any existing
* cached information so that we can avoid the wasteful
* challenge/response dialogue.
*/
space = [GSHTTPAuthentication protectionSpaceForURL: u];
if (space != nil && [[space authenticationMethod] isEqual:
NSURLAuthenticationMethodHTTPDigest] == YES)
{
NSURLCredential *cred;
GSHTTPAuthentication *digest;
NSString *method;
/*
* Create credential from user and password
* stored in the URL.
*/
cred = [[NSURLCredential alloc]
initWithUser: [u user]
password: [u password]
persistence: NSURLCredentialPersistenceForSession];
/*
* Get the digest object and ask it for a header
* to use for authorisation.
*/
digest = [GSHTTPAuthentication
digestWithCredential: cred
inProtectionSpace: space];
RELEASE(cred);
method = [request objectForKey: GSHTTPPropertyMethodKey];
if (method == nil)
{
if ([wData length] > 0)
{
method = @"POST";
}
else
{
method = @"GET";
}
}
auth = [digest authorizationForAuthentication: nil
method: method
path: [u path]];
}
if (auth == nil)
{
/*
* Not able to do a digest authentication,
* so do a basic authentication in case the
* server accepts it.
*/
if ([[u password] length] > 0) if ([[u password] length] > 0)
{ {
auth = [NSString stringWithFormat: @"%@:%@", auth = [NSString stringWithFormat: @"%@:%@",
@ -432,6 +489,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data)
} }
auth = [NSString stringWithFormat: @"Basic %@", auth = [NSString stringWithFormat: @"Basic %@",
[GSMimeDocument encodeBase64String: auth]]; [GSMimeDocument encodeBase64String: auth]];
}
NSMapInsert(wProperties, (void*)@"Authorization", (void*)auth); NSMapInsert(wProperties, (void*)@"Authorization", (void*)auth);
} }
} }