cocoa - 通过同一个套接字进行安全和不安全的连接

标签 cocoa sockets ssl

我有一些 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 时,我存储 native 套接字句柄:

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

我根据需要处理 NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable 事件。然后从存储的套接字句柄创建两个新流,并设置 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 事件在两个新流上都被调用,但是 NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailable 事件从未被引发。知道我做错了什么吗?

最佳答案

看来我的问题有两个方面。

  1. 当通过 CFStreamCreatePairWithSocketToHost 创建连接时,kCFStreamPropertyShouldCloseNativeSocket 属性自动设置为 TRUE。它应该是假的。

    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];
    

关于cocoa - 通过同一个套接字进行安全和不安全的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4615921/

相关文章:

macos - NSColorPanel 阻止鼠标按下事件

python - 使用 Python 将 TCP 数据流式传输到客户端

php - 如果 secure 为 false,是否可以在 HTTPS 中制作 cookie,并在 HTTP 中使用?

node.js - SPDY - 没有 TLS?

objective-c - 安全地将 NSString 中的内存归零

cocoa - 如何给 NSWindow 特定的背景颜色

cocoa - Foundation.h 和 cocoa.h 之间的区别

java - Android 套接字连接中出现错误 'null'

c++ - 我可以从不同的线程调用 socket send() 吗?

ssl - 支付完成后的 PayPal 安全警告