monotone

monotone Mtn Source Tree

Root/cmd_key_cert.cc

1// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#include <sstream>
11#include <iostream>
12
13#include "cert.hh"
14#include "charset.hh"
15#include "cmd.hh"
16#include "keys.hh"
17#include "packet.hh"
18#include "transforms.hh"
19
20using std::cout;
21using std::ostream_iterator;
22using std::ostringstream;
23using std::set;
24using std::string;
25
26CMD(genkey, N_("key and cert"), N_("KEYID"),
27 N_("generate an RSA key-pair"), OPT_NONE)
28{
29 if (args.size() != 1)
30 throw usage(name);
31
32 rsa_keypair_id ident;
33 internalize_rsa_keypair_id(idx(args, 0), ident);
34 bool exists = app.keys.key_pair_exists(ident);
35 if (app.db.database_specified())
36 {
37 transaction_guard guard(app.db);
38 exists = exists || app.db.public_key_exists(ident);
39 guard.commit();
40 }
41
42 N(!exists, F("key '%s' already exists") % ident);
43
44 keypair kp;
45 P(F("generating key-pair '%s'") % ident);
46 generate_key_pair(app.lua, ident, kp);
47 P(F("storing key-pair '%s' in %s/")
48 % ident % app.keys.get_key_dir());
49 app.keys.put_key_pair(ident, kp);
50}
51
52CMD(dropkey, N_("key and cert"), N_("KEYID"),
53 N_("drop a public and private key"), OPT_NONE)
54{
55 bool key_deleted = false;
56
57 if (args.size() != 1)
58 throw usage(name);
59
60 rsa_keypair_id ident(idx(args, 0)());
61 bool checked_db = false;
62 if (app.db.database_specified())
63 {
64 transaction_guard guard(app.db);
65 if (app.db.public_key_exists(ident))
66 {
67 P(F("dropping public key '%s' from database") % ident);
68 app.db.delete_public_key(ident);
69 key_deleted = true;
70 }
71 guard.commit();
72 checked_db = true;
73 }
74
75 if (app.keys.key_pair_exists(ident))
76 {
77 P(F("dropping key pair '%s' from keystore") % ident);
78 app.keys.delete_key(ident);
79 key_deleted = true;
80 }
81
82 i18n_format fmt;
83 if (checked_db)
84 fmt = F("public or private key '%s' does not exist "
85 "in keystore or database");
86 else
87 fmt = F("public or private key '%s' does not exist "
88 "in keystore, and no database was specified");
89 N(key_deleted, fmt % idx(args, 0)());
90}
91
92CMD(chkeypass, N_("key and cert"), N_("KEYID"),
93 N_("change passphrase of a private RSA key"),
94 OPT_NONE)
95{
96 if (args.size() != 1)
97 throw usage(name);
98
99 rsa_keypair_id ident;
100 internalize_rsa_keypair_id(idx(args, 0), ident);
101
102 N(app.keys.key_pair_exists(ident),
103 F("key '%s' does not exist in the keystore") % ident);
104
105 keypair key;
106 app.keys.get_key_pair(ident, key);
107 change_key_passphrase(app.lua, ident, key.priv);
108 app.keys.delete_key(ident);
109 app.keys.put_key_pair(ident, key);
110 P(F("passphrase changed"));
111}
112
113CMD(cert, N_("key and cert"), N_("REVISION CERTNAME [CERTVAL]"),
114 N_("create a cert for a revision"), OPT_NONE)
115{
116 if ((args.size() != 3) && (args.size() != 2))
117 throw usage(name);
118
119 transaction_guard guard(app.db);
120
121 hexenc<id> ident;
122 revision_id rid;
123 complete(app, idx(args, 0)(), rid);
124 ident = rid.inner();
125
126 cert_name name;
127 internalize_cert_name(idx(args, 1), name);
128
129 rsa_keypair_id key;
130 get_user_key(key, app);
131
132 cert_value val;
133 if (args.size() == 3)
134 val = cert_value(idx(args, 2)());
135 else
136 val = cert_value(get_stdin());
137
138 base64<cert_value> val_encoded;
139 encode_base64(val, val_encoded);
140
141 cert t(ident, name, val_encoded, key);
142
143 packet_db_writer dbw(app);
144 calculate_cert(app, t);
145 dbw.consume_revision_cert(revision<cert>(t));
146 guard.commit();
147}
148
149CMD(trusted, N_("key and cert"),
150 N_("REVISION NAME VALUE SIGNER1 [SIGNER2 [...]]"),
151 N_("test whether a hypothetical cert would be trusted\n"
152 "by current settings"),
153 OPT_NONE)
154{
155 if (args.size() < 4)
156 throw usage(name);
157
158 revision_id rid;
159 complete(app, idx(args, 0)(), rid, false);
160 hexenc<id> ident(rid.inner());
161
162 cert_name name;
163 internalize_cert_name(idx(args, 1), name);
164
165 cert_value value(idx(args, 2)());
166
167 set<rsa_keypair_id> signers;
168 for (unsigned int i = 3; i != args.size(); ++i)
169 {
170 rsa_keypair_id keyid;
171 internalize_rsa_keypair_id(idx(args, i), keyid);
172 signers.insert(keyid);
173 }
174
175
176 bool trusted = app.lua.hook_get_revision_cert_trust(signers, ident,
177 name, value);
178
179
180 ostringstream all_signers;
181 copy(signers.begin(), signers.end(),
182 ostream_iterator<rsa_keypair_id>(all_signers, " "));
183
184 cout << F("if a cert on: %s\n"
185 "with key: %s\n"
186 "and value: %s\n"
187 "was signed by: %s\n"
188 "it would be: %s\n")
189 % ident
190 % name
191 % value
192 % all_signers.str()
193 % (trusted ? _("trusted") : _("UNtrusted"));
194}
195
196CMD(tag, N_("review"), N_("REVISION TAGNAME"),
197 N_("put a symbolic tag cert on a revision"), OPT_NONE)
198{
199 if (args.size() != 2)
200 throw usage(name);
201
202 revision_id r;
203 complete(app, idx(args, 0)(), r);
204 packet_db_writer dbw(app);
205 cert_revision_tag(r, idx(args, 1)(), app, dbw);
206}
207
208
209CMD(testresult, N_("review"), N_("ID (pass|fail|true|false|yes|no|1|0)"),
210 N_("note the results of running a test on a revision"), OPT_NONE)
211{
212 if (args.size() != 2)
213 throw usage(name);
214
215 revision_id r;
216 complete(app, idx(args, 0)(), r);
217 packet_db_writer dbw(app);
218 cert_revision_testresult(r, idx(args, 1)(), app, dbw);
219}
220
221
222CMD(approve, N_("review"), N_("REVISION"),
223 N_("approve of a particular revision"),
224 OPT_BRANCH_NAME)
225{
226 if (args.size() != 1)
227 throw usage(name);
228
229 revision_id r;
230 complete(app, idx(args, 0)(), r);
231 packet_db_writer dbw(app);
232 cert_value branchname;
233 guess_branch(r, app, branchname);
234 N(app.branch_name() != "", F("need --branch argument for approval"));
235 cert_revision_in_branch(r, app.branch_name(), app, dbw);
236}
237
238CMD(comment, N_("review"), N_("REVISION [COMMENT]"),
239 N_("comment on a particular revision"), OPT_NONE)
240{
241 if (args.size() != 1 && args.size() != 2)
242 throw usage(name);
243
244 string comment;
245 if (args.size() == 2)
246 comment = idx(args, 1)();
247 else
248 N(app.lua.hook_edit_comment("", "", comment),
249 F("edit comment failed"));
250
251 N(comment.find_first_not_of("\n\r\t ") != string::npos,
252 F("empty comment"));
253
254 revision_id r;
255 complete(app, idx(args, 0)(), r);
256 packet_db_writer dbw(app);
257 cert_revision_comment(r, comment, app, dbw);
258}
259
260// Local Variables:
261// mode: C++
262// fill-column: 76
263// c-file-style: "gnu"
264// indent-tabs-mode: nil
265// End:
266// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status