Skip to content

Commit

Permalink
Add zypper keys command
Browse files Browse the repository at this point in the history
  • Loading branch information
bzeller committed Mar 16, 2018
1 parent 1c564cd commit f9f6cda
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 42 deletions.
12 changes: 12 additions & 0 deletions doc/zypper.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,18 @@ Package locks serve the purpose of preventing changes to the set of installed pa
+
This command looks for locks that do not currently (with regard to repositories used) lock any package and for each such lock it asks user whether to remove it.


Key Management
~~~~~~~~~~~~~~
The *keys* command lists keys from the internal trust database.

*keys* (*lk*) ['options'] ['key-id'] ['key-filename'] ...::
List all trusted keys or show detailed information about those specified as arguments, supports also keyfiles as argument.
+
--
*-d*, *--detail*::
Shows the keys in a more detailed multiline output, also shows subkey information
--

Other Commands
~~~~~~~~~~~~~~
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SET (zypper_HEADERS
ps.h
SolverRequester.h
Summary.h
keys.h
callbacks/keyring.h
callbacks/media.h
callbacks/rpm.h
Expand Down Expand Up @@ -60,6 +61,7 @@ SET( zypper_SRCS
RequestFeedback.cc
SolverRequester.cc
Summary.cc
keys.cc
callbacks/media.cc
${zypper_HEADERS}
)
Expand Down
2 changes: 2 additions & 0 deletions src/Command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ namespace
//_t( RUG_INFO_REQUIREMENTS_e )| "info-obsoletes" | "io";
_t( RUG_PATCH_SEARCH_e ) | "patch-search" | "pse";
_t( RUG_PING_e ) | "ping";

_t( KEYS_e ) | "keys" | "lk";
#undef _t
}
return _table;
Expand Down
7 changes: 6 additions & 1 deletion src/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct ZypperCommand
static const ZypperCommand RUG_PATCH_SEARCH;
static const ZypperCommand RUG_PING;
//!@}
//!

static const ZypperCommand KEYS;

enum Command
{
Expand Down Expand Up @@ -167,7 +170,9 @@ struct ZypperCommand
//RUG_INFO_OBSOLETES_e,
//RUG_INFO_REQUIREMENTS_e,
RUG_PATCH_SEARCH_e,
RUG_PING_e
RUG_PING_e,

KEYS_e,
};

ZypperCommand( Command command ) : _command(command) {}
Expand Down
41 changes: 41 additions & 0 deletions src/Zypper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "source-download.h"
#include "configtest.h"
#include "subcommand.h"
#include "keys.h"

#include "output/OutNormal.h"
#include "output/OutXML.h"
Expand Down Expand Up @@ -788,6 +789,12 @@ void print_main_help( Zypper & zypper )
"\tzypper <subcommand> [--command-options] [arguments]\n"
);

static std::string help_keys_commands = _(" Key Management:\n"
"\tkeys, lk\t\tList all keys.\n"
//"\taddkey, as\t\tAdd a new key.\n"
//"\tremovekey, rs\tRemove a key from trust.\n"
);

zypper.out().info( help_usage, Out::QUIET );
zypper.out().info( help_global_options, Out::QUIET );
zypper.out().info( repo_manager_options, Out::QUIET );
Expand All @@ -800,6 +807,7 @@ void print_main_help( Zypper & zypper )
zypper.out().info( help_update_commands, Out::QUIET );
zypper.out().info( help_query_commands, Out::QUIET );
zypper.out().info( help_lock_commands, Out::QUIET );
zypper.out().info( help_keys_commands, Out::QUIET );
zypper.out().info( help_other_commands, Out::QUIET );
zypper.out().info( help_subcommands, Out::QUIET );

Expand Down Expand Up @@ -3464,6 +3472,28 @@ void Zypper::processCommandOptions()
break;
}

case ZypperCommand::KEYS_e:
{
static struct option list_updates_options[] = {
{"details", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
specific_options = list_updates_options;

_command_help = CommandHelpFormater()
.synopsis( // translators: command synopsis; do not translate lowercase words
_("keys [OPTIONS] [KEYID] [KEYFILE] ...")
)
.description(// translators: command description
_("List all trusted keys.")
)
.optionSectionCommandOptions()
.option(_("-d, --detail" "\n" "Show more details."))
;
break;
}

default:
{
if ( runningHelp() )
Expand Down Expand Up @@ -5544,6 +5574,17 @@ void Zypper::doCommand()
break;
}

case ZypperCommand::KEYS_e:
{
// load system data...
init_target( *this );
if ( exitCode() != ZYPPER_EXIT_OK )
return;

listTrustedKeys(*this);
break;
}

case ZypperCommand::SUBCOMMAND_e: // subcommands are not expected to be executed here!
default:
// if the program reaches this line, something went wrong
Expand Down
42 changes: 1 addition & 41 deletions src/callbacks/keyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "Zypper.h"
#include "Table.h"
#include "utils/misc.h"

///////////////////////////////////////////////////////////////////
namespace zypp
Expand Down Expand Up @@ -50,47 +51,6 @@ namespace zypp
{
Zypper::instance().out().warningPar( 4, str::Format(_("This file was modified after it has been signed. This may have been a malicious change, so it might not be trustworthy anymore! You should not continue unless you know it's safe.") ) );
}

std::ostream & dumpKeyInfo( std::ostream & str, const PublicKeyData & key, const KeyContext & context = KeyContext() )
{
Zypper & zypper = Zypper::instance();
if ( zypper.out().type() == Out::TYPE_XML )
{
{
xmlout::Node parent( str, "gpgkey-info", xmlout::Node::optionalContent );

if ( !context.empty() )
{
dumpAsXmlOn( *parent, context.repoInfo().asUserString(), "repository" );
}
dumpAsXmlOn( *parent, key.name(), "key-name" );
dumpAsXmlOn( *parent, key.fingerprint(), "key-fingerprint" );
dumpAsXmlOn( *parent, key.created(), "key-created" );
dumpAsXmlOn( *parent, key.expires(), "key-expires" );
dumpAsXmlOn( *parent, str::Format( "gpg-pubkey-%1%-%2%" ) % key.gpgPubkeyVersion() % key.gpgPubkeyRelease(), "rpm-name" );
}
return str;
}

Table t;
t.lineStyle( none );
if ( !context.empty() )
{
t << ( TableRow() << "" << _("Repository:") << context.repoInfo().asUserString() );
}
t << ( TableRow() << "" << _("Key Name:") << key.name() )
<< ( TableRow() << "" << _("Key Fingerprint:") << str::gapify( key.fingerprint(), 8 ) )
<< ( TableRow() << "" << _("Key Created:") << key.created() )
<< ( TableRow() << "" << _("Key Expires:") << key.expiresAsString() );
for ( const PublicSubkeyData & sub : key.subkeys() )
t << ( TableRow() << "" << _("Subkey:") << sub.asString() );
t << ( TableRow() << "" << _("Rpm Name:") << str::Format( "gpg-pubkey-%1%-%2%" ) % key.gpgPubkeyVersion() % key.gpgPubkeyRelease() );

return str << t;
}

inline std::ostream & dumpKeyInfo( std::ostream & str, const PublicKey & key, const KeyContext & context = KeyContext() )
{ return dumpKeyInfo( str, key.keyData(), context ); }
} // namespace
///////////////////////////////////////////////////////////////////

Expand Down
119 changes: 119 additions & 0 deletions src/keys.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
____ _ _ __ _ __ ___ _ _
|_ / || | '_ \ '_ \/ -_) '_|
/__|\_, | .__/ .__/\___|_|
|__/|_| |_|
\*---------------------------------------------------------------------------*/

#include "Zypper.h"
#include "Table.h"
#include "utils/misc.h"

#include <zypp/ZYpp.h>
#include <zypp/target/rpm/RpmDb.h>
#include <zypp/KeyManager.h>


extern ZYpp::Ptr God;

template <class T>
void dumpKeyList ( Zypper &zypp_r, const std::list<T> &keysFound_r, bool details )
{
if ( keysFound_r.empty() )
{
zypp_r.out().warning(_("No keys found.") );
}
else
{
zypp_r.out().gap();
if ( details || zypp_r.globalOpts().machine_readable )
{
for(const auto &key : keysFound_r)
{
dumpKeyInfo( std::cout , key );
zypp_r.out().gap();
}
} else {
Table t;
t << ( TableHeader()
/* translators: Table column header */ << _("ID")
/* translators: Table column header */ << _("Name")
/* translators: Table column header */ << _("Expires"));

for(const auto &key : keysFound_r)
{
t << ( TableRow()
<< key.id()
<< key.name()
<< key.expires().asString());
}
t.dumpTo( std::cout );
zypp_r.out().gap();
}
}
zypp_r.setExitCode( ZYPPER_EXIT_OK );
}

void listTrustedKeys ( Zypper &zypp_r )
{
if ( !God || !God->target() || !God->keyRing() )
return;

KeyRing_Ptr keyRing = God->keyRing();
std::list<PublicKeyData> trustedKeys = keyRing->trustedPublicKeyData();

if ( zypp_r.arguments().size() )
{
std::list<PublicKeyData> pubKeys;
for ( const std::string &arg : zypp_r.arguments() )
{
PublicKeyData foundKey = keyRing->trustedPublicKeyData(arg);
if ( foundKey ) {
//this is a key ID
pubKeys.push_back(foundKey);
} else {
// is the current arg a path or a ID
filesystem::PathInfo path (arg);
if (!path.isExist())
{
zypp_r.out().warning( str::Format(_("Argument '%1%' is not a trusted ID nor a existing file.")) % arg );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
return;
}

KeyManagerCtx::Ptr keyMgr = KeyManagerCtx::createForOpenPGP();
if (!keyMgr)
{
zypp_r.out().error( "Unable to initialize key manager backend" );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}
pubKeys.splice( pubKeys.end(), keyMgr->readKeyFromFile( arg ));
}
}
//print always in detail mode here, the user most likely wants to know more about the key
dumpKeyList( zypp_r, pubKeys, true );
}
else
{
const target::rpm::RpmDb &rpmdb = God->target()->rpmDb();
dumpKeyList( zypp_r, rpmdb.pubkeys(), zypp_r.cOpts().count("details") );
}
}

#if 0
void removeKey(Zypper &zypp_r )
{

}

void exportKey( Zypper &zypp_r )
{

}

void checkKey( Zypper &zypp_r )
{

}
#endif
23 changes: 23 additions & 0 deletions src/keys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------*\
____ _ _ __ _ __ ___ _ _
|_ / || | '_ \ '_ \/ -_) '_|
/__|\_, | .__/ .__/\___|_|
|__/|_| |_|
\*---------------------------------------------------------------------------*/
#ifndef ZYPPERKEYS_H_
#define ZYPPERKEYS_H_

#include <zypp/Pathname.h>

class Zypper;

void listTrustedKeys ( Zypper &zypp_r );

#if 0
void removeKey ( Zypper &zypp_r );
void exportKey ( Zypper &zypp_r );
void checkKey ( Zypper &zypp_r );
#endif


#endif
38 changes: 38 additions & 0 deletions src/utils/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -765,3 +765,41 @@ void packagekit_suggest_quit()
ExternalProgram pkcall( argv );
pkcall.close();
}

std::ostream &dumpKeyInfo(std::ostream &str, const PublicKeyData &key, const KeyContext &context)
{
Zypper & zypper = Zypper::instance();
if ( zypper.out().type() == Out::TYPE_XML )
{
{
xmlout::Node parent( str, "gpgkey-info", xmlout::Node::optionalContent );

if ( !context.empty() )
{
dumpAsXmlOn( *parent, context.repoInfo().asUserString(), "repository" );
}
dumpAsXmlOn( *parent, key.name(), "key-name" );
dumpAsXmlOn( *parent, key.fingerprint(), "key-fingerprint" );
dumpAsXmlOn( *parent, key.created(), "key-created" );
dumpAsXmlOn( *parent, key.expires(), "key-expires" );
dumpAsXmlOn( *parent, str::Format( "gpg-pubkey-%1%-%2%" ) % key.gpgPubkeyVersion() % key.gpgPubkeyRelease(), "rpm-name" );
}
return str;
}

Table t;
t.lineStyle( none );
if ( !context.empty() )
{
t << ( TableRow() << "" << _("Repository:") << context.repoInfo().asUserString() );
}
t << ( TableRow() << "" << _("Key Name:") << key.name() )
<< ( TableRow() << "" << _("Key Fingerprint:") << str::gapify( key.fingerprint(), 8 ) )
<< ( TableRow() << "" << _("Key Created:") << key.created() )
<< ( TableRow() << "" << _("Key Expires:") << key.expiresAsString() );
for ( const PublicSubkeyData & sub : key.subkeys() )
t << ( TableRow() << "" << _("Subkey:") << sub.asString() );
t << ( TableRow() << "" << _("Rpm Name:") << str::Format( "gpg-pubkey-%1%-%2%" ) % key.gpgPubkeyVersion() % key.gpgPubkeyRelease() );

return str << t;
}
Loading

0 comments on commit f9f6cda

Please sign in to comment.