This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
[PATCH setup draft 3/4] Try cygwin signing key for private mirrors
- From: Ken Brown <kbrown at cornell dot edu>
- To: cygwin-apps at cygwin dot com
- Date: Mon, 11 Dec 2017 16:41:35 -0500
- Subject: [PATCH setup draft 3/4] Try cygwin signing key for private mirrors
- Authentication-results: sourceware.org; auth=none
- References: <20171211214136.6500-1-kbrown@cornell.edu>
If validation with the cygwin signing key fails for a purported
private mirror, retry with other supplied keys. If this succeeds,
silently change the status of the site to "user site" and put a note
in the log file. This change will take effect on the next setup run
or if the user selects 'Back'.
This uses a new optional argument 'retry_sig_ok' to
ini.cc:check_ini_sig(). If this is 'true', don't destroy ini_file and
ini_sig_file on a validation failure.
---
ini.cc | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
site.h | 2 ++
2 files changed, 57 insertions(+), 10 deletions(-)
diff --git a/ini.cc b/ini.cc
index 4be8263..62b7e83 100644
--- a/ini.cc
+++ b/ini.cc
@@ -18,6 +18,8 @@
flex parsers are provided also. We check to see if this setup.ini
is older than the one we used last time, and if so, warn the user. */
+#include <algorithm>
+
#include "ini.h"
#include "csu_util/rfc1738.h"
@@ -173,7 +175,7 @@ decompress_ini (io_stream *ini_file)
static io_stream*
check_ini_sig (io_stream* ini_file, io_stream* ini_sig_file,
bool& sig_fail, const char* site, const char* sig_name,
- HWND owner, bool main_key_only = false)
+ HWND owner, bool main_key_only = false, bool retry_sig_ok = false)
{
/* Unless the NoVerifyOption is set, check the signature for the
current setup and record the result. On a failed signature check
@@ -195,12 +197,15 @@ check_ini_sig (io_stream* ini_file, io_stream* ini_sig_file,
}
else if (!verify_ini_file_sig (ini_file, ini_sig_file, owner, main_key_only))
{
- note (owner, IDS_SIG_INVALID, sig_name, site);
- delete ini_sig_file;
- ini_sig_file = NULL;
- delete ini_file;
- ini_file = NULL;
sig_fail = true;
+ if (!retry_sig_ok)
+ {
+ note (owner, IDS_SIG_INVALID, sig_name, site);
+ delete ini_sig_file;
+ ini_sig_file = NULL;
+ delete ini_file;
+ ini_file = NULL;
+ }
}
}
return ini_file;
@@ -265,6 +270,27 @@ do_local_ini (HWND owner)
return ini_error;
}
+static void
+mirror_warn (site_list_type site)
+{
+ Log (LOG_BABBLE) << "Signature validation failed for " << site.url
+ << " using the cygwin key but succeeded using other keys. "
+ << endLog;
+ Log (LOG_BABBLE) << "Changing status from 'mirror' to 'user site'." << endLog;
+ SiteList::iterator i = find (all_site_list.begin (), all_site_list.end (), site);
+ if (i != all_site_list.end ())
+ {
+ all_site_list.erase (i);
+ site_list_type newsite (site.url, "", "", "", false, false);
+ all_site_list.push_back (newsite);
+ selected_usersite_list.push_back (newsite);
+ SiteList::iterator j = find (selected_mirror_list.begin (),
+ selected_mirror_list.end (), site);
+ if (j != selected_mirror_list.end ())
+ selected_mirror_list.erase (j);
+ }
+}
+
static bool
do_remote_ini (HWND owner)
{
@@ -293,14 +319,33 @@ do_remote_ini (HWND owner)
ini_sig_file = get_url_to_membuf (current_ini_sig_name, owner);
ini_file = get_url_to_membuf (current_ini_name, owner);
- // Official mirrors must be signed by the cygwin key.
- bool main_key_only = n->from_mirrors_lst;
+ // Mirrors should be signed by the cygwin key.
+ bool main_key_only = n->is_mirror;
+
+ // If this fails for a purported private mirror, allow a
+ // retry with additional keys; if this succeeds, reclassify
+ // the site as a user site.
+ bool retry_sig_ok = n->is_mirror && !n->from_mirrors_lst;
+ retry:
ini_file = check_ini_sig (ini_file, ini_sig_file, sig_fail,
- n->url.c_str (), current_ini_sig_name.c_str (), owner, main_key_only);
+ n->url.c_str (),
+ current_ini_sig_name.c_str (), owner,
+ main_key_only, retry_sig_ok);
+ if (retry_sig_ok && sig_fail)
+ {
+ sig_fail = false;
+ retry_sig_ok = false;
+ main_key_only = false;
+ goto retry;
+ }
// stop searching as soon as we find a setup file
if (ini_file)
- break;
+ {
+ if (n->is_mirror && !main_key_only)
+ mirror_warn (*n);
+ break;
+ }
}
if (ini_file)
ini_file = decompress_ini (ini_file);
diff --git a/site.h b/site.h
index 3525931..5b01829 100644
--- a/site.h
+++ b/site.h
@@ -79,6 +79,8 @@ typedef std::vector <site_list_type> SiteList;
/* user chosen sites */
extern SiteList site_list;
+extern SiteList selected_mirror_list;
+extern SiteList selected_usersite_list;
/* potential sites */
extern SiteList all_site_list;
--
2.15.1