}
#endif
-static const char *concordstring[] = {
+static const char * __unused concordstring[] = {
"kSOSConcordanceTrusted",
"kSOSConcordanceGenOld", // kSOSErrorReplay
"kSOSConcordanceNoUserSig", // kSOSErrorBadSignature
static bool SOSAccountIsPeerRetired(SOSAccountRef account, CFSetRef peers){
- CFMutableArrayRef peerIDs = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
+ CFMutableArrayRef peerInfos = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault);
bool result = false;
CFSetForEach(peers, ^(const void *value) {
SOSPeerInfoRef peer = (SOSPeerInfoRef)value;
if(SOSPeerInfoIsRetirementTicket(peer))
- CFArrayAppendValue(peerIDs, peer);
+ CFArrayAppendValue(peerInfos, peer);
});
- if(CFArrayGetCount(peerIDs) > 0){
- if(!SOSAccountRemoveBackupPeers(account, peerIDs, NULL))
- secerror("Could not remove peers: %@, from the backup", peerIDs);
+ if(CFArrayGetCount(peerInfos) > 0){
+ if(!SOSAccountRemoveBackupPeers(account, peerInfos, NULL))
+ secerror("Could not remove peers: %@, from the backup", peerInfos);
else
return true;
}
else
result = true;
+ CFReleaseNull(peerInfos);
+
return result;
}
}
+typedef enum {
+ accept,
+ countersign,
+ leave,
+ revert,
+ modify,
+ ignore
+} ringAction_t;
+
+static const char * __unused actionstring[] = {
+ "accept", "countersign", "leave", "revert", "modify", "ignore",
+};
+
bool SOSAccountHandleUpdateRing(SOSAccountRef account, SOSRingRef prospectiveRing, bool writeUpdate, CFErrorRef *error) {
bool success = true;
bool haveOldRing = true;
- const char *localRemote = writeUpdate ? "local": "remote";
+ const char * __unused localRemote = writeUpdate ? "local": "remote";
SOSFullPeerInfoRef fpi = account->my_identity;
SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi);
CFStringRef peerID = SOSPeerInfoGetPeerID(pi);
- bool neverWrite = !(fpi && pi && peerID && SOSAccountIsInCircle(account, NULL));
-
- secinfo("signing", "start:[%s] %@", localRemote, prospectiveRing);
+ bool peerActive = (fpi && pi && peerID && SOSAccountIsInCircle(account, NULL));
+
- require_action_quiet(!(writeUpdate && neverWrite), errOut, SOSCreateError(kSOSErrorNotReady, CFSTR("Can't update from local if FullPeerInfo not present"), NULL, error));
+ secdebug("ringSigning", "start:[%s] %@", localRemote, prospectiveRing);
require_quiet(SOSAccountHasPublicKey(account, error), errOut);
require_action_quiet(prospectiveRing, errOut,
SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("No Ring to work with"), NULL, error));
+ require_action_quiet(SOSRingIsStable(prospectiveRing), errOut, SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("You give rings a bad name"), NULL, error));
+
// We should at least have a sane ring system in the account object
require_quiet(SOSAccountCheckForRings(account, error), errOut);
CFStringRef ringName = SOSRingGetName(prospectiveRing);
- SOSRingRef oldRing = SOSAccountGetRing(account, ringName, NULL);
+ SOSRingRef oldRing = SOSAccountCopyRing(account, ringName, NULL);
SOSTransportCircleRef transport = account->circle_transport;
-
- // SOSAccountScanForRetired(account, prospectiveRing, error);
SOSRingRef newRing = CFRetainSafe(prospectiveRing); // TODO: SOSAccountCloneRingWithRetirement(account, prospectiveRing, error);
- typedef enum {
- accept,
- countersign,
- leave,
- revert,
- modify,
- ignore
- } ringAction_t;
-
- static const char *actionstring[] = {
- "accept", "countersign", "leave", "revert", "modify", "ignore",
- };
-
ringAction_t ringAction = ignore;
- enum DepartureReason leaveReason = kSOSNeverLeftCircle;
bool userTrustedoldRing = true;
#endif
if (!oldRing) {
- oldRing = newRing;
+ oldRing = CFRetainSafe(newRing);
}
SOSConcordanceStatus concstat = SOSRingConcordanceTrust(fpi, peers, oldRing, newRing, oldKey, account->user_public, peerID, error);
case kSOSConcordanceNoPeerSig:
ringAction = accept; // We might like this one eventually but don't countersign.
concStr = CFSTR("No trusted peer signature");
- secerror("##### No trusted peer signature found, accepting hoping for concordance later %@", newRing);
+ secnotice("signing", "##### No trusted peer signature found, accepting hoping for concordance later %@", newRing);
break;
case kSOSConcordanceNoPeer:
ringAction = leave;
- leaveReason = kSOSLeftUntrustedCircle;
concStr = CFSTR("No trusted peer left");
break;
case kSOSConcordanceNoUserKey:
break;
}
- secnotice("signing", "Decided on action [%s] based on concordance state [%s] and [%s] circle.", actionstring[ringAction], concordstring[concstat], userTrustedoldRing ? "trusted" : "untrusted");
+ (void)concStr;
+
+ secdebug("ringSigning", "Decided on action [%s] based on concordance state [%s] and [%s] circle.", actionstring[ringAction], concordstring[concstat], userTrustedoldRing ? "trusted" : "untrusted");
SOSRingRef ringToPush = NULL;
bool iWasInOldRing = peerID && SOSRingHasPeerID(oldRing, peerID);
bool iAmInNewRing = peerID && SOSRingHasPeerID(newRing, peerID);
bool ringIsBackup = SOSRingGetType(newRing) == kSOSRingBackup;
- if (ringIsBackup && !neverWrite) {
+ if (ringIsBackup && peerActive) {
if (ringAction == accept || ringAction == countersign) {
CFErrorRef localError = NULL;
SOSBackupSliceKeyBagRef bskb = SOSRingCopyBackupSliceKeyBag(newRing, &localError);
if(!bskb) {
- secnotice("signing", "Backup ring with no backup slice keybag (%@)", localError);
+ secnotice("ringSigning", "Backup ring with no backup slice keybag (%@)", localError);
} else if (SOSAccountBackupSliceKeyBagNeedsFix(account, bskb)) {
ringAction = modify;
}
if (ringAction == modify) {
CFErrorRef updateError = NULL;
- CFDictionarySetValue(account->trusted_rings, ringName, newRing);
+ SOSAccountSetRing(account, newRing, ringName, error);
if(SOSAccountUpdateOurPeerInBackup(account, newRing, &updateError)) {
secdebug("signing", "Modified backup ring to include us");
if (sosAccountLeaveRing(account, newRing, error)) {
ringToPush = newRing;
} else {
- secnotice("signing", "Can't leave ring %@", oldRing);
+ secdebug("ringSigning", "Can't leave ring %@", oldRing);
success = false;
}
- account->departure_code = leaveReason;
ringAction = accept;
} else {
// We are not in this ring, but we need to update account with it, since we got it from cloud
- secnotice("signing", "We are not in this ring, but we need to update account with it");
ringAction = accept;
}
}
if (ringAction == countersign) {
if (iAmInNewRing) {
if (SOSRingPeerTrusted(newRing, fpi, NULL)) {
- secinfo("signing", "Already concur with: %@", newRing);
+ secdebug("ringSigning", "Already concur with: %@", newRing);
} else {
CFErrorRef signingError = NULL;
if (fpi && SOSRingConcordanceSign(newRing, fpi, &signingError)) {
ringToPush = newRing;
- secinfo("signing", "Concurred with: %@", newRing);
} else {
- secerror("Failed to concurrence sign, error: %@ Old: %@ New: %@", signingError, oldRing, newRing);
+ secerror("Failed to concordance sign, error: %@ Old: %@ New: %@", signingError, oldRing, newRing);
success = false;
}
CFReleaseSafe(signingError);
}
} else {
- secnotice("signing", "Not countersigning, not in ring: %@", newRing);
+ secdebug("ringSigning", "Not countersigning, not in ring: %@", newRing);
}
ringAction = accept;
}
SOSRingRemoveRejection(newRing, peerID);
}
- CFRetainSafe(oldRing);
- CFDictionarySetValue(account->trusted_rings, ringName, newRing);
- // TODO: Why was this? SOSAccountSetPreviousPublic(account);
-
- secnotice("signing", "%@, Accepting ring: %@", concStr, newRing);
+ SOSAccountSetRing(account, newRing, ringName, error);
if (pi && account->user_public_trusted
&& SOSRingHasApplicant(oldRing, peerID)
// Our application is declared lost, let us reapply.
if (SOSRingApply(newRing, account->user_public, fpi, NULL))
- writeUpdate = true;
+ if(peerActive) writeUpdate = true;
}
if (pi && SOSRingHasPeerID(oldRing, peerID)) {
SOSAccountCleanupRetirementTickets(account, RETIREMENT_FINALIZATION_SECONDS, NULL);
}
- CFReleaseNull(oldRing);
account->circle_rings_retirements_need_attention = true;
- if (writeUpdate && !neverWrite)
+ if (writeUpdate)
ringToPush = newRing;
- SOSUpdateKeyInterest();
+ account->key_interests_need_updating = true;
}
/*
*/
if (ringAction == revert) {
- if(haveOldRing && !neverWrite && SOSRingHasPeerID(oldRing, peerID)) {
- secnotice("signing", "%@, Rejecting: %@ re-publishing %@", concStr, newRing, oldRing);
+ if(haveOldRing && peerActive && SOSRingHasPeerID(oldRing, peerID)) {
+ secdebug("ringSigning", "%@, Rejecting: %@ re-publishing %@", concStr, newRing, oldRing);
ringToPush = oldRing;
} else {
- secnotice("canary", "%@, Rejecting: %@ Have no old circle - would reset", concStr, newRing);
+ secdebug("ringSigning", "%@, Rejecting: %@ Have no old circle - would reset", concStr, newRing);
}
}
if (ringToPush != NULL) {
- secnotice("signing", "Pushing:[%s] %@", localRemote, ringToPush);
+ secdebug("ringSigning", "Pushing:[%s] %@", localRemote, ringToPush);
CFDataRef ringData = SOSRingCopyEncodedData(ringToPush, error);
if (ringData) {
success &= SOSTransportCircleRingPostRing(transport, SOSRingGetName(ringToPush), ringData, error);
}
CFReleaseNull(ringData);
}
-
+ CFReleaseNull(oldRing);
CFReleaseSafe(newRing);
return success;
errOut: