monotone

monotone Mtn Source Tree

Root/key_store.cc

1#include <sstream>
2
3#include "key_store.hh"
4#include "file_io.hh"
5#include "packet.hh"
6#include "keys.hh"
7#include "globish.hh"
8
9struct keyreader : public packet_consumer
10{
11 key_store * ks;
12
13 keyreader(key_store * k): ks(k) {}
14 virtual void consume_file_data(file_id const & ident,
15 file_data const & dat)
16 {E(false, F("Extraneous data in key store."));}
17 virtual void consume_file_delta(file_id const & id_old,
18 file_id const & id_new,
19 file_delta const & del)
20 {E(false, F("Extraneous data in key store."));}
21 virtual void consume_file_reverse_delta(file_id const & id_new,
22 file_id const & id_old,
23 file_delta const & del)
24 {E(false, F("Extraneous data in key store."));}
25
26
27 virtual void consume_manifest_data(manifest_id const & ident,
28 manifest_data const & dat)
29 {E(false, F("Extraneous data in key store."));}
30 virtual void consume_manifest_delta(manifest_id const & id_old,
31 manifest_id const & id_new,
32 manifest_delta const & del)
33 {E(false, F("Extraneous data in key store."));}
34 virtual void consume_manifest_reverse_delta(manifest_id const & id_new,
35 manifest_id const & id_old,
36 manifest_delta const & del)
37 {E(false, F("Extraneous data in key store."));}
38
39
40 virtual void consume_revision_data(revision_id const & ident,
41 revision_data const & dat)
42 {E(false, F("Extraneous data in key store."));}
43 virtual void consume_revision_cert(revision<cert> const & t)
44 {E(false, F("Extraneous data in key store."));}
45
46
47 virtual void consume_public_key(rsa_keypair_id const & ident,
48 base64< rsa_pub_key > const & k)
49 {E(false, F("Extraneous data in key store."));}
50
51 virtual void consume_key_pair(rsa_keypair_id const & ident,
52 keypair const & kp)
53 {
54 E(!ks->key_pair_exists(ident),
55 F("Key store has multiple keys with id '%s'.") % ident);
56 ks->keys.insert(std::make_pair(ident, kp));
57 hexenc<id> hash;
58 key_hash_code(ident, kp.pub, hash);
59 ks->hashes.insert(std::make_pair(hash, ident));
60 L(F("Read key pair '%s' from key store.") % ident);
61 }
62};
63
64key_store::key_store(app_state * a): have_read(false), app(a)
65{
66}
67
68void
69key_store::set_key_dir(system_path const & kd)
70{
71 key_dir = kd;
72}
73
74system_path const &
75key_store::get_key_dir()
76{
77 return key_dir;
78}
79
80void
81key_store::read_key_dir()
82{
83 std::vector<utf8> key_files, dirs;
84 if (directory_exists(key_dir))
85 read_directory(key_dir, key_files, dirs);
86 keyreader kr(this);
87 for (std::vector<utf8>::const_iterator i = key_files.begin();
88 i != key_files.end(); ++i)
89 {
90 data dat;
91 read_data(key_dir / (*i)(), dat);
92 std::istringstream is(dat());
93 read_packets(is, kr, *app);
94 }
95}
96
97void
98key_store::maybe_read_key_dir()
99{
100 if (have_read)
101 return;
102 have_read = true;
103 read_key_dir();
104}
105
106void
107key_store::ensure_in_database(rsa_keypair_id const & ident)
108{
109 maybe_read_key_dir();
110 if (app->db.public_key_exists(ident))
111 return;
112 std::map<rsa_keypair_id, keypair>::iterator i = keys.find(ident);
113 I(i != keys.end());
114 app->db.put_key(ident, i->second.pub);
115}
116
117bool
118key_store::try_ensure_in_db(hexenc<id> const & hash)
119{
120 std::map<hexenc<id>, rsa_keypair_id>::const_iterator i = hashes.find(hash);
121 if (i == hashes.end())
122 return false;
123 ensure_in_database(i->second);
124 return true;
125}
126
127void
128key_store::get_key_ids(std::string const & pattern,
129 std::vector<rsa_keypair_id> & priv)
130{
131 maybe_read_key_dir();
132 priv.clear();
133 utf8 inc(pattern);
134 if (pattern.empty())
135 inc = utf8("*");
136 globish_matcher gm(inc, utf8(""));
137 for (std::map<rsa_keypair_id, keypair>::const_iterator
138 i = keys.begin(); i != keys.end(); ++i)
139 {
140 if (gm((i->first)()))
141 priv.push_back(i->first);
142 }
143}
144
145void
146key_store::get_keys(std::vector<rsa_keypair_id> & priv)
147{
148 maybe_read_key_dir();
149 priv.clear();
150 for (std::map<rsa_keypair_id, keypair>::const_iterator
151 i = keys.begin(); i != keys.end(); ++i)
152 {
153 priv.push_back(i->first);
154 }
155}
156
157bool
158key_store::key_pair_exists(rsa_keypair_id const & ident)
159{
160 maybe_read_key_dir();
161 return keys.find(ident) != keys.end();
162}
163
164void
165key_store::get_key_pair(rsa_keypair_id const & ident,
166 keypair & kp)
167{
168 maybe_read_key_dir();
169 std::map<rsa_keypair_id, keypair>::const_iterator i = keys.find(ident);
170 I(i != keys.end());
171 kp = i->second;
172}
173
174namespace
175{
176 // filename is the keypair id, except that some characters can't be put in
177 // filenames (especially on windows).
178 void
179 get_filename(rsa_keypair_id const & ident, std::string & filename)
180 {
181 filename = ident();
182 for (unsigned int i = 0; i < filename.size(); ++i)
183 if (std::string("+").find(filename[i]) != std::string::npos)
184 filename.at(i) = '_';
185 }
186}
187
188void
189key_store::get_key_file(rsa_keypair_id const & ident,
190 system_path & file)
191{
192 std::string leaf;
193 get_filename(ident, leaf);
194 file = key_dir / leaf;
195}
196
197void
198key_store::write_key(rsa_keypair_id const & ident)
199{
200 keypair kp;
201 get_key_pair(ident, kp);
202 std::ostringstream oss;
203 packet_writer pw(oss);
204 pw.consume_key_pair(ident, kp);
205 data dat(oss.str());
206 system_path file;
207 get_key_file(ident, file);
208 write_data(file, dat, key_dir);
209}
210
211void
212key_store::put_key_pair(rsa_keypair_id const & ident,
213 keypair const & kp)
214{
215 maybe_read_key_dir();
216 L(F("putting key pair '%s'") % ident);
217 std::pair<std::map<rsa_keypair_id, keypair>::iterator, bool> res;
218 res = keys.insert(std::make_pair(ident, kp));
219 if (res.second)
220 {
221 hexenc<id> hash;
222 key_hash_code(ident, kp.pub, hash);
223 I(hashes.insert(std::make_pair(hash, ident)).second);
224 write_key(ident);
225 }
226 else
227 {
228 E(/*keys_match(ident, res.first->second.priv, ident, kp.priv)
229 && */keys_match(ident, res.first->second.pub, ident, kp.pub),
230 F("Cannot store key '%s'; a different key by that name exists.")
231 % ident);
232 }
233}
234
235void
236key_store::delete_key(rsa_keypair_id const & ident)
237{
238 maybe_read_key_dir();
239 std::map<rsa_keypair_id, keypair>::iterator i = keys.find(ident);
240 if (i != keys.end())
241 {
242 hexenc<id> hash;
243 key_hash_code(ident, i->second.pub, hash);
244 std::map<hexenc<id>, rsa_keypair_id>::iterator j = hashes.find(hash);
245 I(j != hashes.end());
246 hashes.erase(j);
247 keys.erase(i);
248 }
249 system_path file;
250 get_key_file(ident, file);
251 delete_file(file);
252}

Archive Download this file

Branches

Tags

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