TLS fixups

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38015 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2014-07-25 12:06:34 +00:00
parent e35bf6b65e
commit 6826ad0734
5 changed files with 148 additions and 48 deletions

View file

@ -1,3 +1,11 @@
2014-07-25 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSSocketStream.m: Fix handling TLS handshake in the case
where there is a network failure during the handshake (bug#42781).
* Source/GSTLS.m: Fix erroneous attempt to load revocation lists.
* Tests/base/NSURLConnection/test01.m: https test contributed by
Sergei Golovin.
2014-07-25 Richard Frith-Macdonald <rfm@gnu.org> 2014-07-25 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: Remove compiler charset options * configure.ac: Remove compiler charset options

View file

@ -628,38 +628,48 @@ static NSArray *keys = nil;
case NSStreamEventHasSpaceAvailable: case NSStreamEventHasSpaceAvailable:
case NSStreamEventHasBytesAvailable: case NSStreamEventHasBytesAvailable:
case NSStreamEventOpenCompleted: case NSStreamEventOpenCompleted:
[self hello]; /* try to complete the handshake */ /* try to complete the handshake.
if (handshake == NO) */
{ [self hello];
NSDebugMLLog(@"NSStream",
@"GSTLSHandler completed on %p", stream);
if ([istream streamStatus] == NSStreamStatusOpen)
{
[istream _resetEvents: NSStreamEventOpenCompleted];
[istream _sendEvent: NSStreamEventOpenCompleted];
}
else
{
[istream _resetEvents: NSStreamEventErrorOccurred];
[istream _sendEvent: NSStreamEventErrorOccurred];
}
if ([ostream streamStatus] == NSStreamStatusOpen)
{
[ostream _resetEvents: NSStreamEventOpenCompleted
| NSStreamEventHasSpaceAvailable];
[ostream _sendEvent: NSStreamEventOpenCompleted];
[ostream _sendEvent: NSStreamEventHasSpaceAvailable];
}
else
{
[ostream _resetEvents: NSStreamEventErrorOccurred];
[ostream _sendEvent: NSStreamEventErrorOccurred];
}
}
break; break;
case NSStreamEventErrorOccurred:
case NSStreamEventEndEncountered:
/* stream error or close ... handshake fails.
*/
handshake = NO;
break;
default: default:
break; break;
} }
if (NO == handshake)
{
NSDebugMLLog(@"NSStream",
@"GSTLSHandler completed on %p", stream);
if ([istream streamStatus] == NSStreamStatusOpen)
{
[istream _resetEvents: NSStreamEventOpenCompleted];
[istream _sendEvent: NSStreamEventOpenCompleted];
}
else
{
[istream _resetEvents: NSStreamEventErrorOccurred];
[istream _sendEvent: NSStreamEventErrorOccurred];
}
if ([ostream streamStatus] == NSStreamStatusOpen)
{
[ostream _resetEvents: NSStreamEventOpenCompleted
| NSStreamEventHasSpaceAvailable];
[ostream _sendEvent: NSStreamEventOpenCompleted];
[ostream _sendEvent: NSStreamEventHasSpaceAvailable];
}
else
{
[ostream _resetEvents: NSStreamEventErrorOccurred];
[ostream _sendEvent: NSStreamEventErrorOccurred];
}
}
} }
} }

View file

@ -57,6 +57,10 @@ NSString * const GSTLSVerify = @"GSTLSVerify";
static NSString * static NSString *
standardizedPath(NSString *path) standardizedPath(NSString *path)
{ {
if (0 == [path length])
{
return nil; // Not a path
}
if (NO == [path isAbsolutePath]) if (NO == [path isAbsolutePath])
{ {
path = [[[NSFileManager defaultManager] currentDirectoryPath] path = [[[NSFileManager defaultManager] currentDirectoryPath]
@ -188,9 +192,9 @@ static NSMutableDictionary *fileMap = nil;
* GS_TLS_CA_FILE environment variable. * GS_TLS_CA_FILE environment variable.
*/ */
str = [[NSUserDefaults standardUserDefaults] stringForKey: GSTLSCAFile]; str = [[NSUserDefaults standardUserDefaults] stringForKey: GSTLSCAFile];
str = standardizedPath(str);
if (nil != str) if (nil != str)
{ {
str = standardizedPath(str);
ASSIGN(caFile, str); ASSIGN(caFile, str);
} }
@ -198,9 +202,9 @@ static NSMutableDictionary *fileMap = nil;
* GS_TLS_REVOKE environment variable. * GS_TLS_REVOKE environment variable.
*/ */
str = [[NSUserDefaults standardUserDefaults] stringForKey: GSTLSRevokeFile]; str = [[NSUserDefaults standardUserDefaults] stringForKey: GSTLSRevokeFile];
str = standardizedPath(str);
if (nil != str) if (nil != str)
{ {
str = standardizedPath(str);
ASSIGN(revokeFile, str); ASSIGN(revokeFile, str);
} }
@ -1133,7 +1137,7 @@ static NSMutableDictionary *credentialsCache = nil;
path, GNUTLS_X509_FMT_PEM); path, GNUTLS_X509_FMT_PEM);
if (ret < 0) if (ret < 0)
{ {
NSLog(@"Problem loading revocation list from %@: %s", NSLog(@"Problem loading default revocation list from %@: %s",
drv, gnutls_strerror(ret)); drv, gnutls_strerror(ret));
} }
else else

View file

@ -150,11 +150,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
FILE *theFile = 0; FILE *theFile = 0;
void *tmp = 0; void *tmp = 0;
int c; int c;
#if defined(__MINGW__)
long fileLength;
#else
off_t fileLength; off_t fileLength;
#endif
#if defined(__MINGW__) #if defined(__MINGW__)
thePath = (const unichar*)[path fileSystemRepresentation]; thePath = (const unichar*)[path fileSystemRepresentation];
@ -182,11 +178,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
/* /*
* Seek to the end of the file. * Seek to the end of the file.
*/ */
#if defined(__MINGW__)
c = fseek(theFile, 0L, SEEK_END);
#else
c = fseeko(theFile, 0, SEEK_END); c = fseeko(theFile, 0, SEEK_END);
#endif
if (c != 0) if (c != 0)
{ {
NSWarnFLog(@"Seek to end of file (%@) failed - %@", path, NSWarnFLog(@"Seek to end of file (%@) failed - %@", path,
@ -198,13 +190,8 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
* Determine the length of the file (having seeked to the end of the * Determine the length of the file (having seeked to the end of the
* file) by calling ftello(). * file) by calling ftello().
*/ */
#if defined(__MINGW__)
fileLength = ftell(theFile);
if (fileLength == -1)
#else
fileLength = ftello(theFile); fileLength = ftello(theFile);
if (fileLength == (off_t) -1) if (fileLength == (off_t) -1)
#endif
{ {
NSWarnFLog(@"Ftell on %@ failed - %@", path, [NSError _last]); NSWarnFLog(@"Ftell on %@ failed - %@", path, [NSError _last]);
goto failure; goto failure;
@ -214,11 +201,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
* Rewind the file pointer to the beginning, preparing to read in * Rewind the file pointer to the beginning, preparing to read in
* the file. * the file.
*/ */
#if defined(__MINGW__)
c = fseek(theFile, 0L, SEEK_SET);
#else
c = fseeko(theFile, 0, SEEK_SET); c = fseeko(theFile, 0, SEEK_SET);
#endif
if (c != 0) if (c != 0)
{ {
NSWarnFLog(@"Fseek to start of file (%@) failed - %@", path, NSWarnFLog(@"Fseek to start of file (%@) failed - %@", path,

View file

@ -0,0 +1,95 @@
/**
* The test makes connections to not-listening services.
* One for HTTP and one for HTTPS.
* The NSURLConnection delegate is supposed to catch an
* error in that two cases and sets it's ivars accordingly.
*/
#import <Foundation/Foundation.h>
#import "Testing.h"
@interface Delegate : NSObject
{
BOOL _done;
NSError *_error;
}
- (void) reset;
- (NSError *) error;
- (BOOL) done;
- (void) connection: (NSURLConnection *)connection
didFailWithError: (NSError *)error;
@end
@implementation Delegate
- (void) reset
{
_done = NO;
_error = nil;
}
- (NSError *) error
{
return _error;
}
- (BOOL) done
{
return _done;
}
- (void) connection: (NSURLConnection *)connection
didFailWithError: (NSError *)error
{
_error = error;
_done = YES;
}
@end
int main(int argc, char **argv, char **env)
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSTimeInterval timing;
NSTimeInterval duration;
NSString *urlString;
NSURLRequest *req;
Delegate *del;
duration = 0.0;
timing = 0.1;
urlString = @"http://127.0.0.1:19750";
req = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
del = [[Delegate new] autorelease];
[del reset];
[NSURLConnection connectionWithRequest: req
delegate: del];
while (![del done] && duration < 3.0)
{
[[NSRunLoop currentRunLoop]
runUntilDate: [NSDate dateWithTimeIntervalSinceNow: timing]];
duration += timing;
}
PASS([del done] && nil != [del error],
"connection to dead(not-listening) HTTP service");
duration = 0.0;
urlString = @"https://127.0.0.1:19750";
req = [NSURLRequest requestWithURL: [NSURL URLWithString: urlString]];
[NSURLConnection connectionWithRequest: req
delegate: del];
[del reset];
while (![del done] && duration < 3.0)
{
[[NSRunLoop currentRunLoop]
runUntilDate: [NSDate dateWithTimeIntervalSinceNow: timing]];
duration += timing;
}
PASS([del done] && nil != [del error],
"connection to dead(not-listening) HTTPS service");
[arp release]; arp = nil;
return 0;
}