Безопасное и незащищенное соединение через один разъем - PullRequest
0 голосов
/ 06 января 2011

У меня есть некоторый код Python, который я пытаюсь перевести на Obj-C / Cocoa. Требуется подключение к сети; строка инициализации отправляется в виде открытого текста, после чего соединение защищено. В основном это работает так:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host,port))
sock.send( ... )
sock.recv( ... )
sslSock = ssl.wrap_socket(sock)
sslSock.send( ... )
sslSock.recv( ...)

Пока у меня есть следующее. Сначала я создаю сокет-соединение и потоки R / W:

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream);

inputStream = (NSInputStream *)readStream;
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

outputStream = (NSOutputStream *)writeStream;
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[inputStream open];
[outputStream open];

Когда отправляется NSStreamEventOpenCompleted, я сохраняю собственный дескриптор сокета:

NSSocketNativeHandle *socketHandle = [[outputStream propertyForKey:(NSString *)kCFStreamPropertySocketNativeHandle] bytes];

Я обрабатываю события NSStreamEventHasBytesAvailable и NSStreamEventHasSpaceAvailable, в зависимости от ситуации. Затем создайте два новых потока из сохраненного дескриптора сокета и установите свойства SSL:

[inputStream close];
[outputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

CFStreamCreatePairWithSocket(kCFAllocatorDefault, *socketHandle, &readStream, &writeStream);

inputStream = (NSInputStream *)readStream;
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];

outputStream = (NSOutputStream *)writeStream;
[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];

[inputStream open];
[outputStream open];

И это насколько я понимаю. Событие NSStreamEventOpenCompleted вызывается в обоих новых потоках, но события NSStreamEventHasBytesAvailable и NSStreamEventHasSpaceAvailable никогда не генерируются. Есть идеи, что я делаю не так?

1 Ответ

1 голос
/ 07 января 2011

Похоже, моя проблема была двоякой.

  1. При создании соединения через CFStreamCreatePairWithSocketToHost свойство kCFStreamPropertyShouldCloseNativeSocket автоматически устанавливается в значение ИСТИНА. Это должно быть ЛОЖЬ.

    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)HOST, PORT, &readStream, &writeStream);
    inputStream = (NSInputStream *)readStream;
    [inputStream setDelegate:self];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket];
    
  2. Я неправильно настроил SSL.

    NSMutableDictionary *sslSettings = [[NSMutableDictionary alloc] init];
    [sslSettings setObject:NSStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString *)kCFStreamSSLLevel];
    [sslSettings setObject:(id)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
    [sslSettings setObject:HOST forKey:(NSString *)kCFStreamSSLPeerName];
    [inputStream setProperty:sslSettings forKey:(NSString *)kCFStreamPropertySSLSettings];
    [inputStream open];
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...