]>
git.proxmox.com Git - ceph.git/blob - ceph/src/auth/KeyRing.cc
0b28ff6106393fc8493759f6ece37f60e157cc55
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 <boost/algorithm/string/replace.hpp>
21 #include "auth/KeyRing.h"
22 #include "common/ceph_context.h"
23 #include "common/config.h"
24 #include "common/debug.h"
25 #include "common/errno.h"
26 #include "common/Formatter.h"
28 #define dout_subsys ceph_subsys_auth
31 #define dout_prefix *_dout << "auth: "
35 using std::ostringstream
;
38 using ceph::bufferlist
;
39 using ceph::Formatter
;
41 int KeyRing::from_ceph_context(CephContext
*cct
)
43 const auto& conf
= cct
->_conf
;
46 int ret
= ceph_resolve_file_search(conf
->keyring
, filename
);
48 ret
= load(cct
, filename
);
50 lderr(cct
) << "failed to load " << filename
51 << ": " << cpp_strerror(ret
) << dendl
;
52 } else if (conf
->key
.empty() && conf
->keyfile
.empty()) {
53 lderr(cct
) << "unable to find a keyring on " << conf
->keyring
54 << ": " << cpp_strerror(ret
) << dendl
;
57 if (!conf
->key
.empty()) {
60 ea
.key
.decode_base64(conf
->key
);
64 catch (ceph::buffer::error
& e
) {
65 lderr(cct
) << "failed to decode key '" << conf
->key
<< "'" << dendl
;
70 if (!conf
->keyfile
.empty()) {
73 int r
= bl
.read_file(conf
->keyfile
.c_str(), &err
);
75 lderr(cct
) << err
<< dendl
;
78 string
k(bl
.c_str(), bl
.length());
81 ea
.key
.decode_base64(k
);
84 catch (ceph::buffer::error
& e
) {
85 lderr(cct
) << "failed to decode key '" << k
<< "'" << dendl
;
94 int KeyRing::set_modifier(const char *type
,
97 map
<string
, bufferlist
>& caps
)
102 if (strcmp(type
, "key") == 0) {
106 key
.decode_base64(l
);
107 } catch (const ceph::buffer::error
& err
) {
111 } else if (strncmp(type
, "caps ", 5) == 0) {
112 const char *caps_entity
= type
+ 5;
118 caps
[caps_entity
] = bl
;
119 set_caps(name
, caps
);
120 } else if (strcmp(type
, "auid") == 0) {
121 // just ignore it so we can still decode "old" keyrings that have an auid
128 void KeyRing::encode_plaintext(bufferlist
& bl
)
130 std::ostringstream os
;
132 string str
= os
.str();
136 void KeyRing::encode_formatted(string label
, Formatter
*f
, bufferlist
& bl
)
138 f
->open_array_section(label
.c_str());
139 for (map
<EntityName
, EntityAuth
>::iterator p
= keys
.begin();
143 f
->open_object_section("auth_entities");
144 f
->dump_string("entity", p
->first
.to_str().c_str());
145 std::ostringstream keyss
;
146 keyss
<< p
->second
.key
;
147 f
->dump_string("key", keyss
.str());
148 f
->open_object_section("caps");
149 for (map
<string
, bufferlist
>::iterator q
= p
->second
.caps
.begin();
150 q
!= p
->second
.caps
.end();
152 auto dataiter
= q
->second
.cbegin();
155 decode(caps
, dataiter
);
156 f
->dump_string(q
->first
.c_str(), caps
);
158 f
->close_section(); /* caps */
159 f
->close_section(); /* auth_entities */
161 f
->close_section(); /* auth_dump */
165 void KeyRing::decode(bufferlist::const_iterator
& bli
)
172 if (cf
.parse_bufferlist(&bl
, nullptr) != 0) {
173 throw ceph::buffer::malformed_input("cannot parse buffer");
176 for (auto& [name
, section
] : cf
) {
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 ceph::buffer::malformed_input(oss
.str().c_str());
188 for (auto& [k
, val
] : section
) {
192 std::replace_copy(k
.begin(), k
.end(), back_inserter(key
), '_', ' ');
193 ret
= set_modifier(key
.c_str(), val
.c_str(), ename
, caps
);
196 oss
<< "error setting modifier for [" << name
<< "] type=" << key
198 throw ceph::buffer::malformed_input(oss
.str().c_str());
204 int KeyRing::load(CephContext
*cct
, const std::string
&filename
)
206 if (filename
.empty())
211 int ret
= bl
.read_file(filename
.c_str(), &err
);
213 lderr(cct
) << "error reading file: " << filename
<< ": " << err
<< dendl
;
218 auto iter
= bl
.cbegin();
221 catch (const ceph::buffer::error
& err
) {
222 lderr(cct
) << "error parsing file " << filename
<< ": " << err
.what() << dendl
;
226 ldout(cct
, 2) << "KeyRing::load: loaded key file " << filename
<< dendl
;
230 void KeyRing::print(ostream
& out
)
232 for (map
<EntityName
, EntityAuth
>::iterator p
= keys
.begin();
235 out
<< "[" << p
->first
<< "]" << std::endl
;
236 out
<< "\tkey = " << p
->second
.key
<< std::endl
;
238 for (map
<string
, bufferlist
>::iterator q
= p
->second
.caps
.begin();
239 q
!= p
->second
.caps
.end();
241 auto dataiter
= q
->second
.cbegin();
244 decode(caps
, dataiter
);
245 boost::replace_all(caps
, "\"", "\\\"");
246 out
<< "\tcaps " << q
->first
<< " = \"" << caps
<< '"' << std::endl
;
251 void KeyRing::import(CephContext
*cct
, KeyRing
& other
)
253 for (map
<EntityName
, EntityAuth
>::iterator p
= other
.keys
.begin();
254 p
!= other
.keys
.end();
256 ldout(cct
, 10) << " importing " << p
->first
<< dendl
;
257 ldout(cct
, 30) << " " << p
->second
<< dendl
;
258 keys
[p
->first
] = p
->second
;