mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
More SSL/TLS options support
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35618 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
7771aba9e1
commit
f4eb5e2726
6 changed files with 137 additions and 30 deletions
|
@ -1,3 +1,12 @@
|
|||
2012-09-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSSocketStream.m:
|
||||
* Source/GSTLS.m:
|
||||
* Source/GSHTTPURLHandle.m:
|
||||
* Source/NSURLProtocol.m:
|
||||
* Headers/Foundation/NSFileHandle.h:
|
||||
Add GNUstep TLS/SSL options when loading HTTPS URLs.
|
||||
|
||||
2012-09-26 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSUserDefaults.m: Fix error synchronising from changes in
|
||||
|
|
|
@ -303,7 +303,7 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
|
|||
* <term>GSTLSPriority</term>
|
||||
* <desc>A GNUTLS priority string describing the ciphers etc which may be
|
||||
* used for the connection. In addition the string may be one of
|
||||
* SSLv2, SSLv3, or TLSv1 to use the appropriate general settings
|
||||
* SSLv3, or TLSv1 to use the appropriate general settings
|
||||
* for negotiating a connection of the specified type.
|
||||
* </desc>
|
||||
* <term>GSTLSRemoteHosts</term>
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#import "NSCallBacks.h"
|
||||
#import "GSURLPrivate.h"
|
||||
#import "GSPrivate.h"
|
||||
#import "GSTLS.h"
|
||||
|
||||
#ifdef HAVE_SYS_FILE_H
|
||||
# include <sys/file.h>
|
||||
|
@ -999,11 +1000,45 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
}
|
||||
if ([[u scheme] isEqualToString: @"https"])
|
||||
{
|
||||
static NSArray *keys = nil;
|
||||
NSMutableDictionary *opts;
|
||||
NSUInteger count;
|
||||
|
||||
/* If we are an https connection, negotiate secure connection.
|
||||
* Make sure we are not an observer of the file handle while
|
||||
* it is connecting...
|
||||
*/
|
||||
[nc removeObserver: self name: nil object: sock];
|
||||
|
||||
if (nil == keys)
|
||||
{
|
||||
keys = [[NSArray alloc] initWithObjects:
|
||||
GSTLSCAFile,
|
||||
GSTLSCertificateFile,
|
||||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
}
|
||||
count = [keys count];
|
||||
opts = [[NSMutableDictionary alloc] initWithCapacity: count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
NSString *str = [request objectForKey: key];
|
||||
|
||||
if (nil != str)
|
||||
{
|
||||
[opts setObject: str forKey: key];
|
||||
}
|
||||
}
|
||||
if (debug) [opts setObject: @"YES" forKey: GSTLSDebug];
|
||||
[sock sslSetOptions: opts];
|
||||
[opts release];
|
||||
if ([sock sslConnect] == NO)
|
||||
{
|
||||
if (debug)
|
||||
|
|
|
@ -422,9 +422,25 @@ GSTLSPush(gnutls_transport_ptr_t handle, const void *buffer, size_t len)
|
|||
|
||||
@implementation GSTLSHandler
|
||||
|
||||
static NSArray *keys = nil;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
[GSTLSObject class];
|
||||
if (nil == keys)
|
||||
{
|
||||
keys = [[NSArray alloc] initWithObjects:
|
||||
GSTLSCAFile,
|
||||
GSTLSCertificateFile,
|
||||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) tryInput: (GSSocketInputStream*)i output: (GSSocketOutputStream*)o
|
||||
|
@ -496,47 +512,68 @@ GSTLSPush(gnutls_transport_ptr_t handle, const void *buffer, size_t len)
|
|||
- (id) initWithInput: (GSSocketInputStream*)i
|
||||
output: (GSSocketOutputStream*)o
|
||||
{
|
||||
NSString *proto;
|
||||
NSDictionary *opts;
|
||||
BOOL server = NO;
|
||||
NSString *str;
|
||||
NSMutableDictionary *opts;
|
||||
NSUInteger count;
|
||||
BOOL server;
|
||||
|
||||
proto = [i propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
/* FIXME
|
||||
if ([[o propertyForKey: NSStreamSocketCertificateServerKey] boolValue] == YES)
|
||||
{
|
||||
server = YES;
|
||||
}
|
||||
*/
|
||||
server = [[o propertyForKey: @"IsServer"] boolValue];
|
||||
|
||||
if (GSDebugSet(@"NSStream") == YES)
|
||||
str = [o propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
if (nil == str) str = [i propertyForKey: NSStreamSocketSecurityLevelKey];
|
||||
if ([str isEqual: NSStreamSocketSecurityLevelNone] == YES)
|
||||
{
|
||||
gnutls_global_set_log_level (11); // Full debug output
|
||||
}
|
||||
else
|
||||
{
|
||||
gnutls_global_set_log_level (0); // No debug
|
||||
}
|
||||
|
||||
if ([[o propertyForKey: NSStreamSocketSecurityLevelKey] isEqual: proto] == NO)
|
||||
{
|
||||
NSLog(@"NSStreamSocketSecurityLevel on input stream does not match output stream");
|
||||
GSOnceMLog(@"NSStreamSocketSecurityLevelNone is insecure ..."
|
||||
@" not implemented");
|
||||
DESTROY(self);
|
||||
return nil;
|
||||
}
|
||||
opts = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
proto, NSStreamSocketSecurityLevelKey,
|
||||
nil];
|
||||
else if ([str isEqual: NSStreamSocketSecurityLevelSSLv2] == YES)
|
||||
{
|
||||
GSOnceMLog(@"NSStreamSocketSecurityLevelTLSv2 is insecure ..."
|
||||
@" not implemented");
|
||||
DESTROY(self);
|
||||
return nil;
|
||||
}
|
||||
else if ([str isEqual: NSStreamSocketSecurityLevelSSLv3] == YES)
|
||||
{
|
||||
str = @"SSLv3";
|
||||
}
|
||||
else if ([str isEqual: NSStreamSocketSecurityLevelTLSv1] == YES)
|
||||
{
|
||||
str = @"TLSV1";
|
||||
}
|
||||
else
|
||||
{
|
||||
str = nil;
|
||||
}
|
||||
|
||||
if ((self = [super initWithInput: i output: o]) == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* Create the options dictionary, copying in any option from the stream
|
||||
* properties. GSTLSPriority overrides NSStreamSocketSecurityLevelKey.
|
||||
*/
|
||||
opts = [NSMutableDictionary new];
|
||||
if (nil != str) [opts setObject: str forKey: GSTLSPriority];
|
||||
count = [keys count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
|
||||
str = [o propertyForKey: key];
|
||||
if (nil == str) str = [i propertyForKey: key];
|
||||
if (nil != str) [opts setObject: str forKey: key];
|
||||
}
|
||||
|
||||
session = [[GSTLSSession alloc] initWithOptions: opts
|
||||
direction: (server ? NO : YES)
|
||||
transport: (void*)self
|
||||
push: GSTLSPush
|
||||
pull: GSTLSPull];
|
||||
[opts release];
|
||||
initialised = YES;
|
||||
return self;
|
||||
}
|
||||
|
@ -2501,6 +2538,7 @@ setNonBlocking(SOCKET fd)
|
|||
[outs _setAddress: addr];
|
||||
[ins _setSock: acceptReturn];
|
||||
[outs _setSock: acceptReturn];
|
||||
[ins setProperty: @"YES" forKey: @"IsServer"];
|
||||
}
|
||||
if (inputStream)
|
||||
{
|
||||
|
|
|
@ -1018,11 +1018,6 @@ static NSMutableDictionary *privateKeyCache1 = nil;
|
|||
pri = NSStreamSocketSecurityLevelSSLv3;
|
||||
str = nil;
|
||||
}
|
||||
else if (YES == [str isEqual: @"SSLv2"])
|
||||
{
|
||||
pri = NSStreamSocketSecurityLevelSSLv2;
|
||||
str = nil;
|
||||
}
|
||||
else if (YES == [str isEqual: @"TLSv1"])
|
||||
{
|
||||
pri = NSStreamSocketSecurityLevelTLSv1;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#import "Foundation/NSValue.h"
|
||||
|
||||
#import "GSPrivate.h"
|
||||
#import "GSTLS.h"
|
||||
#import "GSURLPrivate.h"
|
||||
#import "GNUstepBase/GSMime.h"
|
||||
#import "GNUstepBase/NSObject+GNUstepBase.h"
|
||||
|
@ -780,10 +781,39 @@ static NSURLProtocol *placeholder = nil;
|
|||
#endif
|
||||
if ([[url scheme] isEqualToString: @"https"] == YES)
|
||||
{
|
||||
static NSArray *keys;
|
||||
NSUInteger count;
|
||||
|
||||
[this->input setProperty: NSStreamSocketSecurityLevelNegotiatedSSL
|
||||
forKey: NSStreamSocketSecurityLevelKey];
|
||||
[this->output setProperty: NSStreamSocketSecurityLevelNegotiatedSSL
|
||||
forKey: NSStreamSocketSecurityLevelKey];
|
||||
if (nil == keys)
|
||||
{
|
||||
keys = [[NSArray alloc] initWithObjects:
|
||||
GSTLSCAFile,
|
||||
GSTLSCertificateFile,
|
||||
GSTLSCertificateKeyFile,
|
||||
GSTLSCertificateKeyPassword,
|
||||
GSTLSDebug,
|
||||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
}
|
||||
count = [keys count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSString *key = [keys objectAtIndex: count];
|
||||
NSString *str = [this->request _propertyForKey: key];
|
||||
|
||||
if (nil != str)
|
||||
{
|
||||
[this->output setProperty: str forKey: key];
|
||||
}
|
||||
}
|
||||
if (_debug) [this->output setProperty: @"YES" forKey: GSTLSDebug];
|
||||
}
|
||||
[this->input setDelegate: self];
|
||||
[this->output setDelegate: self];
|
||||
|
|
Loading…
Reference in a new issue