diff options
author | Michael Vogt <michael.vogt@ubuntu.com> | 2008-08-06 14:00:02 +0200 |
---|---|---|
committer | Michael Vogt <michael.vogt@ubuntu.com> | 2008-08-06 14:00:02 +0200 |
commit | cbf217843cc8eaaebd6d798854d92aab961efd9d (patch) | |
tree | cdec428db26249b5fb395bdf315dabd87384250a | |
parent | ff38d63b19c0be1fb4be9a692fed2702d935d5e5 (diff) | |
parent | 5aa95c863d9bc5b0de7dd1279d3ad672193cc3a6 (diff) |
* merge patch that enforces stricter https server certificate
checking (thanks to Arnaud Ebalard, closes: #485960)
* allow per-mirror specific https settings
(thanks to Arnaud Ebalard, closes: #485965)
* add doc/examples/apt-https-method-example.cof
(thanks to Arnaud Ebalard, closes: #485964)
* add DPkg::NoTriggers option so that applications that call
apt/aptitude (like the installer) defer trigger processing
(thanks to Joey Hess)
* document --install-recommends and --no-install-recommends
(thanks to Dereck Wonnacott, LP: #126180)
* apt-ftparchive might write corrupt Release files (LP: #46439)
* Apply --important option to apt-cache depends (LP: #16947)
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 5 | ||||
-rw-r--r-- | cmdline/apt-cache.cc | 14 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | debian/changelog | 20 | ||||
-rw-r--r-- | doc/apt-cache.8.xml | 2 | ||||
-rw-r--r-- | doc/apt-get.8.xml | 8 | ||||
-rw-r--r-- | doc/examples/apt-https-method-example.conf | 165 | ||||
-rw-r--r-- | ftparchive/writer.h | 2 | ||||
-rw-r--r-- | methods/https.cc | 59 |
9 files changed, 254 insertions, 23 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ede1673bc..a3f32e3c5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -556,6 +556,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) { unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024); unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024); + bool NoTriggers = _config->FindB("DPkg::NoTriggers",false); if (RunScripts("DPkg::Pre-Invoke") == false) return false; @@ -606,7 +607,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) PackageProcessingOps.insert( make_pair("install",N_("Installing %s")) ); PackageProcessingOps.insert( make_pair("configure",N_("Configuring %s")) ); PackageProcessingOps.insert( make_pair("remove",N_("Removing %s")) ); - PackageProcessingOps.insert( make_pair("trigproc",N_("Triggering %s")) ); + PackageProcessingOps.insert( make_pair("trigproc",N_("Running post-installation trigger %s")) ); // init the PackageOps map, go over the list of packages that // that will be [installed|configured|removed|purged] and add @@ -691,6 +692,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) case Item::Configure: Args[n++] = "--configure"; + if (NoTriggers) + Args[n++] = "--no-triggers"; Size += strlen(Args[n-1]); break; diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index f10ea48be..a73e35a53 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -102,15 +102,13 @@ bool UnMet(CommandLine &CmdL) if (End->Type != pkgCache::Dep::PreDepends && End->Type != pkgCache::Dep::Depends && End->Type != pkgCache::Dep::Suggests && - End->Type != pkgCache::Dep::Recommends && - End->Type != pkgCache::Dep::DpkgBreaks) + End->Type != pkgCache::Dep::Recommends) continue; // Important deps only if (Important == true) if (End->Type != pkgCache::Dep::PreDepends && - End->Type != pkgCache::Dep::Depends && - End->Type != pkgCache::Dep::DpkgBreaks) + End->Type != pkgCache::Dep::Depends) continue; // Verify the or group @@ -557,6 +555,7 @@ bool Depends(CommandLine &CmdL) bool Recurse = _config->FindB("APT::Cache::RecurseDepends",false); bool Installed = _config->FindB("APT::Cache::Installed",false); + bool Important = _config->FindB("APT::Cache::Important",false); bool DidSomething; do { @@ -579,7 +578,12 @@ bool Depends(CommandLine &CmdL) for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) { - + // Important deps only + if (Important == true) + if (D->Type != pkgCache::Dep::PreDepends && + D->Type != pkgCache::Dep::Depends) + continue; + pkgCache::PkgIterator Trg = D.TargetPkg(); if((Installed && Trg->CurrentVer != 0) || !Installed) diff --git a/configure.in b/configure.in index b9368ae8c..cb229a68d 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ AC_CONFIG_AUX_DIR(buildlib) AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in) dnl -- SET THIS TO THE RELEASE VERSION -- -AC_DEFINE_UNQUOTED(VERSION,"0.7.14ubuntu3") +AC_DEFINE_UNQUOTED(VERSION,"0.7.14ubuntu4") PACKAGE="apt" AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE") AC_SUBST(PACKAGE) diff --git a/debian/changelog b/debian/changelog index fb5fc9f77..91724d164 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,26 @@ apt (0.7.14ubuntu4) intrepid; urgency=low + [ Michael Vogt ] * apt-pkg/deb/dpkgpm.cc: - fix uninitialized variable that caused no apport reports to be written sometimes (thanks to Matt Zimmerman) - - -- + * merge patch that enforces stricter https server certificate + checking (thanks to Arnaud Ebalard, closes: #485960) + * allow per-mirror specific https settings + (thanks to Arnaud Ebalard, closes: #485965) + * add doc/examples/apt-https-method-example.cof + (thanks to Arnaud Ebalard, closes: #485964) + * add DPkg::NoTriggers option so that applications that call + apt/aptitude (like the installer) defer trigger processing + (thanks to Joey Hess) + * document --install-recommends and --no-install-recommends + (thanks to Dereck Wonnacott, LP: #126180) + + [ Dereck Wonnacott ] + * apt-ftparchive might write corrupt Release files (LP: #46439) + * Apply --important option to apt-cache depends (LP: #16947) + + -- Michael Vogt <michael.vogt@ubuntu.com> Tue, 05 Aug 2008 10:10:49 +0200 apt (0.7.14ubuntu3) intrepid; urgency=low diff --git a/doc/apt-cache.8.xml b/doc/apt-cache.8.xml index c1e65332d..c359ac3d8 100644 --- a/doc/apt-cache.8.xml +++ b/doc/apt-cache.8.xml @@ -289,7 +289,7 @@ Reverse Provides: </varlistentry> <varlistentry><term><option>-i</option></term><term><option>--important</option></term> - <listitem><para>Print only important dependencies; for use with unmet. Causes only Depends and + <listitem><para>Print only important dependencies; for use with unmet and depends. Causes only Depends and Pre-Depends relations to be printed. Configuration Item: <literal>APT::Cache::Important</literal>.</para></listitem> </varlistentry> diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml index 329a46c51..edb74270b 100644 --- a/doc/apt-get.8.xml +++ b/doc/apt-get.8.xml @@ -313,6 +313,14 @@ Configuration Item: <literal>APT::Get::Compile</literal>.</para></listitem> </varlistentry> + <varlistentry><term><option>--install-recommends</option></term> + <listitem><para>Also install recommended packages.</para></listitem> + </varlistentry> + + <varlistentry><term><option>--no-install-recommends</option></term> + <listitem><para>Do not install recommended packages.</para></listitem> + </varlistentry> + <varlistentry><term><option>--ignore-hold</option></term> <listitem><para>Ignore package Holds; This causes <command>apt-get</command> to ignore a hold placed on a package. This may be useful in conjunction with diff --git a/doc/examples/apt-https-method-example.conf b/doc/examples/apt-https-method-example.conf new file mode 100644 index 000000000..0067171bd --- /dev/null +++ b/doc/examples/apt-https-method-example.conf @@ -0,0 +1,165 @@ +/* This file is a sample configuration for apt https method. Configuration + parameters found in this example file are expected to be used in main + apt.conf file, just like other configuration parameters for different + methods (ftp, file, ...). + + This example file starts with a common setup that voluntarily exhibits + all available configurations knobs with simple comments. Extended + comments on the behavior of the option is provided at the end for + better readibility. As a matter of fact, a common configuration file + will certainly contain far less elements and benefit of default values + for many parameters. + + Because some configuration parameters for apt https method in following + examples apply to specific (fictional) repositories, the associated + sources.list file is provided here: + + ... + + deb https://secure.dom1.tld/debian unstable main contrib non-free + deb-src https://secure.dom1.tld/debian unstable main contrib non-free + + deb https://secure.dom2.tld/debian unstable main contrib non-free + deb-src https://secure.dom2.tld/debian unstable main contrib non-free + + ... + + + Some notes on the servers: + + - secure.dom1.tld is freely accessible using https (no client + authentication is required). + - secure.dom1.tld certificate is part of a multi level PKI, and we + want to specifically check the issuer of its certificate. We do + not have the constraint for secure.dom2.tld + - secure.dom2.tld requires client authentication by certificate + to access its content. + - The certificate presented by both server have (as expected) a CN that + matches their respective DNS names. + - It somtimes happens that we had other more generic https available + repository to our list. We want the checks to be performed against + a common list of anchors (like the one provided by ca-certificates + package for instance) + + The sample configuration below basically covers those simpe needs. +*/ + + +// Verify peer certificate and also matching between certificate name +// and server name as provided in sources.list (default values) +Acquire::https::Verify-Peer "true"; +Acquire::https::Verify-Host "true"; + +// Except otherwise specified, use that list of anchors +Acquire::https::CaInfo "/etc/ssl/certs/ca-certificates.pem"; + +// Use a specific anchor and associated CRL. Enforce issuer of +// server certificate using its cert. +Acquire::https::secure.dom1.tld::CaInfo "/etc/apt/certs/ca-dom1-crt.pem"; + +// Like previous for anchor and CRL, but also provide our +// certificate and keys for client authentication. +Acquire::https::secure.dom2.tld::CaInfo "/etc/apt/certs/ca-dom2-crt.pem"; +Acquire::https::secure.dom2.tld::SslCert "/etc/apt/certs/my-crt.pem"; +Acquire::https::secure.dom2.tld::SslKey "/etc/apt/certs/my-key.pem"; + +// No need to downgrade, TLS will be proposed by default. Uncomment +// to have SSLv3 proposed. +// Acquire::https::mirror.ipv6.ssi.corp::SslForceVersion "SSLv3"; + +// No need for more debug if every is fine (default). Uncomment +// me to get additional information. +// Debug::Acquire::https "true"; + + +/* + Options with extended comments: + + Acquire::https[::repo.domain.tld]::CaInfo "/path/to/ca/certs.pem"; + + A string providing the path of a file containing the list of trusted + CA certificates used to verify the server certificate. The pointed + file is made of the concatenation of the CA certificates (in + PEM format) creating the chain used for the verification of the path + from the root (self signed one). If the remote server provides the + whole chain during the exchange, the file need only contain the root + certificate. Otherwise, the whole chain is required. + + If you need to support multiple authorities, the only way is to + concatenate everything. + + If None is provided, the default CA bundle used by GnuTLS (apt https + method is linked against libcurl-gnutls) is used. At the time of + writing, /etc/ssl/certs/ca-certificates.crt. + + If no specific hostname is provided, the file is used by default + for all https targets. If a specific mirror is provided, it is + used for the https entries in the sources.list file that use that + repository (with the same name). + + Acquire::https[::repo.domain.tld]::Verify-Peer "true"; + + When authenticating the server, if the certificate verification fails + for some reason (expired, revoked, man in the middle, lack of anchor, + ...), the connection fails. This is obviously what you want in all + cases and what the default value (true) of this option provides. + + If you know EXACTLY what you are doing, setting this option to "false" + allow you to skip peer certificate verification and make the exchange + succeed. Again, this option is for debugging or testing purpose only. + It removes ALL the security provided by the use of SSL.TLS to secure + the HTTP exchanges. + + Acquire::https[::repo.domain.tld]::Verify-Host "true"; + + The certificate provided by the server during the TLS/SSL exchange + provides the identity of the server which should match the DNS name + used to access it. By default, as requested by RFC 2818, the name + of the mirror is checked against the identity found in the + certificate. This default behavior is safe and should not be + changed. If you know that the server you are using has a DNS name + which does not match the identity in its certificate, you can + [report that issue to its administrator or] set the option to + "false", which will prevent the comparison to be done. + + The options can be set globally or on a per-mirror basis. If set + globally, the DNS name used is the one found in the sources.list + file in the https URI. + + Acquire::https[::repo.domain.tld]::SslCert "/path/to/client/cert.pem"; + Acquire::https[::repo.domain.tld]::SslKey "/path/to/client/key.pem"; + + These two options provides support for client authentication using + certificates. They respectively accept the X.509 client certificate + in PEM format and the associated client key in PEM format (non + encrypted form). + + The options can be set globally (which rarely makes sense) or on a + per-mirror basis. + + Acquire::https[::repo.domain.tld]::SslForceVersion "TLSv1"; + + This option can be use to select the version which will be proposed + to the server. "SSLv3" and "TLSv1" are supported. SSLv2, which is + considered insecure anyway is not supported (by gnutls, which is + used by libcurl against which apt https method is linked). + + When the option is set to "SSLv3" to have apt propose SSLv3 (and + associated sets of ciphersuites) instead of TLSv1 (the default) + when performing the exchange. This prevents the server to select + TLSv1 and use associated cipheruites. You should probably not use + this option except if you know exactly what you are doing. + + Note that the default setting does not guarantee that the server + will not select SSLv3 (for ciphersuites and SSL/TLS version as + selectio is always done by the server, in the end). It only means + that apt will not advertise TLS support. + + Debug::Acquire::https "true"; + + This option can be used to show debug information. Because it is + quite verbose, it is mainly useful to debug problems in case of + failure to connect to a server for some reason. The default value + is "false". + +*/ diff --git a/ftparchive/writer.h b/ftparchive/writer.h index a4e4356f9..6e161c752 100644 --- a/ftparchive/writer.h +++ b/ftparchive/writer.h @@ -52,7 +52,7 @@ class FTWScanner { if (ErrorPrinted == false && Quiet <= Priority) { - cout << endl; + c1out << endl; ErrorPrinted = true; } } diff --git a/methods/https.cc b/methods/https.cc index b0b05a47e..e53ba1a11 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -108,6 +108,8 @@ bool HttpsMethod::Fetch(FetchItem *Itm) struct curl_slist *headers=NULL; char curl_errorstr[CURL_ERROR_SIZE]; long curl_responsecode; + URI Uri = Itm->Uri; + string remotehost = Uri.Host; // TODO: // - http::Pipeline-Depth @@ -127,23 +129,56 @@ bool HttpsMethod::Fetch(FetchItem *Itm) curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); curl_easy_setopt(curl, CURLOPT_FILETIME, true); - // FIXME: https: offer various options of verification - bool peer_verify = _config->FindB("Acquire::https::Verify-Peer", false); + // SSL parameters are set by default to the common (non mirror-specific) value + // if available (or a default one) and gets overload by mirror-specific ones. + + // File containing the list of trusted CA. + string cainfo = _config->Find("Acquire::https::CaInfo",""); + string knob = "Acquire::https::"+remotehost+"::CaInfo"; + cainfo = _config->Find(knob.c_str(),cainfo.c_str()); + if(cainfo != "") + curl_easy_setopt(curl, CURLOPT_CAINFO,cainfo.c_str()); + + // Check server certificate against previous CA list ... + bool peer_verify = _config->FindB("Acquire::https::Verify-Peer",true); + knob = "Acquire::https::" + remotehost + "::Verify-Peer"; + peer_verify = _config->FindB(knob.c_str(), peer_verify); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, peer_verify); - // sslcert file + // ... and hostname against cert CN or subjectAltName + int default_verify = 2; + bool verify = _config->FindB("Acquire::https::Verify-Host",true); + knob = "Acquire::https::"+remotehost+"::Verify-Host"; + verify = _config->FindB(knob.c_str(),verify); + if (!verify) + default_verify = 0; + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verify); + + // For client authentication, certificate file ... string pem = _config->Find("Acquire::https::SslCert",""); + knob = "Acquire::https::"+remotehost+"::SslCert"; + pem = _config->Find(knob.c_str(),pem.c_str()); if(pem != "") curl_easy_setopt(curl, CURLOPT_SSLCERT, pem.c_str()); - - // CA-Dir - string certdir = _config->Find("Acquire::https::CaPath",""); - if(certdir != "") - curl_easy_setopt(curl, CURLOPT_CAPATH, certdir.c_str()); - - // Server-verify - int verify = _config->FindI("Acquire::https::Verify-Host",2); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, verify); + + // ... and associated key. + string key = _config->Find("Acquire::https::SslKey",""); + knob = "Acquire::https::"+remotehost+"::SslKey"; + key = _config->Find(knob.c_str(),key.c_str()); + if(key != "") + curl_easy_setopt(curl, CURLOPT_SSLKEY, key.c_str()); + + // Allow forcing SSL version to SSLv3 or TLSv1 (SSLv2 is not + // supported by GnuTLS). + long final_version = CURL_SSLVERSION_DEFAULT; + string sslversion = _config->Find("Acquire::https::SslForceVersion",""); + knob = "Acquire::https::"+remotehost+"::SslForceVersion"; + sslversion = _config->Find(knob.c_str(),sslversion.c_str()); + if(sslversion == "TLSv1") + final_version = CURL_SSLVERSION_TLSv1; + else if(sslversion == "SSLv3") + final_version = CURL_SSLVERSION_SSLv3; + curl_easy_setopt(curl, CURLOPT_SSLVERSION, final_version); // cache-control if(_config->FindB("Acquire::http::No-Cache",false) == false) |