]>
git.proxmox.com Git - ceph.git/blob - ceph/src/auth/KeyRing.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
20 #include "auth/KeyRing.h"
21 #include "common/config.h"
22 #include "common/debug.h"
23 #include "common/errno.h"
24 #include "common/Formatter.h"
26 #define dout_subsys ceph_subsys_auth
29 #define dout_prefix *_dout << "auth: "
33 int KeyRing::from_ceph_context(CephContext
*cct
)
35 const md_config_t
*conf
= cct
->_conf
;
38 int ret
= ceph_resolve_file_search(conf
->keyring
, filename
);
40 ret
= load(cct
, filename
);
42 lderr(cct
) << "failed to load " << filename
43 << ": " << cpp_strerror(ret
) << dendl
;
45 lderr(cct
) << "unable to find a keyring on " << conf
->keyring
46 << ": " << cpp_strerror(ret
) << dendl
;
49 if (!conf
->key
.empty()) {
52 ea
.key
.decode_base64(conf
->key
);
56 catch (buffer::error
& e
) {
57 lderr(cct
) << "failed to decode key '" << conf
->key
<< "'" << dendl
;
62 if (!conf
->keyfile
.empty()) {
65 int r
= bl
.read_file(conf
->keyfile
.c_str(), &err
);
67 lderr(cct
) << err
<< dendl
;
70 string
k(bl
.c_str(), bl
.length());
73 ea
.key
.decode_base64(k
);
76 catch (buffer::error
& e
) {
77 lderr(cct
) << "failed to decode key '" << k
<< "'" << dendl
;
86 KeyRing
*KeyRing::create_empty()
91 int KeyRing::set_modifier(const char *type
, const char *val
, EntityName
& name
, map
<string
, bufferlist
>& caps
)
96 if (strcmp(type
, "key") == 0) {
100 key
.decode_base64(l
);
101 } catch (const buffer::error
& err
) {
105 } else if (strncmp(type
, "caps ", 5) == 0) {
106 const char *caps_entity
= type
+ 5;
112 caps
[caps_entity
] = bl
;
113 set_caps(name
, caps
);
114 } else if (strcmp(type
, "auid") == 0) {
115 uint64_t auid
= strtoull(val
, NULL
, 0);
123 void KeyRing::encode_plaintext(bufferlist
& bl
)
125 std::ostringstream os
;
127 string str
= os
.str();
131 void KeyRing::encode_formatted(string label
, Formatter
*f
, bufferlist
& bl
)
133 std::ostringstream(os
);
134 f
->open_array_section(label
.c_str());
135 for (map
<EntityName
, EntityAuth
>::iterator p
= keys
.begin();
139 f
->open_object_section("auth_entities");
140 f
->dump_string("entity", p
->first
.to_str().c_str());
141 std::ostringstream keyss
;
142 keyss
<< p
->second
.key
;
143 f
->dump_string("key", keyss
.str());
144 if (p
->second
.auid
!= CEPH_AUTH_UID_DEFAULT
)
145 f
->dump_int("auid", p
->second
.auid
);
146 f
->open_object_section("caps");
147 for (map
<string
, bufferlist
>::iterator q
= p
->second
.caps
.begin();
148 q
!= p
->second
.caps
.end();
150 bufferlist::iterator dataiter
= q
->second
.begin();
152 ::decode(caps
, dataiter
);
153 f
->dump_string(q
->first
.c_str(), caps
);
155 f
->close_section(); /* caps */
156 f
->close_section(); /* auth_entities */
158 f
->close_section(); /* auth_dump */
162 void KeyRing::decode_plaintext(bufferlist::iterator
& bli
)
168 std::deque
<std::string
> parse_errors
;
170 if (cf
.parse_bufferlist(&bl
, &parse_errors
, NULL
) != 0) {
171 throw buffer::malformed_input("cannot parse buffer");
174 for (ConfFile::const_section_iter_t s
= cf
.sections_begin();
175 s
!= cf
.sections_end(); ++s
) {
176 string name
= s
->first
;
177 if (name
== "global")
181 map
<string
, bufferlist
> caps
;
182 if (!ename
.from_str(name
)) {
184 oss
<< "bad entity name in keyring: " << name
;
185 throw buffer::malformed_input(oss
.str().c_str());
188 for (ConfSection::const_line_iter_t l
= s
->second
.lines
.begin();
189 l
!= s
->second
.lines
.end(); ++l
) {
193 std::replace(k
.begin(), k
.end(), '_', ' ');
194 ret
= set_modifier(k
.c_str(), l
->val
.c_str(), ename
, caps
);
197 oss
<< "error setting modifier for [" << name
<< "] type=" << k
198 << " val=" << l
->val
;
199 throw buffer::malformed_input(oss
.str().c_str());
205 void KeyRing::decode(bufferlist::iterator
& bl
) {
207 bufferlist::iterator start_pos
= bl
;
209 ::decode(struct_v
, bl
);
211 } catch (buffer::error
& err
) {
213 decode_plaintext(start_pos
);
217 int KeyRing::load(CephContext
*cct
, const std::string
&filename
)
219 if (filename
.empty())
224 int ret
= bl
.read_file(filename
.c_str(), &err
);
226 lderr(cct
) << "error reading file: " << filename
<< ": " << err
<< dendl
;
231 bufferlist::iterator iter
= bl
.begin();
234 catch (const buffer::error
& err
) {
235 lderr(cct
) << "error parsing file " << filename
<< dendl
;
239 ldout(cct
, 2) << "KeyRing::load: loaded key file " << filename
<< dendl
;
243 void KeyRing::print(ostream
& out
)
245 for (map
<EntityName
, EntityAuth
>::iterator p
= keys
.begin();
248 out
<< "[" << p
->first
<< "]" << std::endl
;
249 out
<< "\tkey = " << p
->second
.key
<< std::endl
;
250 if (p
->second
.auid
!= CEPH_AUTH_UID_DEFAULT
)
251 out
<< "\tauid = " << p
->second
.auid
<< std::endl
;
253 for (map
<string
, bufferlist
>::iterator q
= p
->second
.caps
.begin();
254 q
!= p
->second
.caps
.end();
256 bufferlist::iterator dataiter
= q
->second
.begin();
258 ::decode(caps
, dataiter
);
259 out
<< "\tcaps " << q
->first
<< " = \"" << caps
<< '"' << std::endl
;
264 void KeyRing::import(CephContext
*cct
, KeyRing
& other
)
266 for (map
<EntityName
, EntityAuth
>::iterator p
= other
.keys
.begin();
267 p
!= other
.keys
.end();
269 ldout(cct
, 10) << " importing " << p
->first
<< dendl
;
270 ldout(cct
, 30) << " " << p
->second
<< dendl
;
271 keys
[p
->first
] = p
->second
;