~ubuntu-branches/ubuntu/utopic/gnustep-base/utopic

« back to all changes in this revision

Viewing changes to SSL/GSSSLHandle.m

  • Committer: Package Import Robot
  • Author(s): Paul Gevers
  • Date: 2014-07-19 13:02:18 UTC
  • mfrom: (20.1.6 utopic-proposed)
  • Revision ID: package-import@ubuntu.com-20140719130218-pn967l7wzjjf90yi
Tags: 1.24.6-2ubuntu1
* debian/rules:
  - Print the config.log if configure fails to debug
    powerpc/ppc64el FTBFS. (LP: #1277975)

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
 
96
96
#include <sys/ioctl.h>
97
97
#ifdef  __svr4__
 
98
#ifdef HAVE_SYS_FILIO_H
98
99
#include <sys/filio.h>
99
100
#endif
 
101
#endif
100
102
#include <netdb.h>
101
103
#include <string.h>
102
104
 
120
122
    }
121
123
  else
122
124
    {
123
 
      str = [NSString stringWithFormat: @"%s", ERR_reason_error_string(err)];
124
 
 
 
125
      const char        *s = ERR_reason_error_string(err);
 
126
 
 
127
      if (0 == s)
 
128
        {
 
129
          char  buf[128];
 
130
 
 
131
          ERR_error_string(err, buf);
 
132
          str = [NSString stringWithFormat: @"%s", buf];
 
133
        }
 
134
      else
 
135
        {
 
136
          str = [NSString stringWithFormat: @"%s", s];
 
137
        }
125
138
    }
126
139
  return str;
127
140
}
130
143
static NSLock   **locks = 0;
131
144
 
132
145
static void
133
 
locking_function(int mode, int n, const char *file, int line) 
134
 
 
146
locking_function(int mode, int n, const char *file, int line)
 
147
{
135
148
  if (mode & CRYPTO_LOCK)
136
 
    { 
 
149
    {
137
150
      [locks[n] lock];
138
151
    }
139
152
  else
140
 
    { 
 
153
    {
141
154
      [locks[n] unlock];
142
 
    } 
143
 
 
155
    }
 
156
}
144
157
 
145
158
#if     defined(HAVE_CRYPTO_THREADID_SET_CALLBACK)
146
159
static void
147
 
threadid_function(CRYPTO_THREADID *ref) 
148
 
 
160
threadid_function(CRYPTO_THREADID *ref)
 
161
{
149
162
  CRYPTO_THREADID_set_pointer(ref, GSCurrentThread());
150
 
 
163
}
151
164
#else
152
165
static unsigned long
153
 
threadid_function() 
154
 
 
166
threadid_function()
 
167
{
155
168
  return (unsigned long) GSCurrentThread();
156
 
 
169
}
157
170
#endif
158
171
 
159
172
 
164
177
  BOOL          connected;
165
178
}
166
179
 
167
 
- (BOOL) sslAccept;
168
 
- (BOOL) sslConnect;
169
180
- (void) sslDisconnect;
170
181
- (BOOL) sslHandshakeEstablished: (BOOL*)result outgoing: (BOOL)isOutgoing;
171
 
- (void) sslSetCertificate: (NSString*)certFile
172
 
                privateKey: (NSString*)privateKey
173
 
                 PEMpasswd: (NSString*)PEMpasswd;
 
182
- (NSString*) sslSetOptions: (NSDictionary*)options;
174
183
@end
175
184
 
176
 
static BOOL     permitSSLv2 = NO;
177
 
static NSString *cipherList = nil;
178
 
 
179
185
@implementation GSSSLHandle
180
 
+ (void) _defaultsChanged: (NSNotification*)n
181
 
{
182
 
  permitSSLv2
183
 
    = [[NSUserDefaults standardUserDefaults] boolForKey: @"GSPermitSSLv2"];
184
 
  cipherList
185
 
    = [[NSUserDefaults standardUserDefaults] stringForKey: @"GSCipherList"];
186
 
}
187
186
 
188
187
+ (void) initialize
189
188
{
190
189
  if (self == [GSSSLHandle class])
191
190
    {
192
 
      NSUserDefaults    *defs;
193
191
      unsigned          count;
194
192
 
195
193
      SSL_library_init();
200
198
        {
201
199
          locks[count] = [NSLock new];
202
200
        }
203
 
      CRYPTO_set_locking_callback(locking_function); 
 
201
      CRYPTO_set_locking_callback(locking_function);
204
202
#if     defined(HAVE_CRYPTO_THREADID_SET_CALLBACK)
205
 
      CRYPTO_THREADID_set_callback(threadid_function); 
 
203
      CRYPTO_THREADID_set_callback(threadid_function);
206
204
#else
207
 
      CRYPTO_set_id_callback(threadid_function); 
 
205
      CRYPTO_set_id_callback(threadid_function);
208
206
#endif
209
207
 
210
208
      /*
218
216
          inf = [[[NSProcessInfo processInfo] globallyUniqueString] UTF8String];
219
217
          RAND_seed(inf, strlen(inf));
220
218
        }
221
 
      defs = [NSUserDefaults standardUserDefaults];
222
 
      permitSSLv2 = [defs boolForKey: @"GSPermitSSLv2"];
223
 
      cipherList = [defs stringForKey: @"GSCipherList"];
224
 
      [[NSNotificationCenter defaultCenter]
225
 
        addObserver: self
226
 
           selector: @selector(_defaultsChanged:)
227
 
               name: NSUserDefaultsDidChangeNotification
228
 
             object: nil];
229
219
    }
230
220
}
231
221
 
250
240
  return [super read: buf length: len];
251
241
}
252
242
 
253
 
- (BOOL) sslAccept
254
 
{
255
 
  BOOL          result = NO;
256
 
 
257
 
  if (YES == isStandardFile)
258
 
    {
259
 
      NSLog(@"Attempt to make ssl connection to a standard file");
260
 
      return NO;
261
 
    }
262
 
  if (NO == [self sslHandshakeEstablished: &result outgoing: NO])
263
 
    {
264
 
      NSRunLoop *loop;
265
 
 
266
 
      IF_NO_GC([self retain];)          // Don't get destroyed during runloop
267
 
      loop = [NSRunLoop currentRunLoop];
268
 
      [loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
269
 
      if (NO == [self sslHandshakeEstablished: &result outgoing: NO])
270
 
        {
271
 
          NSDate                *final;
272
 
          NSDate                *when;
273
 
          NSTimeInterval        last = 0.0;
274
 
          NSTimeInterval        limit = 0.1;
275
 
 
276
 
          final = [[NSDate alloc] initWithTimeIntervalSinceNow: 30.0];
277
 
          when = [NSDate alloc];
278
 
 
279
 
          while (NO == [self sslHandshakeEstablished: &result outgoing: NO]
280
 
            && [final timeIntervalSinceNow] > 0.0)
281
 
            {
282
 
              NSTimeInterval    tmp = limit;
283
 
 
284
 
              limit += last;
285
 
              last = tmp;
286
 
              if (limit > 0.5)
287
 
                {
288
 
                  limit = 0.1;
289
 
                  last = 0.1;
290
 
                }
291
 
              when = [when initWithTimeIntervalSinceNow: limit];
292
 
              [loop runUntilDate: when];
293
 
            }
294
 
          RELEASE(when);
295
 
          RELEASE(final);
296
 
        }
297
 
      DESTROY(self);
298
 
    }
299
 
  return result;
300
 
}
301
 
 
302
 
- (BOOL) sslConnect
303
 
{
304
 
  BOOL          result = NO;
305
 
 
306
 
  if (YES == isStandardFile)
307
 
    {
308
 
      NSLog(@"Attempt to make ssl connection to a standard file");
309
 
      return NO;
310
 
    }
311
 
  if (NO == [self sslHandshakeEstablished: &result outgoing: YES])
312
 
    {
313
 
      NSRunLoop *loop;
314
 
 
315
 
      IF_NO_GC([self retain];)          // Don't get destroyed during runloop
316
 
      loop = [NSRunLoop currentRunLoop];
317
 
      [loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
318
 
      if (NO == [self sslHandshakeEstablished: &result outgoing: YES])
319
 
        {
320
 
          NSDate                *final;
321
 
          NSDate                *when;
322
 
          NSTimeInterval        last = 0.0;
323
 
          NSTimeInterval        limit = 0.1;
324
 
 
325
 
          final = [[NSDate alloc] initWithTimeIntervalSinceNow: 30.0];
326
 
          when = [NSDate alloc];
327
 
 
328
 
          while (NO == [self sslHandshakeEstablished: &result outgoing: YES]
329
 
            && [final timeIntervalSinceNow] > 0.0)
330
 
            {
331
 
              NSTimeInterval    tmp = limit;
332
 
 
333
 
              limit += last;
334
 
              last = tmp;
335
 
              if (limit > 0.5)
336
 
                {
337
 
                  limit = 0.1;
338
 
                  last = 0.1;
339
 
                }
340
 
              when = [when initWithTimeIntervalSinceNow: limit];
341
 
              [loop runUntilDate: when];
342
 
            }
343
 
          RELEASE(when);
344
 
          RELEASE(final);
345
 
        }
346
 
      DESTROY(self);
347
 
    }
348
 
  return result;
349
 
}
350
 
 
351
243
- (void) sslDisconnect
352
244
{
353
245
  if (ssl != 0)
388
280
  /*
389
281
   * Ensure we have a context and handle to connect with.
390
282
   */
391
 
  if (ctx == 0)
 
283
  if (0 == ctx)
392
284
    {
393
285
      ctx = SSL_CTX_new(SSLv23_client_method());
394
 
      if (permitSSLv2 == NO)
395
 
        {
396
 
          SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
397
 
        }
398
 
      if (nil != cipherList)
399
 
        {
400
 
          SSL_CTX_set_cipher_list(ctx, [cipherList UTF8String]);
401
 
        }
 
286
      SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
402
287
    }
403
 
  if (ssl == 0)
 
288
  if (0 == ssl)
404
289
    {
405
290
      ssl = SSL_new(ctx);
406
291
    }
407
292
 
408
 
  /*
409
 
   * Set non-blocking so accept won't hang if remote end goes wrong.
410
 
   */
411
 
  [self setNonBlocking: YES];
412
 
  ret = SSL_set_fd(ssl, descriptor);
 
293
  if (SSL_get_fd(ssl) == descriptor)
 
294
    {
 
295
      ret = 1;
 
296
    }
 
297
  else
 
298
    {
 
299
      /* Set non-blocking so accept won't hang if remote end goes wrong.
 
300
       */
 
301
      [self setNonBlocking: YES];
 
302
      ret = SSL_set_fd(ssl, descriptor);
 
303
    }
413
304
  if (1 == ret)
414
305
    {
415
306
      if (YES == isOutgoing)
441
332
  return YES;
442
333
}
443
334
 
444
 
- (void) sslSetCertificate: (NSString*)certFile
445
 
                privateKey: (NSString*)privateKey
446
 
                 PEMpasswd: (NSString*)PEMpasswd
 
335
- (NSString*) sslSetOptions: (NSDictionary*)options
447
336
{
448
 
  int   ret;
 
337
  NSString      *certFile;
 
338
  NSString      *privateKey;
 
339
  NSString      *PEMpasswd;
 
340
  int           ret;
 
341
 
 
342
  certFile = [options objectForKey: GSTLSCertificateFile];
 
343
  privateKey = [options objectForKey: GSTLSCertificateKeyFile];
 
344
  PEMpasswd = [options objectForKey: GSTLSCertificateKeyPassword];
449
345
 
450
346
  if (isStandardFile == YES)
451
347
    {
452
 
      NSLog(@"Attempt to set ssl certificate for a standard file");
453
 
      return;
 
348
      return @"Attempt to set ssl certificate for a standard file";
454
349
    }
 
350
 
455
351
  /*
456
352
   * Ensure we have a context to set the certificate for.
457
353
   */
458
354
  if (ctx == 0)
459
355
    {
460
356
      ctx = SSL_CTX_new(SSLv23_method());
461
 
      if (permitSSLv2 == NO)
462
 
        {
463
 
          SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
464
 
        }
465
 
      if (nil != cipherList)
466
 
        {
467
 
          SSL_CTX_set_cipher_list(ctx, [cipherList UTF8String]);
468
 
        }
 
357
      SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
469
358
    }
470
359
  if ([PEMpasswd length] > 0)
471
360
    {
479
368
        {
480
369
          NSLog(@"Failed to set certificate file to %@ - %@",
481
370
            certFile, sslError(ERR_get_error()));
 
371
          return @"Failed to set certificate file";
482
372
        }
483
373
    }
484
374
  if ([privateKey length] > 0)
489
379
        {
490
380
          NSLog(@"Failed to set private key file to %@ - %@",
491
381
            privateKey, sslError(ERR_get_error()));
 
382
          return @"Failed to set key file";
492
383
        }
493
384
    }
 
385
  return nil;
494
386
}
495
387
 
496
388
- (NSInteger) write: (const void*)buf length: (NSUInteger)len