aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-07-12 17:25:28 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-14 17:56:54 +0300
commit7ea82c5013ab3c3d44b4b85cf767559e7019854f (patch)
tree24369f953efa5b3aa6b8b44937150f195f8f23e0
parentdb5ac510d317fc3d9c2c881257e8c6a25851ea1c (diff)
Add --cert-* rep-info command options
-rw-r--r--bpkg/auth8
-rw-r--r--bpkg/auth.cxx11
-rw-r--r--bpkg/openssl.cxx1
-rw-r--r--bpkg/rep-info.cli38
-rw-r--r--bpkg/rep-info.cxx81
-rwxr-xr-xtests/test.sh8
6 files changed, 140 insertions, 7 deletions
diff --git a/bpkg/auth b/bpkg/auth
index 3d1ff65..a608667 100644
--- a/bpkg/auth
+++ b/bpkg/auth
@@ -91,6 +91,14 @@ namespace bpkg
const string& key_name, // --key option value
const string& cert_pem,
const dir_path& repository);
+
+ // Parse a repository certificate. The repository location argument is used
+ // for diagnostics only.
+ //
+ shared_ptr<certificate>
+ parse_certificate (const common_options&,
+ const string& cert_pem,
+ const repository_location&);
}
#endif // BPKG_AUTH
diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx
index 673e3ec..c152834 100644
--- a/bpkg/auth.cxx
+++ b/bpkg/auth.cxx
@@ -844,4 +844,15 @@ namespace bpkg
throw failed ();
}
+
+ shared_ptr<certificate>
+ parse_certificate (const common_options& co,
+ const string& cert_pem,
+ const repository_location& rl)
+ {
+ return parse_cert (co,
+ real_fingerprint (co, cert_pem, rl),
+ cert_pem,
+ rl.canonical_name ());
+ }
}
diff --git a/bpkg/openssl.cxx b/bpkg/openssl.cxx
index 67500b6..4e795cb 100644
--- a/bpkg/openssl.cxx
+++ b/bpkg/openssl.cxx
@@ -5,7 +5,6 @@
#include <bpkg/openssl>
#include <butl/process>
-#include <butl/fdstream>
#include <bpkg/diagnostics>
diff --git a/bpkg/rep-info.cli b/bpkg/rep-info.cli
index 5fa5d3d..faa6456 100644
--- a/bpkg/rep-info.cli
+++ b/bpkg/rep-info.cli
@@ -21,10 +21,14 @@ namespace bpkg
The \cb{rep-info} command prints various information about the specified
repository. By default it print the repository's name and location as the
- first line followed by the list of complement and prerequisite
- repositories and the list of available packages. This default behavior,
- however, can be altered in various ways using options listed below. Note
- that the information is written to \cb{STDOUT}, not \cb{STDERR}.
+ first line. If the repository is signed, the certificate information
+ (name/organization/email) is printed as the next line following by the
+ certificate fingerprint. Then comes the list of complement and
+ prerequisite repositories followed by the list of available packages.
+
+ This default format can be altered in various ways using options listed
+ below. Note also that the information is written to \cb{STDOUT}, not
+ \cb{STDERR}.
If the current working directory contains a \cb{bpkg} configuration, then
\cb{rep-info} will use its certificate database for the repository
@@ -42,7 +46,31 @@ namespace bpkg
bool --name|-n
{
- "Print the specified repository's name and location."
+ "Print the repository's name and location."
+ }
+
+ bool --cert-fingerprint
+ {
+ "Print the repository's certificate fingerprint or empty line if the
+ repository is unsigned."
+ }
+
+ bool --cert-name
+ {
+ "Print the repository's certificate common name (CN) or empty line if
+ the repository is unsigned."
+ }
+
+ bool --cert-organization
+ {
+ "Print the repository's certificate organization name (O) or empty line
+ if the repository is unsigned."
+ }
+
+ bool --cert-email
+ {
+ "Print the repository's certificate email or empty line if the
+ repository is unsigned."
}
bool --repositories|-r
diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx
index 9cad4fd..765bc70 100644
--- a/bpkg/rep-info.cxx
+++ b/bpkg/rep-info.cxx
@@ -6,6 +6,8 @@
#include <iostream> // cout
+#include <butl/sha256> // sha256_to_fingerprint()
+
#include <bpkg/manifest>
#include <bpkg/manifest-serializer>
@@ -94,7 +96,15 @@ namespace bpkg
// Now print.
//
- bool all (!o.name () && !o.repositories () && !o.packages ());
+ bool cert_info (o.cert_fingerprint () ||
+ o.cert_name () ||
+ o.cert_organization () ||
+ o.cert_email ());
+
+ bool all (!o.name () &&
+ !o.repositories () &&
+ !o.packages () &&
+ !cert_info);
try
{
@@ -103,6 +113,75 @@ namespace bpkg
if (all || o.name ())
cout << rl.canonical_name () << " " << rl << endl;
+ // Certificate.
+ //
+ if (all || cert_info)
+ {
+ if (cert_pem)
+ {
+ // Repository is signed. If we got the repository certificate as the
+ // result of authentication then use it for printing as well.
+ // Otherwise parse it's PEM representation.
+ //
+ if (cert == nullptr)
+ cert = parse_certificate (o, *cert_pem, rl);
+ else
+ assert (!cert->dummy ());
+ }
+ else if (cert != nullptr)
+ {
+ // Reset the dummy certificate pointer that we got as a result of
+ // the unsigned repository authentication.
+ //
+ assert (cert->dummy ());
+ cert = nullptr;
+ }
+
+ if (all)
+ {
+ // Print in the human-friendly format (nothing for an unsigned
+ // repository).
+ //
+ if (cert != nullptr)
+ cout << "CN=" << cert->name << "/O=" << cert->organization <<
+ "/" << cert->email << endl
+ << sha256_to_fingerprint (cert->fingerprint) << endl;
+ }
+ else
+ {
+ // Print in the structured format if any of --cert-* options are
+ // specified. Print empty lines for an unsigned repository.
+ //
+ if (o.cert_fingerprint ())
+ {
+ if (cert != nullptr)
+ cout << sha256_to_fingerprint (cert->fingerprint);
+ cout << endl;
+ }
+
+ if (o.cert_name ())
+ {
+ if (cert != nullptr)
+ cout << "name:" << cert->name;
+ cout << endl;
+ }
+
+ if (o.cert_organization ())
+ {
+ if (cert != nullptr)
+ cout << cert->organization;
+ cout << endl;
+ }
+
+ if (o.cert_email ())
+ {
+ if (cert != nullptr)
+ cout << cert->email;
+ cout << endl;
+ }
+ }
+ }
+
// Repositories.
//
if (all || o.repositories ())
diff --git a/tests/test.sh b/tests/test.sh
index b630bda..5f92c7c 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -1587,22 +1587,30 @@ fail rep-fetch --trust-yes # packages file signature:mismatch
test cfg-create --wipe
test rep-info --trust-no --trust $signed_fp -d $cfg $rep/auth/signed <<EOF
${repn}auth/signed `location auth/signed`
+CN=build2.org/O=Code Synthesis/info@build2.org
+$signed_fp
libfoo 1.0.0
EOF
test rep-info --trust-no -d $cfg $rep/auth/signed <<EOF
${repn}auth/signed `location auth/signed`
+CN=build2.org/O=Code Synthesis/info@build2.org
+$signed_fp
libfoo 1.0.0
EOF
test cfg-create --wipe
test rep-info --trust-yes $rep/auth/signed <<EOF
${repn}auth/signed `location auth/signed`
+CN=build2.org/O=Code Synthesis/info@build2.org
+$signed_fp
libfoo 1.0.0
EOF
fail rep-info --trust-no $rep/auth/signed <<EOF
${repn}auth/signed `location auth/signed`
+CN=build2.org/O=Code Synthesis/info@build2.org
+$signed_fp
libfoo 1.0.0
EOF