Kaidul

NSsocket.mm

Nov 23rd, 2014
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.16 KB | None | 0 0
  1. //
  2. //  NSsocket.cpp
  3. //  PAL
  4. //
  5. //  Created by Erfan on 4/23/14.
  6. //
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10. #include "NSsocket.h"
  11. #import "mach/mach.h"
  12. #include <sys/time.h>
  13. #include <netdb.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include "PALcritsec.h"
  17. #include <list>
  18. #include <CoreFoundation/CFArray.h>
  19. #include "winEmul.h"
  20.  
  21. #include <openssl/ssl.h>
  22. #include <openssl/bio.h>
  23. #include <openssl/x509.h>
  24. #include <openssl/x509_vfy.h>
  25. #include <openssl/pem.h>
  26. #include <openssl/x509v3.h>
  27. #include <openssl/err.h>
  28. #include <openssl/conf.h>
  29. #include <fstream>
  30.  
  31. #define BUFFER_SIZE 4096
  32.  
  33. @interface NSsocket : NSObject <NSStreamDelegate> {
  34.     @private volatile bool m_bConnected;
  35.     @private volatile bool m_bHasSpaceAvailable;
  36.        
  37.     @private NSInputStream *m_pInputStream;
  38.     @private NSOutputStream *m_pOutputStream;
  39.        
  40.     @private HANDLE m_hSocketError;
  41.     @private HANDLE m_hSocketOpened;
  42.     @private HANDLE m_hSocketDataReceived;
  43.     @private HANDLE m_hSocketClosed;
  44.        
  45.     @private PAL::Mutex* m_pReadMutex;
  46.     @private PAL::Mutex* m_pWriteMutex;
  47.        
  48.     @private std::list<std::string> recvMessageBuffer;
  49.     @private std::list<std::string> sendMessageBuffer;
  50. }
  51.  
  52. -(NSStream *)GetStream:(bool)bInput;
  53. -(bool)CreateAndConnect:(const std::string&) serverAddress withPort:(const u_int16_t&) serverPort withTransportMode:(bool)bTLS;
  54. -(void)CloseConnection;
  55. -(void)CloseStreams;
  56. -(void)CloseEvents;
  57. -(bool)IsConnected;
  58. -(int)Send:(const std::string&)sDataToSend;
  59. -(int)Recv:(char *)dataReceived withBufferSize:(int)bufferSize;
  60. -(int)Select:(u_int64_t)uTimeoutValue;
  61. -(void)Signal;
  62.  
  63. @end
  64.  
  65. @implementation NSsocket
  66.  
  67. - (id)init
  68. {
  69.     self = [super init];
  70.     if(self)
  71.     {
  72.         // Must be created at the beginning, otherwise calling Select would cause a crash with NULL events
  73.         m_hSocketError = CreateEvent(NULL, FALSE, FALSE, NULL);
  74.         m_hSocketOpened = CreateEvent(NULL, FALSE, FALSE, NULL);
  75.         m_hSocketDataReceived = CreateEvent(NULL, FALSE, FALSE, NULL);
  76.         m_hSocketClosed = CreateEvent(NULL, FALSE, FALSE, NULL);
  77.        
  78.         m_pReadMutex = new PAL::Mutex;
  79.         m_pWriteMutex = new PAL::Mutex;
  80.     }
  81.    
  82.     return self;
  83. }
  84.  
  85. -(NSStream *)GetStream:(bool)bInput
  86. {
  87.     return bInput ? m_pInputStream : m_pOutputStream;
  88. }
  89.  
  90. SecTrustRef changeHostForTrust(SecTrustRef trust)
  91. {
  92.     CFMutableArrayRef newTrustPolicies = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
  93.    
  94.     SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.smartbabymonitor.ugrow.philips.com"));
  95.    
  96.     CFArrayAppendValue(newTrustPolicies, sslPolicy);
  97.    
  98. #ifdef MAC_BACKWARDS_COMPATIBILITY
  99.     /* This technique works in OS X (v10.5 and later) */
  100.    
  101.     SecTrustSetPolicies(trust, newTrustPolicies);
  102.     CFRelease(oldTrustPolicies);
  103.    
  104.     return trust;
  105. #else
  106.     /* This technique works in iOS 2 and later, or
  107.      OS X v10.7 and later */
  108.    
  109.     CFMutableArrayRef certificates = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
  110.    
  111.     /* Copy the certificates from the original trust object */
  112.     CFIndex count = SecTrustGetCertificateCount(trust);
  113.     CFIndex i=0;
  114.     for (i = 0; i < count; i++) {
  115.         SecCertificateRef item = SecTrustGetCertificateAtIndex(trust, i);
  116.         CFArrayAppendValue(certificates, item);
  117.     }
  118.     NSLog(@"Cert: %@", certificates);
  119.    
  120.     /* Create a new trust object */
  121.     SecTrustRef newtrust = NULL;
  122.     if (SecTrustCreateWithCertificates(certificates, newTrustPolicies, &newtrust) != errSecSuccess) {
  123.         /* Probably a good spot to log something. */
  124.        
  125.         return NULL;
  126.     }
  127.    
  128.     return newtrust;
  129. #endif
  130. }
  131.  
  132. std::string gserverAddress;
  133. int gPort;
  134.  
  135. -(bool)CreateAndConnect:(const std::string&) serverAddress withPort:(const u_int16_t&) serverPort withTransportMode:(bool)bTLS
  136. {
  137.     gserverAddress = serverAddress;
  138.     gPort = serverPort;
  139.     NSLog(@"NSStream %p connecting to: %s:%d in %s", self, serverAddress.c_str(), serverPort, bTLS ? "TLS" : "TCP");
  140.    
  141.     CFStringRef remoteHost = CFStringCreateWithCString(kCFAllocatorDefault, serverAddress.c_str(), kCFStringEncodingMacRoman);
  142.    
  143.     CFReadStreamRef readStream;
  144.     CFWriteStreamRef writeStream;
  145.    
  146.     CFStreamCreatePairWithSocketToHost(NULL, remoteHost, serverPort, &readStream, &writeStream);
  147.    
  148.     // Set options then bridge to ARC:
  149.     if(bTLS)
  150.     {
  151.         NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
  152.                                   (id)kCFStreamSocketSecurityLevelTLSv1, kCFStreamPropertySocketSecurityLevel,
  153.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
  154.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
  155.                                   [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredRoots,
  156.                                   [NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
  157.                                   nil];
  158.  
  159.         /*CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);*/
  160.        
  161.        
  162.         // Set this kCFStreamPropertySocketSecurityLevel before
  163.         // setting kCFStreamPropertySSLSettings.
  164.         // Setting kCFStreamPropertySocketSecurityLevel
  165.         // appears to override previous settings in kCFStreamPropertySSLSettings
  166.         CFReadStreamSetProperty(readStream,
  167.                                 kCFStreamPropertySocketSecurityLevel,
  168.                                 kCFStreamSocketSecurityLevelTLSv1);
  169.         // this disables certificate chain validation in ssl settings.
  170.         NSDictionary *sslSettings =
  171.         [NSDictionary dictionaryWithObjectsAndKeys:
  172.          (id)kCFBooleanFalse, (id)kCFStreamSSLValidatesCertificateChain,
  173.          nil];
  174.         CFReadStreamSetProperty(readStream,
  175.                                 kCFStreamPropertySSLSettings,
  176.                                 (__bridge CFDictionaryRef)sslSettings);
  177.        
  178.        
  179.         CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (__bridge CFDictionaryRef)settings);
  180.        
  181.         CFReadStreamOpen(readStream);
  182.         CFWriteStreamOpen(writeStream);
  183.     }
  184.    
  185.     CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  186.     CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
  187.  
  188.     m_pInputStream = (__bridge_transfer NSInputStream *)readStream;
  189.     m_pOutputStream = (__bridge_transfer NSOutputStream *)writeStream;
  190.    
  191.     [m_pInputStream setDelegate:self];
  192.     [m_pOutputStream setDelegate:self];
  193.    
  194.     recvMessageBuffer.clear();
  195.     sendMessageBuffer.clear();
  196.    
  197.     m_bConnected = false;
  198.     m_bHasSpaceAvailable = false;
  199.  
  200.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
  201.     dispatch_async(queue, ^ {
  202.         // mainRunLoop used instead of currentRunLoop to avoid a crash on Logout
  203.         [m_pInputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  204.         [m_pOutputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  205.        
  206.         [m_pInputStream open];
  207.         [m_pOutputStream open];
  208.        
  209.         [[NSRunLoop currentRunLoop] run];
  210.     });
  211.    
  212.     return true;
  213. }
  214.  
  215. -(void)CloseConnection
  216. {
  217.     NSLog(@"NSStream %p closing connection", self);
  218.  
  219.     SetEvent(m_hSocketClosed);
  220.    
  221.     [self CloseStreams];
  222. }
  223.  
  224. -(void)CloseStreams
  225. {
  226.     m_bConnected = false;
  227.  
  228.     [m_pInputStream close];
  229.     [m_pOutputStream close];
  230.     [m_pInputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  231.     [m_pOutputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  232.    
  233.     recvMessageBuffer.clear();
  234.     sendMessageBuffer.clear();
  235. }
  236.  
  237. // Called as the destructor from the CNSsocket's destructor
  238. -(void)CloseEvents
  239. {
  240.     CloseEvent(m_hSocketError);
  241.     CloseEvent(m_hSocketOpened);
  242.     CloseEvent(m_hSocketDataReceived);
  243.     CloseEvent(m_hSocketClosed);
  244.    
  245.     delete m_pReadMutex;
  246.     delete m_pWriteMutex;
  247. }
  248.  
  249. -(bool)IsConnected
  250. {
  251.     return m_bConnected;
  252. }
  253.  
  254. -(int)Send:(const std::string&)sDataToSend
  255. {
  256.     PAL::Critical_Section cs(*m_pWriteMutex);
  257.     int iRet = sDataToSend.length();
  258.     if(m_bHasSpaceAvailable){
  259.         m_bHasSpaceAvailable = false;
  260.         //NSLog(@"NSStream %p sending data of length %lu", self, sDataToSend.length());
  261.         iRet = [m_pOutputStream write:(const uint8_t *)sDataToSend.c_str() maxLength:sDataToSend.length()];
  262.         //NSLog(@"NSStream %p sent length %d", self, iRet);
  263.     }
  264.     else{
  265.         sendMessageBuffer.push_back(sDataToSend);
  266.     }
  267.     return iRet;
  268. }
  269.  
  270. -(int)Recv:(char *)dataReceived withBufferSize:(int)bufferSize
  271. {
  272.     PAL::Critical_Section cs(*m_pReadMutex);
  273.     int dataLength = 0;
  274.     if (recvMessageBuffer.size() > 0)
  275.     {
  276.         std::string buffer = recvMessageBuffer.front();
  277.         recvMessageBuffer.pop_front();
  278.         dataLength = buffer.length() < bufferSize ? buffer.length() : bufferSize;
  279.         memcpy(dataReceived, buffer.c_str(), dataLength);
  280.         // TODO: if buffer.length is greater than bufferSize then the extra data should be stored back so that next time it returns this
  281.     }
  282.    
  283.     if(dataLength == 0 && [m_pInputStream streamStatus] >= NSStreamStatusClosed)
  284.     {
  285.         NSLog(@"NSStream %p recv error", self);
  286.         return -1;
  287.     }
  288.    
  289.     return dataLength;
  290.  
  291. }
  292.  
  293. -(int)Select:(u_int64_t)uTimeoutValue
  294. {
  295.     int iRet = 0;
  296.  
  297.     const int iNumEvents = 4;
  298.    
  299.     HANDLE EventArray[iNumEvents];
  300.     EventArray[0] = m_hSocketError;
  301.     EventArray[1] = m_hSocketOpened;
  302.     EventArray[2] = m_hSocketDataReceived;
  303.     EventArray[3] = m_hSocketClosed;
  304.  
  305.     DWORD dwWaitStatus = WaitForMultipleObjects(iNumEvents, EventArray, FALSE, uTimeoutValue);
  306.    
  307.     switch (dwWaitStatus)
  308.     {
  309.         case WAIT_FAILED:
  310.             break;
  311.            
  312.         case WAIT_OBJECT_0:
  313.             iRet = -1;
  314.             break;
  315.            
  316.         case WAIT_OBJECT_0 + 1:
  317.             iRet = 1;
  318.             break;
  319.            
  320.         case WAIT_OBJECT_0 + 2:
  321.             iRet = 1;
  322.             break;
  323.            
  324.         case WAIT_OBJECT_0 + 3:
  325.             iRet = 0;
  326.             break;
  327.            
  328.         default:
  329.             break;
  330.     }
  331.    
  332.     return iRet;
  333. }
  334.  
  335. -(void)Signal
  336. {
  337.     SetEvent(m_hSocketDataReceived);
  338. }
  339.  
  340.  
  341. bool openssl_verification(X509 *root_cert, X509 *server_cert) {
  342.    
  343.     OpenSSL_add_all_algorithms();
  344.     ERR_load_BIO_strings();
  345.     ERR_load_crypto_strings();
  346.    
  347.     EVP_PKEY *pkey = X509_get_pubkey(root_cert);
  348.     bool result = X509_verify(server_cert, pkey);
  349.    
  350.     EVP_PKEY_free(pkey);
  351.     X509_free(server_cert);
  352.     X509_free(root_cert);
  353.    
  354.     if(result) {
  355.         NSLog(@"Certificate Verification Success.\n");
  356.     } else {
  357.         NSLog(@"Certificate Verification Failed.\n");
  358.     }
  359.    
  360.     return result;
  361. }
  362.  
  363. /*
  364.  * Returns the leaf certificate from a SecTrust object
  365.  * (that is always the certificate at index 0)
  366.  */
  367. static SecCertificateRef SecTrustGetLeafCertificate(SecTrustRef trust)
  368. {
  369.     SecCertificateRef   result;
  370.    
  371.     assert(trust != NULL);
  372.    
  373.     if (SecTrustGetCertificateCount(trust) > 0) {
  374.         result = SecTrustGetCertificateAtIndex(trust, 0);
  375.         assert(result != NULL);
  376.     } else {
  377.         result = NULL;
  378.     }
  379.     return result;
  380. }
  381.  
  382. #pragma mark -
  383. #pragma mark NSStreamDelegate
  384. - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
  385. {
  386.     // NSLog(@"NSStream %p eventCode: %d", self, (int)eventCode);
  387.    
  388.     switch (eventCode) {
  389.         case NSStreamEventNone:
  390.             break;
  391.            
  392.         case NSStreamEventEndEncountered:
  393.             NSLog(@"NSStreamEventEndEncountered %@", [aStream streamError]);
  394.             [self CloseStreams];
  395.             SetEvent(m_hSocketError);
  396.             break;
  397.            
  398.         case NSStreamEventErrorOccurred:
  399.             NSLog(@"NSStreamEventErrorOccurred %@", [aStream streamError]);
  400.             [self CloseStreams];
  401.             SetEvent(m_hSocketError);
  402.             break;
  403.            
  404.         case NSStreamEventHasBytesAvailable:
  405.         {
  406.             if (aStream == m_pInputStream)
  407.             {
  408.                 PAL::Critical_Section cs(*m_pReadMutex);
  409.                 uint8_t buffer[BUFFER_SIZE];
  410.                 NSInteger bytesRead = [m_pInputStream read:buffer maxLength:BUFFER_SIZE];
  411.                
  412.                 if (0 >= bytesRead)
  413.                     break;
  414.                
  415.                 NSString *nsStringRead = [[NSString alloc] initWithBytes:buffer length:bytesRead encoding:NSUTF8StringEncoding];
  416.                
  417.                 std::string sStringRead = [nsStringRead UTF8String];
  418.                 NSLog(@"recieved data: %s", sStringRead.c_str());
  419.                 recvMessageBuffer.push_back(sStringRead);
  420.                
  421.                 SetEvent(m_hSocketDataReceived);
  422.             }
  423.             break;
  424.         }
  425.         case NSStreamEventHasSpaceAvailable:
  426.         {
  427.             NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  428.             NSString *documentsDirectory = [paths objectAtIndex:0];
  429.             NSError *error2 = nil;
  430.            
  431.             NSString *certPath = [documentsDirectory stringByAppendingPathComponent:@"ss.pem"];
  432.            
  433.             if (![[NSFileManager defaultManager] fileExistsAtPath:certPath])
  434.             {
  435.                 NSLog(@"File Doesn't exist");
  436.             }else {
  437.                 NSLog(@"Certificate Path %@\n",certPath);
  438.             }
  439.            
  440.             NSData * certData = nil;
  441.            
  442.             certData = [NSData dataWithContentsOfFile: certPath options: 1  error: &error2];
  443.             if (error2 || !certData) {
  444.                 NSLog(@"Read failed with error: %@", [error2 localizedDescription]);
  445.             }
  446.             else
  447.             {
  448.                 NSLog(@"Certificate Data: %@\n", certData);
  449.             }
  450.            
  451.             const unsigned char *certificateDataBytes = (const unsigned char *)[certData bytes];
  452.             X509 *certificate2X509 = d2i_X509(NULL, &certificateDataBytes, [certData length]);
  453.            
  454.  
  455.             error2 = nil;
  456.             SecCertificateRef cert = (__bridge SecCertificateRef)[NSData dataWithContentsOfFile: certPath options: 1  error: &error2];
  457.            
  458.            
  459.             if(error2 || !cert)
  460.             {
  461.                 NSLog(@"Certificate Nil: %@",[error2 localizedDescription]);
  462.             }
  463.             else
  464.             {
  465.                 NSLog(@"Certificate is okay: %@", cert);
  466.             }
  467.            
  468.             ///////////////////////////////////////////1. Create Policy////////////////////////////////
  469.        
  470.             SecPolicyRef policy = SecPolicyCreateSSL(NO, CFSTR("www.smartbabymonitor.ugrow.philips.com"));
  471.             if(policy == NULL)
  472.             {
  473.                 NSLog(@"Policy is NULL");
  474.             }
  475.             else
  476.             {
  477.                 NSLog(@"Policy not NULL: %@", policy);
  478.             }
  479.            
  480.            
  481.             CFArrayRef streamCertificates = (CFArrayRef)CFBridgingRetain([aStream propertyForKey:(NSString *) kCFStreamPropertySSLPeerCertificates]);
  482.            
  483.            
  484.             if(streamCertificates == NULL)
  485.             {
  486.                 NSLog(@"NULL streamCertificates");
  487.             }
  488.             else
  489.             {
  490.                 NSLog(@"StreamCertificates is not NULL. Server CERTIFICATES: %@", streamCertificates);
  491.                 // NSLog(@"Astream: %@", aStream);
  492.             }
  493.            
  494.             //////////////////////////////////3. Create trust////////////////////////////////////////////
  495.            
  496.             SecTrustRef trust = NULL;
  497.             OSStatus status = SecTrustCreateWithCertificates(streamCertificates, policy, &trust);
  498.             trust = changeHostForTrust(trust);
  499.            
  500.             if (status != noErr || trust == NULL) {
  501.                 NSLog(@"could not create a trust management object!");
  502.             }
  503.             else
  504.             {
  505.                 NSLog(@"StreamCertificates is created: %@", trust);
  506.                
  507.             }
  508.             NSLog(@"SecTrustCreateWithCertificates STATUS code :%d\n", (int)status); // 0 = errSecSuccess
  509.            
  510.             CFIndex count = SecTrustGetCertificateCount(trust);
  511.             for (CFIndex i = 0; i < count; i++) {
  512.                 SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trust, i);
  513.                 CFStringRef certSummary = SecCertificateCopySubjectSummary(certRef);
  514.                 NSLog(@"Server Certificate: %@", certSummary);
  515.             }
  516.            
  517.             /////////////////////////////4. Set Anchor///////////////////////////////////////
  518.             CFArrayRef certArrayRef = CFArrayCreate(kCFAllocatorDefault, ( const void **)(&cert), (CFIndex) 1, NULL);
  519.             status = SecTrustSetAnchorCertificates(trust, certArrayRef);
  520.             SecCertificateRef certRef = SecTrustGetLeafCertificate(trust);
  521.            
  522.             CFDataRef cfCertRef = SecCertificateCopyData(certRef);
  523.             NSData *certNSData = (__bridge NSData *) cfCertRef;
  524.             NSLog(@"certNSData: %@", certNSData);
  525.            
  526.             const unsigned char *certDataBytes = (const unsigned char *)[certNSData bytes];
  527.             X509 *certificateX509 = d2i_X509(NULL, &certDataBytes, [certNSData length]);
  528.            
  529.             BOOL result = openssl_verification(certificate2X509, certificateX509);
  530.            
  531.             if(!result) {
  532.                 [aStream close];
  533.             }
  534.            
  535.             CFRelease(cfCertRef);
  536.            
  537.             NSLog(@"SecCertificateRef: %@", certRef);
  538.            
  539.             if (status != noErr || trust == NULL) {
  540.                 NSLog(@"could not SecTrustSetAnchorCertificates");
  541.             }
  542.             else
  543.             {
  544.                 NSLog(@"SecTrustSetAnchorCertificates: %@", certArrayRef);
  545.                
  546.             }
  547.            
  548.             // #5
  549.             NSLog(@"SecTrustSetAnchorCertificates STATUS code :%d\n", (int)status);
  550.  
  551.            
  552.             /////////////////////////5. Verify Trust////////////////////////////////////
  553.            
  554.             SecTrustResultType trustResultType = kSecTrustResultInvalid;
  555.            
  556.             // NSLog(@"trustResultType: %d", (int) trustResultType);
  557.            
  558.             status = SecTrustEvaluate(trust, &trustResultType); // issue
  559.             BOOL trusted = NO;
  560.             trusted = (trustResultType == kSecTrustResultUnspecified);
  561.            
  562.             if(trusted) {
  563.                 NSLog(@"We can trust this certificate!\n");
  564.             } else {
  565.                 NSLog(@"We can't trust this certificate!\n");
  566.             }
  567.            
  568.             // NSLog(@"status = %d, trustResultType = %d", (int) status, (int) trustResultType);
  569.            
  570.             switch (trustResultType) {
  571.                 case kSecTrustResultProceed: // 1
  572.                     NSLog(@"kSecTrustResultProceed");
  573.                     break;
  574.                 case kSecTrustResultConfirm: // 2 - deprecated in iOS 7, but still valid in iOS 6
  575.                     NSLog(@"kSecTrustResultConfirm");
  576.                     break;
  577.                 case kSecTrustResultUnspecified: // 4 (expected)
  578.                     NSLog(@"kSecTrustResultUnspecified");
  579.                     break;
  580.                 case kSecTrustResultRecoverableTrustFailure:  // 5
  581.                     NSLog(@"kSecTrustResultRecoverableTrustFailure");
  582.                     break;
  583.                 case kSecTrustResultDeny: // 3
  584.                     NSLog(@"kSecTrustResultDeny");
  585.                     break;
  586.                 case kSecTrustResultFatalTrustFailure: // 6
  587.                     NSLog(@"kSecTrustResultFatalTrustFailure");
  588.                     break;
  589.                 case kSecTrustResultOtherError: // 7
  590.                     NSLog(@"kSecTrustResultOtherError");
  591.                     break;
  592.                 case kSecTrustResultInvalid: // 0
  593.                     NSLog(@"kSecTrustResultInvalid");
  594.                     break;
  595.                 default:
  596.                     NSLog(@"default");
  597.                     break;
  598.             }
  599.            
  600.             if (status == errSecSuccess) {
  601.                 if (trustResultType == kSecTrustResultUnspecified) {
  602.                     NSLog(@"We can trust this certificate! TrustResultType: %d", trustResultType);
  603.                 } else {
  604.                     NSLog(@"Cannot trust certificate. TrustResultType: %d", trustResultType);
  605.                     // [aStream close];
  606.                 }
  607.             } else {
  608.                 NSLog(@"Creating trust failed: %d", (int) status);
  609.                 // [aStream close];
  610.             }
  611.            
  612.             if (trust) {
  613.                 CFRelease(trust);
  614.                 NSLog(@"Trust Released.\n");
  615.             }
  616.             if (policy) {
  617.                 CFRelease(policy);
  618.                 NSLog(@"Policy Released.\n");
  619.             }
  620.  
  621.             NSLog(@".......................................................\n\n");
  622.            
  623.             if(aStream == m_pOutputStream)
  624.             {
  625.                 PAL::Critical_Section cs(*m_pWriteMutex);
  626.                 m_bHasSpaceAvailable = true;
  627.                 if(sendMessageBuffer.size() > 0)
  628.                 {
  629.                     std::string sDataToSend = sendMessageBuffer.front();
  630.                     sendMessageBuffer.pop_front();
  631.                     int iWritten = 0;
  632.                     if(sDataToSend.length() > 0)
  633.                     {
  634.                         m_bHasSpaceAvailable = false;
  635.                         iWritten = [m_pOutputStream write:(const uint8_t *)sDataToSend.c_str() maxLength:sDataToSend.length()];
  636.                     }
  637.                 }
  638.             }
  639.            
  640.             // SetEvent(m_hSocketOpened);
  641.         }
  642.         break;
  643.         case NSStreamEventOpenCompleted:
  644.             NSLog(@"NSStreamEventOpenCompleted");
  645.             m_bConnected = true;
  646.             //SetEvent(m_hSocketOpened);
  647.             break;
  648.            
  649.         default:
  650.             //NSLog(@"NSStream default");
  651.             break;
  652.     }
  653. }
  654.  
  655. @end
  656.  
  657. /**********************************************************
  658.  CNSsocket implementation
  659.  **********************************************************/
  660.  
  661.  
  662. CNSsocket::CNSsocket()
  663. {
  664.     m_pNSsocket = [[NSsocket alloc] init];
  665. }
  666.  
  667. CNSsocket::~CNSsocket()
  668. {
  669.     CloseConnection();
  670.     [m_pNSsocket CloseEvents];
  671. }
  672.  
  673. // [TODO] we MUST check the connection status
  674.  
  675. bool CNSsocket::CreateAndConnect(const std::string& serverAddress, const u_int16_t& serverPort, bool bTLS)
  676. {
  677.     return [m_pNSsocket CreateAndConnect:serverAddress withPort:serverPort withTransportMode:bTLS];
  678. }
  679.  
  680. void CNSsocket::GetLocalAddressAndPort(std::string& serverAddress, u_int16_t& serverPort)
  681. {
  682.     CFWriteStreamRef writeStream = (__bridge CFWriteStreamRef) [m_pNSsocket GetStream:false];
  683.    
  684.     // Get the native socket handle:
  685.     CFTypeRef socketTypeRef = CFWriteStreamCopyProperty(writeStream, kCFStreamPropertySocketNativeHandle);
  686.     if(socketTypeRef == NULL)
  687.     {
  688.         NSLog(@"Error in getting native socket handle");
  689.         serverAddress = "";
  690.         serverPort = 0;
  691.        
  692.         return;
  693.     }
  694.  
  695.     CFDataRef socketData = (CFDataRef)socketTypeRef;
  696.     CFSocketNativeHandle socket;
  697.     CFDataGetBytes(socketData, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8 *)&socket);
  698.    
  699.     // Get the local socket address from the socket handle:
  700.     struct sockaddr_storage sa;
  701.     socklen_t salen = sizeof(sa);
  702.     getsockname(socket, (struct sockaddr *)&sa, &salen);
  703.    
  704.     // Get numeric host and port from socket address:
  705.     char host[NI_MAXHOST];
  706.     char service[NI_MAXSERV];
  707.     getnameinfo((struct sockaddr *)&sa, salen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST|NI_NUMERICSERV);
  708.    
  709.     serverAddress = std::string(host);
  710.     serverPort = (u_int16_t)atoi(service);
  711.    
  712.     NSLog(@"Local address: %s, local port: %d", serverAddress.c_str(), serverPort);
  713. }
  714.  
  715. void CNSsocket::CloseConnection()
  716. {
  717.     [m_pNSsocket CloseConnection];
  718. }
  719.  
  720. int CNSsocket::Send(const char* dataToSend, int sizeOfData)
  721. {
  722.     return [m_pNSsocket Send:std::string(dataToSend, sizeOfData)];
  723. }
  724.  
  725. int CNSsocket::Recv(char dataReceived[], int bufferSize)
  726. {
  727.     return [m_pNSsocket Recv:dataReceived withBufferSize:bufferSize];
  728. }
  729.  
  730.  
  731. // [TODO] We should use callback instead of select() to reduce processing cost.
  732. // This needs to be called after invoking CreateAndConnect to get connection status.
  733.  
  734. int CNSsocket::Select(u_int64_t timeOutValue)
  735. {
  736.     return [m_pNSsocket Select:timeOutValue];
  737. }
  738.  
  739. int CNSsocket::WaitForConnect(u_int64_t timeOutValue)
  740. {
  741.     u_int64_t slept = 0;
  742.     const u_int64_t duration = 50;
  743.     while(slept < timeOutValue){
  744.         if([m_pNSsocket IsConnected])
  745.             return 1;
  746.         usleep(duration * 1000);
  747.         slept += duration;
  748.     }
  749.     return [m_pNSsocket IsConnected] ? 1 : -1;
  750. }
  751.  
  752. void CNSsocket::Signal()
  753. {
  754.     [m_pNSsocket Signal];
  755. }
Advertisement
Add Comment
Please, Sign In to add comment