From a7c6b32ca254a8764231723145cdce9803e1bae1 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 29 Aug 2014 13:35:51 -0700 Subject: [PATCH] scheduler: changes to allow the code signing key to be changed. Aargh! My checkin of 31 Aug 2011 causes the client to strip the trailing \n from the code-signing key; this change affects 7.0+ clients. This broke the documented protocol for changing code-signing keys, since signatures for the new key with the trailing \n won't work. Solution: when you change code-signing key, you have to sign both the stripped and non-stripped versions of the new public key. See http://boinc.berkeley.edu/trac/wiki/CodeSigning This required a change to the scheduler so that it sends one signature or the other based on client version (stripped for 7.0+, else unstripped). This change is entirely within send_code_sign_key(), in case you want to update just that. --- sched/handle_request.cpp | 127 +++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/sched/handle_request.cpp b/sched/handle_request.cpp index e43b5dabbb..0e04c4111c 100644 --- a/sched/handle_request.cpp +++ b/sched/handle_request.cpp @@ -834,7 +834,7 @@ int handle_global_prefs() { // if the client has an old code sign public key, // send it the new one, with a signature based on the old one. // If they don't have a code sign key, send them one. -// Return false if they have a key we recognize +// Return false if they have a key we don't recognize // (in which case we won't send them work). // bool send_code_sign_key(char* code_sign_key) { @@ -842,70 +842,79 @@ bool send_code_sign_key(char* code_sign_key) { int i, retval; char path[MAXPATHLEN]; - if (strlen(g_request->code_sign_key)) { - if (strcmp(g_request->code_sign_key, code_sign_key)) { - log_messages.printf(MSG_NORMAL, "received old code sign key\n"); + if (!strlen(g_request->code_sign_key)) { + safe_strcpy(g_reply->code_sign_key, code_sign_key); + return true; + } + if (!strcmp(g_request->code_sign_key, code_sign_key)) { + return true; + } - // look for a signature file for the key the client has. - // these are in pairs of files (N = 0, 1, ...) - // old_key_N: contains an old key - // signature_N: contains a signature for new key, - // based on the old key - // A project can have several of these pairs if it wants, - // e.g. if it changes keys a lot. + log_messages.printf(MSG_NORMAL, "received old code sign key\n"); + + // look for a signature file for the client's key. + // These are in pairs of files (N = 0, 1, ...) + // old_key_N: contains an old key + // signature_N: contains a signature for new key, + // based on the old key + // signature_stripped_N: signature for new key w/ trailing \n removed + // (needed for 7.0+ clients, which strip trailing whitespace) + // + // A project can have several of these if it wants, + // e.g. if it changes keys a lot. + // + for (i=0; ; i++) { + sprintf(path, "%s/old_key_%d", config.key_dir, i); + retval = read_file_malloc(path, oldkey); + if (retval) { + // we've scanned all the signature files and + // didn't find one that worked. + // User must reattach. // - for (i=0; ; i++) { - sprintf(path, "%s/old_key_%d", config.key_dir, i); - retval = read_file_malloc(path, oldkey); - if (retval) { - // we've scanned all the signature files and - // didn't find one that worked. - // User must reattach. - // - g_reply->insert_message( - _("Invalid code signing key. To fix, remove and add this project."), - "notice" - ); - return false; - } - strip_whitespace(oldkey); - if (!strcmp(oldkey, g_request->code_sign_key)) { - // We've found the client's key. - // Get the signature for the new key. - // - sprintf(path, "%s/signature_%d", config.key_dir, i); - retval = read_file_malloc(path, signature); - if (retval) { - // project is missing the signature file. - // Tell the user to reattach. - // - g_reply->insert_message( - _("The project has changed its security key. Please remove and add this project."), - "notice" - ); - log_messages.printf(MSG_CRITICAL, - "Missing signature file for old key %d\n", i - ); - free(oldkey); - return false; - } else { - log_messages.printf(MSG_NORMAL, - "sending new code sign key and signature\n" - ); - safe_strcpy(g_reply->code_sign_key, code_sign_key); - safe_strcpy(g_reply->code_sign_key_signature, signature); - free(signature); - free(oldkey); - return true; - } - } + log_messages.printf(MSG_CRITICAL, + "scanned old_key_i files, can find client's key\n" + ); + break; + } + strip_whitespace(oldkey); + if (!strcmp(oldkey, g_request->code_sign_key)) { + // We've found the client's key. + // Get the signature for the new key. + // + if (g_request->core_client_major_version < 7) { + sprintf(path, "%s/signature_%d", config.key_dir, i); + } else { + sprintf(path, "%s/signature_stripped_%d", config.key_dir, i); + } + retval = read_file_malloc(path, signature); + if (retval) { + // project is missing the signature file. + // Tell the user to reattach. + // + log_messages.printf(MSG_CRITICAL, + "Missing signature file for old key %d\n", i + ); free(oldkey); + break; + } else { + log_messages.printf(MSG_NORMAL, + "sending new code sign key and signature\n" + ); + safe_strcpy(g_reply->code_sign_key, code_sign_key); + safe_strcpy(g_reply->code_sign_key_signature, signature); + free(signature); + free(oldkey); + return true; } } - } else { - safe_strcpy(g_reply->code_sign_key, code_sign_key); + free(oldkey); } - return true; + + g_reply->insert_message( + _("The project has changed its security key. Please remove and add this project."), + "notice" + ); + return false; } // If is set,