This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH setup draft 3/4] Try cygwin signing key for private mirrors


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]