bool SOSAccountSendIKSPSyncList(SOSAccountRef account, CFErrorRef *error){
    bool result = true;
    __block CFErrorRef localError = NULL;
    __block CFMutableArrayRef ids = NULL;
    SOSCircleRef circle = NULL;
    
    require_action_quiet(SOSAccountIsInCircle(account, NULL), xit,
                         SOSCreateError(kSOSErrorNoCircle, CFSTR("This device is not in circle"),
                                        NULL, &localError));
    
    circle  = SOSAccountGetCircle(account, error);
    ids = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
    
    SOSCircleForEachValidPeer(circle, account->user_public, ^(SOSPeerInfoRef peer) {
        if (!SOSAccountIsThisPeerIDMe(account, SOSPeerInfoGetPeerID(peer))) {
            if(SOSPeerInfoShouldUseIDSTransport(SOSFullPeerInfoGetPeerInfo(account->my_identity), peer) &&
               SOSPeerInfoShouldUseIDSMessageFragmentation(SOSFullPeerInfoGetPeerInfo(account->my_identity), peer) &&
               !SOSPeerInfoShouldUseACKModel(SOSFullPeerInfoGetPeerInfo(account->my_identity), peer)){
                SOSTransportMessageIDSSetFragmentationPreference(account->ids_message_transport, kCFBooleanTrue);
                CFStringRef deviceID = SOSPeerInfoCopyDeviceID(peer);
                if(deviceID != NULL){
                    CFArrayAppendValue(ids, deviceID);
                }
                CFReleaseNull(deviceID);
            }
        }
    });
static void tests(void)
{
    SOSCircleRef circle = SOSCircleCreate(NULL, CFSTR("TEST DOMAIN"), NULL);
    
    ok(NULL != circle, "Circle creation");

    ok(0 == SOSCircleCountPeers(circle), "Zero peers");

    //SecKeyRef publicKey = NULL;
    SecKeyRef dev_a_key = NULL;
    SecKeyRef dev_b_key = NULL;
    CFErrorRef error = NULL;
    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
    
    if(cfpassword == NULL) printf("WTF\n");
    
    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
    ok(parameters, "No parameters!");
    ok(error == NULL, "Error: (%@)", error);
    CFReleaseNull(error);

    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
    CFReleaseNull(parameters);

    SOSFullPeerInfoRef peer_a_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer A"), &dev_a_key, NULL);
    
    SOSFullPeerInfoRef peer_b_full_info = SOSCreateFullPeerInfoFromName(CFSTR("Peer B"), &dev_b_key, NULL);
    
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));

    ok(SOSCircleAcceptRequest(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
    
    ok(!SOSCircleRequestAdmission(circle, user_privkey, peer_a_full_info, NULL));
    ok(SOSCircleRequestAdmission(circle, user_privkey, peer_b_full_info, NULL));
    
    ok(SOSCircleCountPeers(circle) == 1, "Peer count");

    size_t size = SOSCircleGetDEREncodedSize(circle, &error);
    uint8_t buffer[size];
    uint8_t* start = SOSCircleEncodeToDER(circle, &error, buffer, buffer + sizeof(buffer));
    
    ok(start, "successful encoding");
    ok(start == buffer, "Used whole buffer");
    
    const uint8_t *der = buffer;
    SOSCircleRef inflated = SOSCircleCreateFromDER(NULL, &error, &der, buffer + sizeof(buffer));
    
    ok(inflated, "inflated");
    ok(CFEqualSafe(inflated, circle), "Compares");
    
    
    ok(SOSCircleRemovePeer(circle, user_privkey, peer_a_full_info, SOSFullPeerInfoGetPeerInfo(peer_a_full_info), NULL));
    ok(SOSCircleCountPeers(circle) == 0, "Peer count");
    
    CFReleaseNull(dev_a_key);
    CFReleaseNull(cfpassword);
}
Esempio n. 3
0
bool SOSAccountIsMyPeerActiveInCircleNamed(SOSAccountRef account, CFStringRef circle_name, CFErrorRef* error) {
    SOSFullPeerInfoRef myfpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, circle_name, NULL);
    if(!myfpi) return false;
    SOSPeerInfoRef mypi = SOSFullPeerInfoGetPeerInfo(myfpi);
    if(!mypi) return false;
    CFStringRef peerid = SOSPeerInfoGetPeerID(mypi);
    if (!peerid) return false;
    return SOSAccountIsActivePeerInCircleNamed(account, circle_name, peerid, error);
}
static bool SOSAccountIsThisPeerIDMe(SOSAccountRef account, CFStringRef peerID) {
    SOSPeerInfoRef mypi = SOSFullPeerInfoGetPeerInfo(account->my_identity);
    CFStringRef myPeerID = SOSPeerInfoGetPeerID(mypi);
    
    return myPeerID && CFEqualSafe(myPeerID, peerID);
}
static void tests(void)
{
    CFErrorRef error = NULL;
    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);
    CFStringRef cfaccount = CFSTR("*****@*****.**");
    CFStringRef circle_name = CFSTR("TestSource");
    
    CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault);

    SOSAccountRef alice_account = CreateAccountForLocalChanges(CFSTR("Alice"), circle_name);
    SOSAccountRef bob_account = CreateAccountForLocalChanges(CFSTR("Bob"), circle_name);
    SOSAccountRef carole_account = CreateAccountForLocalChanges(CFSTR("Carole"), circle_name);
    
    ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
    
    // Bob wins writing at this point, feed the changes back to alice.
    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 1, "updates");

    ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
    CFReleaseNull(error);
    
    ok(SOSAccountAssertUserCredentialsAndUpdate(carole_account, cfaccount, cfpassword, &error), "Credential setting (%@)", error);
    CFReleaseNull(error);
    ok(SOSAccountResetToOffering_wTxn(alice_account, &error), "Reset to offering (%@)", error);
    CFReleaseNull(error);

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 2, "updates");

    ok(SOSAccountJoinCircles_wTxn(bob_account, &error), "Bob Applies (%@)", error);
    CFReleaseNull(error);

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 2, "updates");

    {
        CFArrayRef applicants = SOSAccountCopyApplicants(alice_account, &error);
        
        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
        ok(SOSAccountAcceptApplicants(alice_account, applicants, &error), "Alice accepts (%@)", error);
        CFReleaseNull(error);
        CFReleaseNull(applicants);
    }
    
    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 3, "updates");

    accounts_agree("bob&alice pair", bob_account, alice_account);
    
    CFArrayRef peers = SOSAccountCopyPeers(alice_account, &error);
    ok(peers && CFArrayGetCount(peers) == 2, "See two peers %@ (%@)", peers, error);
    CFReleaseNull(peers);
    
    SOSFullPeerInfoRef fpiAlice = SOSAccountGetMyFullPeerInfo(alice_account);
    CFStringRef alice_id = CFStringCreateCopy(NULL, SOSPeerInfoGetPeerID(SOSFullPeerInfoGetPeerInfo(fpiAlice)));
    
    ok(SOSAccountLeaveCircle(alice_account, &error), "Alice Leaves (%@)", error);
    CFReleaseNull(error);
    CFReleaseNull(cfpassword);
    
    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 2, "updates");

    accounts_agree("Alice bails", bob_account, alice_account);
    accounts_agree("Alice bails", bob_account, carole_account);
    
    SOSAccountCleanupRetirementTickets(bob_account, 0, &error);

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 1, "updates");

    //is(CFDictionaryGetCountOfValue(BobChanges, kCFNull),0, "0 Keys Nulled Out");
    
    ok(SOSAccountJoinCircles_wTxn(carole_account, &error), "Carole Applies (%@)", error);
    CFReleaseNull(error);

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 2, "updates");

    
    {
        CFArrayRef applicants = SOSAccountCopyApplicants(bob_account, &error);
        
        ok(applicants && CFArrayGetCount(applicants) == 1, "See one applicant %@ (%@)", applicants, error);
        ok(SOSAccountAcceptApplicants(bob_account, applicants, &error), "Bob accepts Carole (%@)", error);
        CFReleaseNull(error);
        CFReleaseNull(applicants);
    }
    
    // Bob should not yet cleanup Alice's retirment here on his own since it hasn't been long enough
    // by default.
    //is(CFDictionaryGetCountOfValue(BobChanges, kCFNull),0, "0 Keys Nulled Out");

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 3, "updates");

    accounts_agree("Carole joins", bob_account, carole_account);
    
    SOSAccountCleanupRetirementTickets(bob_account, 0, &error);

    is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 1, "updates");

    is(countPeers(bob_account), 2, "Active peers after forced cleanup");
    is(countActivePeers(bob_account), 3, "Inactive peers after forced cleanup");
    
    //is(CFDictionaryGetCountOfValue(BobChanges, kCFNull), 1, "1 Keys Nulled Out");
    
//    CFDictionaryForEach(BobChanges, ^(const void *key, const void *value) {
//        if(isNull(value)) {
//            CFStringRef circle_name = NULL, retiree = NULL;
//            SOSKVSKeyType keytype = SOSKVSKeyGetKeyTypeAndParse(key, &circle_name, &retiree, NULL);
//            is(keytype, kRetirementKey, "Expect only a retirement key");
//            ok(CFEqualSafe(alice_id, retiree), "Alice (%@) is retiree (%@)", alice_id, retiree);
//            CFReleaseNull(circle_name);
//            CFReleaseNull(retiree);
//        }
//    });

    CFReleaseNull(alice_id);
    CFReleaseNull(carole_account);
    CFReleaseNull(bob_account);
    CFReleaseNull(alice_account);
    
    SOSTestCleanup();
}
Esempio n. 6
0
bool SOSAccountIsMyPeerActiveInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
    SOSFullPeerInfoRef fpi = SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, SOSCircleGetName(circle), NULL);
    if(!fpi) return false;
    return SOSCircleHasActivePeer(circle, SOSFullPeerInfoGetPeerInfo(fpi), error);
}
Esempio n. 7
0
SOSPeerInfoRef SOSAccountGetMyPeerInCircleNamed(SOSAccountRef account, CFStringRef name, CFErrorRef *error)
{
    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, name, error);
    
    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
}
Esempio n. 8
0
SOSPeerInfoRef SOSAccountGetMyPeerInCircle(SOSAccountRef account, SOSCircleRef circle, CFErrorRef* error) {
    SOSFullPeerInfoRef fpi =  SOSAccountGetMyFullPeerInCircleNamedIfPresent(account, SOSCircleGetName(circle), error);
    
    return fpi ? SOSFullPeerInfoGetPeerInfo(fpi) : NULL;
}
static void tests()
{
    CFErrorRef error = NULL;

    CFStringRef aliceID = CFSTR("Alice");
    CFStringRef bobID = CFSTR("Bob");    // not really remote, just another client on same machine

    SecKeyRef alice_key = NULL;
    SecKeyRef bob_key = NULL;

    CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10);

    CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error);
    ok(parameters, "No parameters!");
    ok(error == NULL, "Error: (%@)", error);
    CFReleaseNull(error);

    SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, &error);
    CFReleaseNull(parameters);
    CFReleaseSafe(cfpassword);

    CFStringRef circleName = CFSTR("Woot Circle");

    SOSFullPeerInfoRef alice_full_peer_info = SOSCreateFullPeerInfoFromName(aliceID, &alice_key, &error);
    SOSPeerInfoRef alice_peer_info = SOSFullPeerInfoGetPeerInfo(alice_full_peer_info);

    SOSFullPeerInfoRef bob_full_peer_info = SOSCreateFullPeerInfoFromName(bobID, &bob_key, &error);
    SOSPeerInfoRef bob_peer_info = SOSFullPeerInfoGetPeerInfo(bob_full_peer_info);

    SOSCircleRef aliceCircle = SOSCircleCreate(kCFAllocatorDefault, circleName, &error);

    ok(SOSCircleRequestAdmission(aliceCircle, user_privkey, alice_full_peer_info, &error));
    ok(SOSCircleAcceptRequests(aliceCircle, user_privkey, alice_full_peer_info, NULL));
    ok(SOSCircleRequestAdmission(aliceCircle, user_privkey, bob_full_peer_info, &error), "requested admission");
    ok(SOSCircleAcceptRequests(aliceCircle, user_privkey, bob_full_peer_info, &error), "accepted them all!");

    alice_peer_info = SOSFullPeerInfoGetPeerInfo(alice_full_peer_info);
    bob_peer_info = SOSFullPeerInfoGetPeerInfo(bob_full_peer_info);

    CFDataRef aliceCircleEncoded;
    ok(aliceCircleEncoded = SOSCircleCopyEncodedData(aliceCircle, kCFAllocatorDefault, &error), "encode alice circle: %@", error);
    CFReleaseNull(error);
    SOSCircleRef bobCircle;
    ok(bobCircle = SOSCircleCreateFromData(0, aliceCircleEncoded, &error), "decode bobCircle: %@", error);
    CFReleaseNull(aliceCircleEncoded);
    CFReleaseNull(error);

    /* Transport. */
    __block CFDataRef queued_message = NULL;
    
    SOSPeerSendBlock enqueueMessage =  ^bool (CFDataRef message, CFErrorRef *error) {
        if (queued_message)
            fail("We already had an unproccessed message");
        
        queued_message = (CFDataRef) CFRetain(message);
        return true;
    };
    
    CFDataRef (^dequeueMessage)() = ^CFDataRef () {
        CFDataRef result = queued_message;
        queued_message = NULL;
        
        return result;
    };

    /* DataSource */
    SOSDataSourceRef aliceDs = SOSTestDataSourceCreate();
    SOSDataSourceRef bobDs = SOSTestDataSourceCreate();
    
    SOSDataSourceFactoryRef aliceDsf = SOSTestDataSourceFactoryCreate();
    SOSTestDataSourceFactoryAddDataSource(aliceDsf, circleName, aliceDs);

    SOSDataSourceFactoryRef bobDsf = SOSTestDataSourceFactoryCreate();
    SOSTestDataSourceFactoryAddDataSource(bobDsf, circleName, bobDs);
    
    /* Test passing peer messages to the engine. */
    CFDataRef message;

    CFStringRef bob_peer_id = SOSPeerInfoGetPeerID(bob_peer_info);

    /* Hand an empty message to the engine for handeling. */
    message = CFDataCreate(NULL, NULL, 0);
    is(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error), false,
       "empty message rejected, %@", error);

    CFReleaseNull(error);
    CFReleaseNull(message);

    ok(SOSCircleSyncWithPeer(alice_full_peer_info, aliceCircle, aliceDsf, enqueueMessage, bob_peer_id, &error), "Start sync [error %@]", error);
    CFReleaseNull(error);

    ok(message = dequeueMessage(), "Alice sent message");
    CFStringRef alice_peer_id = SOSPeerInfoGetPeerID(alice_peer_info);
    is(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error), true,
       "Bob accepted message: %@", error);
    CFReleaseNull(message);

#if 1
    CFStringRef desc = NULL;
    ok(message = dequeueMessage(), "we got a message from Bob %@", desc = SOSMessageCopyDescription(message));
    ok(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error),
       "Alice accepted message: %@", error);
    CFReleaseNull(message);
    CFReleaseNull(desc);

    ok(message = dequeueMessage(), "we got a reply from Alice %@", desc = SOSMessageCopyDescription(message));
    ok(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error),
       "Bob accepted message: %@", error);
    CFReleaseNull(message);
    CFReleaseNull(desc);
#endif

#if 0
    message = dequeueMessage();
    ok(NULL == message, "we got no message from Bob %@", desc = SOSMessageCopyDescription(message));

    SOSObjectRef object = SOSDataSourceCreateGenericItem(aliceDs, CFSTR("75_circle_engine_account"), CFSTR("test service"));
    ok(SOSTestDataSourceAddObject(aliceDs, object, &error), "add empty object to datasource: %@", error);
    CFReleaseNull(error);
    CFReleaseNull(object);

    ok(SOSCircleSyncWithPeer(alice_full_peer_info, aliceCircle, aliceDsf, enqueueMessage, bob_peer_id, &error), "Restart sync [error %@]", error);
    CFReleaseNull(error);
    
    ok(message = dequeueMessage(), "Alice started again %@", desc = SOSMessageCopyDescription(message));
    is(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error), true,
       "bob accepted %@: %@", SOSMessageCopyDescription(message), error);
    CFReleaseNull(error);
    CFReleaseNull(message);
#endif

#if 1
    bool alice = true;
    int max_loops = 50;
    while (max_loops-- && NULL != (message = dequeueMessage())) {
        if (alice) {
            ok(SOSCircleHandlePeerMessage(aliceCircle, alice_full_peer_info, aliceDsf, enqueueMessage, bob_peer_id, message, &error),
               "alice accepted %@: %@", desc = SOSMessageCopyDescription(message), error);
        } else {
            ok(SOSCircleHandlePeerMessage(bobCircle, bob_full_peer_info, bobDsf, enqueueMessage, alice_peer_id, message, &error),
               "bob accepted %@: %@", desc = SOSMessageCopyDescription(message), error);
        }
        alice = !alice;
        CFRelease(message);
        CFReleaseNull(desc);
    }
#endif

    CFReleaseNull(aliceCircle);
    CFReleaseNull(bobCircle);

    CFReleaseNull(alice_peer_info);
    CFReleaseNull(bob_peer_info);

    CFReleaseNull(alice_key);
    CFReleaseNull(bob_key);
    aliceDsf->release(aliceDsf);
    bobDsf->release(bobDsf);
}