monotone

monotone Mtn Source Tree

Root/cmd_packet.cc

1// Copyright (C) 2010 Stephen Leake <stephen_leake@stephe-leake.org>
2// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
3//
4// This program is made available under the GNU GPL version 2.0 or
5// greater. See the accompanying file COPYING for details.
6//
7// This program is distributed WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9// PURPOSE.
10
11#include "base.hh"
12#include <iostream>
13#include <sstream>
14
15#include "cmd.hh"
16#include "app_state.hh"
17#include "database.hh"
18#include "key_store.hh"
19#include "key_packet.hh"
20#include "packet.hh"
21#include "project.hh"
22#include "vocab_cast.hh"
23
24using std::cin;
25using std::cout;
26using std::istringstream;
27using std::vector;
28
29namespace
30{
31 // this writer injects key packets it receives to the database and/or
32 // keystore.
33
34 struct key_packet_db_writer : public key_packet_consumer
35 {
36 database & db;
37 key_store & keys;
38
39 public:
40 key_packet_db_writer(database & db, key_store & keys)
41 : db(db), keys(keys)
42 {}
43 virtual ~key_packet_db_writer() {}
44 virtual void consume_public_key(key_name const & ident,
45 rsa_pub_key const & k)
46 {
47 transaction_guard guard(db);
48 db.put_key(ident, k);
49 guard.commit();
50 }
51
52 virtual void consume_key_pair(key_name const & ident,
53 keypair const & kp)
54 {
55 keys.put_key_pair(ident, kp);
56 }
57
58 virtual void consume_old_private_key(key_name const & ident,
59 old_arc4_rsa_priv_key const & k)
60 {
61 rsa_pub_key dummy;
62 keys.migrate_old_key_pair(ident, k, dummy);
63 }
64 };
65}
66
67CMD_AUTOMATE(put_public_key, N_("KEY-PACKET-DATA"),
68 N_("Store the public key in the database"),
69 "",
70 options::opts::none)
71{
72 E(args.size() == 1, origin::user,
73 F("wrong argument count"));
74
75 database db(app);
76 key_store keys(app);
77 key_packet_db_writer dbw(db, keys);
78
79 istringstream ss(idx(args,0)());
80 read_key_packets(ss, dbw);
81}
82
83static void
84pubkey_common(app_state & app,
85 args_vector args,
86 std::ostream & output)
87{
88 database db(app);
89 key_store keys(app);
90 project_t project(db);
91
92 key_identity_info identity;
93 project.get_key_identity(keys, app.lua,
94 typecast_vocab<external_key_name>(idx(args, 0)),
95 identity);
96 bool exists(false);
97 rsa_pub_key key;
98 if (db.database_specified() && db.public_key_exists(identity.id))
99 {
100 db.get_key(identity.id, key);
101 exists = true;
102 }
103 if (keys.key_pair_exists(identity.id))
104 {
105 keypair kp;
106 keys.get_key_pair(identity.id, kp);
107 key = kp.pub;
108 exists = true;
109 }
110 E(exists, origin::user,
111 F("public key '%s' does not exist") % idx(args, 0)());
112
113 packet_writer pw(output);
114 pw.consume_public_key(identity.given_name, key);
115}
116
117CMD(pubkey, "pubkey", "", CMD_REF(packet_io), N_("KEY_NAME_OR_HASH"),
118 N_("Prints a public key packet"),
119 "",
120 options::opts::none)
121{
122 if (args.size() != 1)
123 throw usage(execid);
124
125 pubkey_common(app, args, cout);
126}
127
128CMD_AUTOMATE(get_public_key, N_("KEY_NAME_OR_HASH"),
129 N_("Prints a public key packet"),
130 "",
131 options::opts::none)
132{
133 E(args.size() == 1, origin::user,
134 F("wrong argument count"));
135
136 pubkey_common(app, args, output);
137}
138
139CMD(privkey, "privkey", "", CMD_REF(packet_io), N_("ID"),
140 N_("Prints a private key packet"),
141 "",
142 options::opts::none)
143{
144 database db(app);
145 key_store keys(app);
146 project_t project(db);
147
148 if (args.size() != 1)
149 throw usage(execid);
150
151 key_name name = typecast_vocab<key_name>(idx(args, 0));
152 key_identity_info identity;
153 project.get_key_identity(app.lua,
154 typecast_vocab<external_key_name>(idx(args, 0)),
155 identity);
156 E(keys.key_pair_exists(identity.id), origin::user,
157 F("public and private key '%s' do not exist in keystore")
158 % idx(args, 0)());
159
160 packet_writer pw(cout);
161 keypair kp;
162 key_name given_name;
163 keys.get_key_pair(identity.id, given_name, kp);
164 pw.consume_key_pair(given_name, kp);
165}
166
167namespace
168{
169 // this writer injects packets it receives to the database
170 // and/or keystore.
171
172 struct packet_db_writer : public packet_consumer
173 {
174 database & db;
175 key_store & keys;
176
177 public:
178 packet_db_writer(database & db, key_store & keys)
179 : db(db), keys(keys)
180 {}
181 virtual ~packet_db_writer() {}
182 virtual void consume_file_data(file_id const & ident,
183 file_data const & dat)
184 {
185 transaction_guard guard(db);
186 db.put_file(ident, dat);
187 guard.commit();
188 }
189
190 virtual void consume_file_delta(file_id const & old_id,
191 file_id const & new_id,
192 file_delta const & del)
193 {
194 transaction_guard guard(db);
195 db.put_file_version(old_id, new_id, del);
196 guard.commit();
197 }
198
199 virtual void consume_revision_data(revision_id const & ident,
200 revision_data const & dat)
201 {
202 transaction_guard guard(db);
203 db.put_revision(ident, dat);
204 guard.commit();
205 }
206
207 virtual void consume_revision_cert(cert const & t)
208 {
209 transaction_guard guard(db);
210 db.put_revision_cert(t);
211 guard.commit();
212 }
213
214 virtual void consume_public_key(key_name const & ident,
215 rsa_pub_key const & k)
216 {
217 transaction_guard guard(db);
218 db.put_key(ident, k);
219 guard.commit();
220 }
221
222 virtual void consume_key_pair(key_name const & ident,
223 keypair const & kp)
224 {
225 keys.put_key_pair(ident, kp);
226 }
227
228 virtual void consume_old_private_key(key_name const & ident,
229 old_arc4_rsa_priv_key const & k)
230 {
231 rsa_pub_key dummy;
232 keys.migrate_old_key_pair(ident, k, dummy);
233 }
234 };
235}
236
237// Name : read_packets
238// Arguments:
239// packet-data
240// Added in: 9.0
241// Purpose:
242// Store public keys (and incidentally anything else that can be
243// represented as a packet) into the database.
244// Input format:
245// The format of the packet-data argument is identical to the output
246// of "mtn pubkey <keyname>" (or other packet output commands).
247// Output format:
248// No output.
249// Error conditions:
250// Invalid input formatting.
251CMD_AUTOMATE(read_packets, N_("PACKET-DATA"),
252 N_("Load the given packets into the database"),
253 "",
254 options::opts::none)
255{
256 E(args.size() == 1, origin::user,
257 F("wrong argument count"));
258
259 database db(app);
260 key_store keys(app);
261 packet_db_writer dbw(db, keys);
262
263 istringstream ss(idx(args,0)());
264 read_packets(ss, dbw);
265}
266
267CMD(read, "read", "", CMD_REF(packet_io), "[FILE1 [FILE2 [...]]]",
268 N_("Reads packets from files"),
269 N_("If no files are provided, the standard input is used."),
270 options::opts::none)
271{
272 database db(app);
273 key_store keys(app);
274 packet_db_writer dbw(db, keys);
275 size_t count = 0;
276 if (args.empty())
277 {
278 count += read_packets(cin, dbw);
279 E(count != 0, origin::user, F("no packets found on stdin"));
280 }
281 else
282 {
283 for (args_vector::const_iterator i = args.begin();
284 i != args.end(); ++i)
285 {
286 data dat;
287 read_data(system_path(*i), dat);
288 istringstream ss(dat());
289 count += read_packets(ss, dbw);
290 }
291 E(count != 0, origin::user,
292 FP("no packets found in given file",
293 "no packets found in given files",
294 args.size()));
295 }
296 P(FP("read %d packet", "read %d packets", count) % count);
297}
298
299
300// Local Variables:
301// mode: C++
302// fill-column: 76
303// c-file-style: "gnu"
304// indent-tabs-mode: nil
305// End:
306// 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