Skip to content

Commit

Permalink
Add --trusted option to gpg-add-user
Browse files Browse the repository at this point in the history
If this option is specified, then the GPG users are added even
if their keys are not trusted by GPG.

In addition, if a full fingerprint, prefixed by 0x, is specified,
it is assumed to be trusted, regardless of its trust level in the
GPG trustdb.
  • Loading branch information
AGWA committed Apr 1, 2015
1 parent ad71c7f commit 3104508
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
25 changes: 16 additions & 9 deletions commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ static bool decrypt_repo_keys (std::vector<Key_file>& key_files, uint32_t key_ve
return successful;
}

static void encrypt_repo_key (const char* key_name, const Key_file::Entry& key, const std::vector<std::string>& collab_keys, const std::string& keys_path, std::vector<std::string>* new_files)
static void encrypt_repo_key (const char* key_name, const Key_file::Entry& key, const std::vector<std::pair<std::string, bool> >& collab_keys, const std::string& keys_path, std::vector<std::string>* new_files)
{
std::string key_file_data;
{
Expand All @@ -505,17 +505,19 @@ static void encrypt_repo_key (const char* key_name, const Key_file::Entry& key,
key_file_data = this_version_key_file.store_to_string();
}

for (std::vector<std::string>::const_iterator collab(collab_keys.begin()); collab != collab_keys.end(); ++collab) {
for (std::vector<std::pair<std::string, bool> >::const_iterator collab(collab_keys.begin()); collab != collab_keys.end(); ++collab) {
const std::string& fingerprint(collab->first);
const bool key_is_trusted(collab->second);
std::ostringstream path_builder;
path_builder << keys_path << '/' << (key_name ? key_name : "default") << '/' << key.version << '/' << *collab << ".gpg";
path_builder << keys_path << '/' << (key_name ? key_name : "default") << '/' << key.version << '/' << fingerprint << ".gpg";
std::string path(path_builder.str());

if (access(path.c_str(), F_OK) == 0) {
continue;
}

mkdir_parent(path);
gpg_encrypt_to_file(path, *collab, key_file_data.data(), key_file_data.size());
gpg_encrypt_to_file(path, fingerprint, key_is_trusted, key_file_data.data(), key_file_data.size());
new_files->push_back(path);
}
}
Expand Down Expand Up @@ -1025,17 +1027,20 @@ void help_add_gpg_user (std::ostream& out)
out << std::endl;
out << " -k, --key-name KEYNAME Add GPG user to given key, instead of default" << std::endl;
out << " -n, --no-commit Don't automatically commit" << std::endl;
out << " --trusted Assume the GPG user IDs are trusted" << std::endl;
out << std::endl;
}
int add_gpg_user (int argc, const char** argv)
{
const char* key_name = 0;
bool no_commit = false;
bool trusted = false;
Options_list options;
options.push_back(Option_def("-k", &key_name));
options.push_back(Option_def("--key-name", &key_name));
options.push_back(Option_def("-n", &no_commit));
options.push_back(Option_def("--no-commit", &no_commit));
options.push_back(Option_def("--trusted", &trusted));

int argi = parse_options(options, argc, argv);
if (argc - argi == 0) {
Expand All @@ -1044,8 +1049,8 @@ int add_gpg_user (int argc, const char** argv)
return 2;
}

// build a list of key fingerprints for every collaborator specified on the command line
std::vector<std::string> collab_keys;
// build a list of key fingerprints, and whether the key is trusted, for every collaborator specified on the command line
std::vector<std::pair<std::string, bool> > collab_keys;

for (int i = argi; i < argc; ++i) {
std::vector<std::string> keys(gpg_lookup_key(argv[i]));
Expand All @@ -1057,7 +1062,9 @@ int add_gpg_user (int argc, const char** argv)
std::clog << "Error: more than one public key matches '" << argv[i] << "' - please be more specific" << std::endl;
return 1;
}
collab_keys.push_back(keys[0]);

const bool is_full_fingerprint(std::strncmp(argv[i], "0x", 2) == 0 && std::strlen(argv[i]) == 42);
collab_keys.push_back(std::make_pair(keys[0], trusted || is_full_fingerprint));
}

// TODO: have a retroactive option to grant access to all key versions, not just the most recent
Expand Down Expand Up @@ -1108,8 +1115,8 @@ int add_gpg_user (int argc, const char** argv)
// TODO: include key_name in commit message
std::ostringstream commit_message_builder;
commit_message_builder << "Add " << collab_keys.size() << " git-crypt collaborator" << (collab_keys.size() != 1 ? "s" : "") << "\n\nNew collaborators:\n\n";
for (std::vector<std::string>::const_iterator collab(collab_keys.begin()); collab != collab_keys.end(); ++collab) {
commit_message_builder << '\t' << gpg_shorten_fingerprint(*collab) << ' ' << gpg_get_uid(*collab) << '\n';
for (std::vector<std::pair<std::string, bool> >::const_iterator collab(collab_keys.begin()); collab != collab_keys.end(); ++collab) {
commit_message_builder << '\t' << gpg_shorten_fingerprint(collab->first) << ' ' << gpg_get_uid(collab->first) << '\n';
}

// git commit -m MESSAGE NEW_FILE ...
Expand Down
6 changes: 5 additions & 1 deletion gpg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,16 @@ std::vector<std::string> gpg_list_secret_keys ()
return secret_keys;
}

void gpg_encrypt_to_file (const std::string& filename, const std::string& recipient_fingerprint, const char* p, size_t len)
void gpg_encrypt_to_file (const std::string& filename, const std::string& recipient_fingerprint, bool key_is_trusted, const char* p, size_t len)
{
// gpg --batch -o FILENAME -r RECIPIENT -e
std::vector<std::string> command;
command.push_back("gpg");
command.push_back("--batch");
if (key_is_trusted) {
command.push_back("--trust-model");
command.push_back("always");
}
command.push_back("-o");
command.push_back(filename);
command.push_back("-r");
Expand Down
2 changes: 1 addition & 1 deletion gpg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ std::string gpg_shorten_fingerprint (const std::string& fingerprint);
std::string gpg_get_uid (const std::string& fingerprint);
std::vector<std::string> gpg_lookup_key (const std::string& query);
std::vector<std::string> gpg_list_secret_keys ();
void gpg_encrypt_to_file (const std::string& filename, const std::string& recipient_fingerprint, const char* p, size_t len);
void gpg_encrypt_to_file (const std::string& filename, const std::string& recipient_fingerprint, bool key_is_trusted, const char* p, size_t len);
void gpg_decrypt_from_file (const std::string& filename, std::ostream&);

#endif

0 comments on commit 3104508

Please sign in to comment.