| 1211 | out << std::endl; |
| 1212 | } |
| 1213 | int add_gpg_user (int argc, const char** argv) |
| 1214 | { |
| 1215 | const char* key_name = 0; |
| 1216 | bool no_commit = false; |
| 1217 | bool trusted = false; |
| 1218 | Options_list options; |
| 1219 | options.push_back(Option_def("-k", &key_name)); |
| 1220 | options.push_back(Option_def("--key-name", &key_name)); |
| 1221 | options.push_back(Option_def("-n", &no_commit)); |
| 1222 | options.push_back(Option_def("--no-commit", &no_commit)); |
| 1223 | options.push_back(Option_def("--trusted", &trusted)); |
| 1224 | |
| 1225 | int argi = parse_options(options, argc, argv); |
| 1226 | if (argc - argi == 0) { |
| 1227 | std::clog << "Error: no GPG user ID specified" << std::endl; |
| 1228 | help_add_gpg_user(std::clog); |
| 1229 | return 2; |
| 1230 | } |
| 1231 | |
| 1232 | // build a list of key fingerprints, and whether the key is trusted, for every collaborator specified on the command line |
| 1233 | std::vector<std::pair<std::string, bool> > collab_keys; |
| 1234 | |
| 1235 | for (int i = argi; i < argc; ++i) { |
| 1236 | std::vector<std::string> keys(gpg_lookup_key(argv[i])); |
| 1237 | if (keys.empty()) { |
| 1238 | std::clog << "Error: public key for '" << argv[i] << "' not found in your GPG keyring" << std::endl; |
| 1239 | return 1; |
| 1240 | } |
| 1241 | if (keys.size() > 1) { |
| 1242 | std::clog << "Error: more than one public key matches '" << argv[i] << "' - please be more specific" << std::endl; |
| 1243 | return 1; |
| 1244 | } |
| 1245 | |
| 1246 | const bool is_full_fingerprint(std::strncmp(argv[i], "0x", 2) == 0 && std::strlen(argv[i]) == 42); |
| 1247 | collab_keys.push_back(std::make_pair(keys[0], trusted || is_full_fingerprint)); |
| 1248 | } |
| 1249 | |
| 1250 | // TODO: have a retroactive option to grant access to all key versions, not just the most recent |
| 1251 | Key_file key_file; |
| 1252 | load_key(key_file, key_name); |
| 1253 | const Key_file::Entry* key = key_file.get_latest(); |
| 1254 | if (!key) { |
| 1255 | std::clog << "Error: key file is empty" << std::endl; |
| 1256 | return 1; |
| 1257 | } |
| 1258 | |
| 1259 | const std::string state_path(get_repo_state_path()); |
| 1260 | std::vector<std::string> new_files; |
| 1261 | |
| 1262 | encrypt_repo_key(key_name, *key, collab_keys, get_repo_keys_path(state_path), &new_files); |
| 1263 | |
| 1264 | // Add a .gitatributes file to the repo state directory to prevent files in it from being encrypted. |
| 1265 | const std::string state_gitattributes_path(state_path + "/.gitattributes"); |
| 1266 | if (access(state_gitattributes_path.c_str(), F_OK) != 0) { |
| 1267 | std::ofstream state_gitattributes_file(state_gitattributes_path.c_str()); |
| 1268 | // |--------------------------------------------------------------------------------| 80 chars |
| 1269 | state_gitattributes_file << "# Do not edit this file. To specify the files to encrypt, create your own\n"; |
| 1270 | state_gitattributes_file << "# .gitattributes file in the directory where your files are.\n"; |
no test coverage detected