mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Add GSTLSServerName option
This commit is contained in:
parent
09da1e6894
commit
ed286536e2
8 changed files with 91 additions and 7 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2018-05-18 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Tools/gdnc.m: Remove a little unused code
|
||||
* Headers/Foundation/NSFileHandle.h:
|
||||
* Source/GSHTTPURLHandle.m:
|
||||
* Source/GSSocketStream.m:
|
||||
* Source/GSTLS.h:
|
||||
* Source/GSTLS.m:
|
||||
* Source/NSURLProtocol.m:
|
||||
Add support for TLS SNI (Server Name Indication) and a new option
|
||||
(GSTLSServerName) to control what name (if any) is passed in the TLS
|
||||
handshake.
|
||||
|
||||
2018-05-17 Yavor Doganov <yavor@gnu.org>
|
||||
|
||||
* Tests/base/NSNumberFormatter/basic10_4.m: Avoid test failure on
|
||||
|
|
|
@ -287,7 +287,7 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
|
|||
* be set.<br />
|
||||
* You may use the same options as property settings with the GNUstep
|
||||
* implementation of NSStream.<br />
|
||||
* Expects key value pairs with the follwing names/meanings:
|
||||
* Expects key value pairs with the following names/meanings:
|
||||
* <deflist>
|
||||
* <term>GSTLSCAFile</term>
|
||||
* <desc>A string identifying the full path to the file containing any
|
||||
|
@ -330,6 +330,18 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
|
|||
* information for certificates issued by our trusted authorites but
|
||||
* no longer valid.
|
||||
* </desc>
|
||||
* <term>GSTLSServerName</term>
|
||||
* <desc>By default the TLS layer when making an HTTPS request sets the
|
||||
* 'Server Name Indication' (SNI) to be the name of the host in the URL
|
||||
* that is being fetched.<br />
|
||||
* This option allows the SNI to be set for other connections and permits
|
||||
* overriding of the default behavior for HTTPS requests. Setting the
|
||||
* value of GSTLSServerName to an empty string will prevent the SNI from
|
||||
* being sent in the TLS handshake (this is sometimes desirable to prevent
|
||||
* information leakage; the SNI information is sent unencrypted).<br />
|
||||
* Some web servers require SNI in order to tell what hostname an HTTPS
|
||||
* request is for and decide which certificate to present to the client.
|
||||
* </desc>
|
||||
* <term>GSTLSVerify</term>
|
||||
* <desc>A boolean specifying whether we should require the remote end to
|
||||
* supply a valid certificate in order to establish an encrypted connection.
|
||||
|
@ -386,6 +398,11 @@ GS_EXPORT NSString * const GSTLSRemoteHosts;
|
|||
*/
|
||||
GS_EXPORT NSString * const GSTLSRevokeFile;
|
||||
|
||||
/** Dictionary key for the value controlling the Server Name Indication
|
||||
* (SNI) sent as part of the TLS handshake.
|
||||
*/
|
||||
GS_EXPORT NSString * const GSTLSServerName;
|
||||
|
||||
/** Dictionary key for a boolean to enable certificate verification.
|
||||
*/
|
||||
GS_EXPORT NSString * const GSTLSVerify;
|
||||
|
|
|
@ -1112,6 +1112,7 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSServerName,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
}
|
||||
|
@ -1127,6 +1128,21 @@ debugWrite(GSHTTPURLHandle *handle, NSData *data)
|
|||
[opts setObject: str forKey: key];
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is no value set for the server name, and the host in the
|
||||
* URL is a domain name rather than an address, we use that.
|
||||
*/
|
||||
if (nil == [opts objectForKey: GSTLSServerName])
|
||||
{
|
||||
NSString *host = [u host];
|
||||
unichar c = [host length] == 0 ? 0 : [host characterAtIndex: 0];
|
||||
|
||||
if (c != 0 && c != ':' && !isdigit(c))
|
||||
{
|
||||
[opts setObject: host forKey: GSTLSServerName];
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) [opts setObject: @"YES" forKey: GSTLSDebug];
|
||||
[sock sslSetOptions: opts];
|
||||
[opts release];
|
||||
|
|
|
@ -455,6 +455,7 @@ static NSArray *keys = nil;
|
|||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSServerName,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
[[NSObject leakAt: &keys] release];
|
||||
|
|
|
@ -36,6 +36,7 @@ extern NSString * const GSTLSDebug;
|
|||
extern NSString * const GSTLSPriority;
|
||||
extern NSString * const GSTLSRemoteHosts;
|
||||
extern NSString * const GSTLSRevokeFile;
|
||||
extern NSString * const GSTLSServerName;
|
||||
extern NSString * const GSTLSVerify;
|
||||
|
||||
#if defined(HAVE_GNUTLS)
|
||||
|
|
|
@ -81,6 +81,7 @@ NSString * const GSTLSDebug = @"GSTLSDebug";
|
|||
NSString * const GSTLSPriority = @"GSTLSPriority";
|
||||
NSString * const GSTLSRemoteHosts = @"GSTLSRemoteHosts";
|
||||
NSString * const GSTLSRevokeFile = @"GSTLSRevokeFile";
|
||||
NSString * const GSTLSServerName = @"GSTLSServerName";
|
||||
NSString * const GSTLSVerify = @"GSTLSVerify";
|
||||
|
||||
#if defined(HAVE_GNUTLS)
|
||||
|
@ -1533,6 +1534,32 @@ retrieve_callback(gnutls_session_t session,
|
|||
if (YES == outgoing)
|
||||
{
|
||||
gnutls_init(&session, GNUTLS_CLIENT);
|
||||
|
||||
str = [opts objectForKey: GSTLSServerName];
|
||||
if ([str length] > 0)
|
||||
{
|
||||
const char *ptr = [str UTF8String];
|
||||
unsigned len = strlen(ptr);
|
||||
int ret;
|
||||
|
||||
ret = gnutls_server_name_set(session, GNUTLS_NAME_DNS, ptr, len);
|
||||
if (YES == debug)
|
||||
{
|
||||
if (ret < 0)
|
||||
{
|
||||
NSLog(@"%@ %@: failed '%s'", self, GSTLSServerName,
|
||||
gnutls_strerror(ret));
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"%@ %@: set to '%s'", self, GSTLSServerName, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (YES == debug)
|
||||
{
|
||||
NSLog(@"%@ %@: not set", self, GSTLSServerName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -882,6 +882,7 @@ static NSURLProtocol *placeholder = nil;
|
|||
GSTLSPriority,
|
||||
GSTLSRemoteHosts,
|
||||
GSTLSRevokeFile,
|
||||
GSTLSServerName,
|
||||
GSTLSVerify,
|
||||
nil];
|
||||
}
|
||||
|
@ -896,6 +897,20 @@ static NSURLProtocol *placeholder = nil;
|
|||
[this->output setProperty: str forKey: key];
|
||||
}
|
||||
}
|
||||
/* If there is no value set for the server name, and the host in the
|
||||
* URL is a domain name rather than an address, we use that.
|
||||
*/
|
||||
if (nil == [this->output propertyForKey: GSTLSServerName])
|
||||
{
|
||||
NSString *host = [url host];
|
||||
unichar c;
|
||||
|
||||
c = [host length] == 0 ? 0 : [host characterAtIndex: 0];
|
||||
if (c != 0 && c != ':' && !isdigit(c))
|
||||
{
|
||||
[this->output setProperty: host forKey: GSTLSServerName];
|
||||
}
|
||||
}
|
||||
if (_debug) [this->output setProperty: @"YES" forKey: GSTLSDebug];
|
||||
}
|
||||
[this->input setDelegate: self];
|
||||
|
|
|
@ -425,7 +425,6 @@ ihandler(int sig)
|
|||
NSString *service;
|
||||
BOOL isNetwork = NO;
|
||||
BOOL isPublic = NO;
|
||||
BOOL isLocal = NO;
|
||||
NSPort *port;
|
||||
NSPortNameServer *ns;
|
||||
NSUserDefaults *defs;
|
||||
|
@ -451,11 +450,6 @@ ihandler(int sig)
|
|||
{
|
||||
isNetwork = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
isLocal = YES;
|
||||
}
|
||||
|
||||
|
||||
if (isNetwork)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue