Add option to control hosts allowed

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35606 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2012-09-26 16:05:36 +00:00
parent db9c84ff4e
commit da52c8df5e

View file

@ -48,6 +48,7 @@ NSString * const GSTLSCertificateKeyFile = @"GSTLSCertificateKeyFile";
NSString * const GSTLSCertificateKeyPassword = @"GSTLSCertificateKeyPassword";
NSString * const GSTLSDebug = @"GSTLSDebug";
NSString * const GSTLSCAVerify = @"GSTLSCAVerify";
NSString * const GSTLSRemoteHosts = @"GSTLSRemoteHosts";
#if defined(HAVE_GNUTLS)
@ -110,8 +111,8 @@ static BOOL verifyServer = NO;
/* The globalDebug variable turns on gnutls debug. The hard-code value is
* overridden by GS_TLS_DEBUG, which in turn can be overridden by the
* GSTLSDebug user default. This is an integer debug level with higher
* values producing more debug output. Usually levels higher than 1 are
* too verbose and not useful unless you have the gnutls source code to hand.
* values producing more debug output. Usually levels above 1 are too
* verbose and not useful unless you have the gnutls source code to hand.
* NB. The GSTLSDebug session option is a boolean to turn on extra debug for
* a particular session to be produced on verification failure.
*/
@ -1292,6 +1293,8 @@ static NSMutableDictionary *privateKeyCache1 = nil;
- (int) verify
{
BOOL debug = (globalDebug > 0) ? YES : NO;
NSArray *names;
NSString *str;
unsigned int status;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
@ -1313,6 +1316,8 @@ static NSMutableDictionary *privateKeyCache1 = nil;
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (YES == debug)
{
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
NSLog(@"The certificate hasn't got a known issuer.");
@ -1326,10 +1331,11 @@ static NSMutableDictionary *privateKeyCache1 = nil;
if (status & GNUTLS_CERT_NOT_ACTIVATED)
NSLog(@"The certificate is not yet activated");
*/
}
if (status & GNUTLS_CERT_INVALID)
{
NSLog(@"The certificate is not trusted.");
NSLog(@"The remote certificate is not trusted.");
return GNUTLS_E_CERTIFICATE_ERROR;
}
@ -1338,18 +1344,21 @@ static NSMutableDictionary *privateKeyCache1 = nil;
* be easily extended to work with openpgp keys as well.
*/
if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509)
{
NSLog(@"The remote certificate is not of the X509 type.");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (gnutls_x509_crt_init(&cert) < 0)
{
NSLog(@"error in initialization");
NSLog(@"error in certificate initialization");
return GNUTLS_E_CERTIFICATE_ERROR;
}
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
if (cert_list == NULL)
{
NSLog(@"No certificate was found!");
NSLog(@"No certificate form remote end was found!");
return GNUTLS_E_CERTIFICATE_ERROR;
}
@ -1359,9 +1368,30 @@ static NSMutableDictionary *privateKeyCache1 = nil;
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (nil != host)
str = [opts objectForKey: GSTLSRemoteHosts];
if (nil == str)
{
NSEnumerator *enumerator = [[host names] objectEnumerator];
/* No names specified ... use all known names for the host we are
* connecting to.
*/
names = [host names];
}
else if ([str length] == 0)
{
/* Empty name ... disable host name checking.
*/
names = nil;
}
else
{
/* The string is a comma separated list of permitted host names.
*/
names = [str componentsSeparatedByString: @","];
}
if (nil != names)
{
NSEnumerator *enumerator = [names objectEnumerator];
BOOL found = NO;
NSString *name;
@ -1375,7 +1405,7 @@ static NSMutableDictionary *privateKeyCache1 = nil;
}
if (NO == found)
{
NSLog(@"The certificate's owner does not match host '%@'", host);
NSLog(@"The certificate's owner does not match '%@'", names);
gnutls_x509_crt_deinit(cert);
return GNUTLS_E_CERTIFICATE_ERROR;
}