Skip to content

Commit

Permalink
Introduce keyadd and keyremove commands
Browse files Browse the repository at this point in the history
  • Loading branch information
bzeller committed Mar 21, 2018
1 parent c394f88 commit 3d97661
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 19 deletions.
9 changes: 8 additions & 1 deletion doc/zypper.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1423,7 +1423,7 @@ Package locks serve the purpose of preventing changes to the set of installed pa

Key Management
~~~~~~~~~~~~~~
The *keys* command lists keys from the internal trust database.
The *keys*, *addkey*, and *removekey* commands serve for manipulating the trusted key database. A key is specified by its ID, which is the last 16 characters of its fingerprint.

*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.
Expand All @@ -1433,6 +1433,13 @@ The *keys* command lists keys from the internal trust database.
Shows the keys in a more detailed multiline output, also shows subkey information
--

*addkey* (*ak*) ['options'] 'url'...::
Imports a new key into the trusted database, the file can be specified as a URL.

*removekey* (*rk*) ['options'] 'key-id' ::
Remove specified key from the trusted database.


Other Commands
~~~~~~~~~~~~~~
*versioncmp* (*vcmp*) 'version1' 'version2'::
Expand Down
4 changes: 3 additions & 1 deletion src/Command.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ namespace
_t( RUG_PATCH_SEARCH_e ) | "patch-search" | "pse";
_t( RUG_PING_e ) | "ping";

_t( KEYS_e ) | "keys" | "lk";
_t( KEYS_e ) | "keys" | "lk";
_t( ADDKEY_e ) | "addkey" | "ak";
_t( REMOVEKEY_e ) | "removekey" | "rk";
#undef _t
}
return _table;
Expand Down
2 changes: 2 additions & 0 deletions src/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ struct ZypperCommand
RUG_PING_e,

KEYS_e,
ADDKEY_e,
REMOVEKEY_e
};

ZypperCommand( Command command ) : _command(command) {}
Expand Down
63 changes: 61 additions & 2 deletions src/Zypper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,8 @@ void print_main_help( Zypper & zypper )

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"
"\taddkey, as\t\tAdd a new key to trust.\n"
"\tremovekey, rs\tRemove a key from trust.\n"
);

zypper.out().info( help_usage, Out::QUIET );
Expand Down Expand Up @@ -3500,6 +3500,43 @@ void Zypper::processCommandOptions()
break;
}

case ZypperCommand::ADDKEY_e:
{
static struct option options[] = {
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
specific_options = options;

_command_help = CommandHelpFormater()
.synopsis( // translators: command synopsis; do not translate lowercase words
_("addkey <url>")
)
.description(// translators: command description
_("Import all keys from a keyfile specified by url.")
)
;
break;
}

case ZypperCommand::REMOVEKEY_e:
{
static struct option options[] = {
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
specific_options = options;

_command_help = CommandHelpFormater()
.synopsis( // translators: command synopsis; do not translate lowercase words
_("removekey <ID>")
)
.description(// translators: command description
_("Remove key specified by ID from trust.")
);
break;
}

default:
{
if ( runningHelp() )
Expand Down Expand Up @@ -5591,6 +5628,28 @@ void Zypper::doCommand()
break;
}

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

importKey( *this, arguments().front() );
break;
}

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

removeKey( *this, arguments().front() );
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
120 changes: 112 additions & 8 deletions src/keys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
\*---------------------------------------------------------------------------*/

#include "Zypper.h"
#include "Table.h"
#include "utils/prompt.h"
#include "utils/misc.h"
#include "utils/text.h"
#include "utils/console.h"

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

#include <sstream>

extern ZYpp::Ptr God;

Expand Down Expand Up @@ -174,19 +176,121 @@ void listTrustedKeys ( Zypper &zypp_r )
}
}

#if 0
void removeKey(Zypper &zypp_r )
void removeKey ( Zypper &zypp_r, const std::string &id )
{
if ( !God || !God->keyRing() )
return;

}
KeyRing_Ptr keyRing = God->keyRing();

void exportKey( Zypper &zypp_r )
{
bool found = false;
for ( const PublicKeyData &key : keyRing->trustedPublicKeyData() )
{
if ( key.providesKey(id) )
{
found = true;

std::stringstream keyInfo;
dumpKeyInfo ( keyInfo, key );
std::string question = str::Format(
"About to delete key: \n"
"%1%\n"
"Do you want to continue?\n"
) % keyInfo.str();

if ( read_bool_answer(PROMPT_YN_GPG_UNKNOWN_KEY_ACCEPT, question, false) )
{
try
{
keyRing->deleteKey( key.id(), true );
} catch ( const Exception & e ) {
ZYPP_CAUGHT( e );
zypp_r.out().error( e, str::Format(_("Failed to delete key: %1%")) % id );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}
}
break;
}
}

if ( !found )
{
zypp_r.out().warning( str::Format(_("Key %1% is not known")) % id );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
return;
}
}

void checkKey( Zypper &zypp_r )
void importKey ( Zypper &zypp_r, const std::string &url_r )
{
if ( !God || !God->keyRing() )
return;

Url url = make_url( url_r );
if ( !url.isValid() )
{
zypp_r.setExitCode( ZYPPER_EXIT_ERR_INVALID_ARGS );
return;
}

//try to get a file from the URL
Pathname local;
try
{ local = MediaSetAccess::provideFileFromUrl(url); }
catch ( const media::MediaException & e )
{
ZYPP_CAUGHT( e );
zypp_r.out().error( e, str::Format(_("Problem accessing the file at the specified URI: %1%")) % url,
_("Please check if the URI is valid and accessible.") );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}
catch ( const Exception & e )
{
ZYPP_CAUGHT( e );
zypp_r.out().error( e, str::Format(_("Problem encountered while trying to read the file at the specified URI %1%")) % url );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}

PublicKey pKey;
try
{
pKey = PublicKey(local);
} catch ( const Exception & e ) {
ZYPP_CAUGHT( e );
zypp_r.out().error( e, str::Format(_("Problem encountered while parsing the file at the specified URI %1%")) % url );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}

//first import all the keys in keyfile into the general keyring, we do not trust yet
KeyRing_Ptr keyRing = God->keyRing();
keyRing->importKey( pKey, false);

//now lets go over all imported keys and ask explicitely if the user wants to trust them
for ( const PublicKey &key : keyRing->publicKeys() )
{
std::stringstream keyInfo;
dumpKeyInfo ( keyInfo, key );
std::string question = str::Format(
"About to import key: \n"
"%1%\n"
"Do you want to continue?\n"
) % keyInfo.str();

if ( read_bool_answer(PROMPT_YN_GPG_UNKNOWN_KEY_ACCEPT, question, false) )
{
try
{
keyRing->importKey( keyRing->exportPublicKey(key.keyData()), true );
} catch ( const Exception & e ) {
ZYPP_CAUGHT( e );
zypp_r.out().error( e, str::Format(_("Failed to import key from URL: %1%")) % url );
zypp_r.setExitCode( ZYPPER_EXIT_ERR_ZYPP );
return;
}
}
}
}
#endif
8 changes: 2 additions & 6 deletions src/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ 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

void importKey ( Zypper &zypp_r, const std::string &url);
void removeKey ( Zypper &zypp_r, const std::string &id );

#endif
4 changes: 3 additions & 1 deletion src/utils/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ std::ostream &dumpKeyInfo(std::ostream &str, const PublicKeyData &key, const Key
{
dumpAsXmlOn( *parent, context.repoInfo().asUserString(), "repository" );
}
dumpAsXmlOn( *parent, key.id(), "key-id" );
dumpAsXmlOn( *parent, key.name(), "key-name" );
dumpAsXmlOn( *parent, key.fingerprint(), "key-fingerprint" );
dumpAsXmlOn( *parent, key.created(), "key-created" );
Expand All @@ -793,7 +794,8 @@ std::ostream &dumpKeyInfo(std::ostream &str, const PublicKeyData &key, const Key
{
t << ( TableRow() << "" << _("Repository:") << context.repoInfo().asUserString() );
}
t << ( TableRow() << "" << _("Key Name:") << key.name() )
t << ( TableRow() << "" << _("Key ID:") << key.id() )
<< ( TableRow() << "" << _("Key Name:") << key.name() )
<< ( TableRow() << "" << _("Key Fingerprint:") << str::gapify( key.fingerprint(), 8 ) )
<< ( TableRow() << "" << _("Key Created:") << key.created() )
<< ( TableRow() << "" << _("Key Expires:") << key.expiresAsString() );
Expand Down

0 comments on commit 3d97661

Please sign in to comment.