local.c revision ab7b33fd7d820688545d5994a402cedf4bcdb6e1
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser Secrets Responder
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn This program is free software; you can redistribute it and/or modify
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn it under the terms of the GNU General Public License as published by
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn the Free Software Foundation; either version 3 of the License, or
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn (at your option) any later version.
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn This program is distributed in the hope that it will be useful,
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn but WITHOUT ANY WARRANTY; without even the implied warranty of
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn GNU General Public License for more details.
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn You should have received a copy of the GNU General Public License
acbb59f50d5196facde837ea377f70e98ce1e6f8Serge Hallyn along with this program. If not, see <http://www.gnu.org/licenses/>.
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallynint local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
1aad9e44d65e7c20dabc4c99f57bcf532db66c68Serge Hallyn if (enctype && strcmp(enctype, "masterkey") == 0) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn _secret.data = (char *)sss_base64_decode(mem_ctx, secret,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
4759162d078d86628956cae4846c6efccf548e67Serge Hallyn if (((strnlen(output, outlen) + 1) != outlen) ||
9313e1e628160ca64f9e7fcec6500056c9a0725fStéphane Graberint local_encrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber if (!enctype || strcmp(enctype, "masterkey") != 0) return EINVAL;
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber (const uint8_t *)secret, strlen(secret) + 1,
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber (uint8_t **)&_secret.data, &_secret.length);
f2a95ee1bf54c949614a68bf152ea9a8e1d3a172Stéphane Graber const char *s, *e;
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber dn = ldb_dn_new(mem_ctx, ldb, "cn=secrets");
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber while (s && *s) {
0a3673e80732ab83d807d406fb2fd3c3b7f54ad3Stéphane Graber if (e == s) {
42ff5f0f8767114d060f5031055038a1a1c3759aSerge Hallyn if (!ldb_dn_add_child_fmt(dn, "cn=%.*s", (int)(e - s), s)) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn for (int i = dncomps - basecomps; i > 0; i--) {
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn path = talloc_strndup_append_buffer(path, (char *)val->data,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser path = talloc_strndup(mem_ctx, (char *)val->data, val->length);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn#define LOCAL_CONTAINER_FILTER "(type=container)"
ed4616b1cfbc84dd01caa8546d813e8c5d482921Christian Bühlerint local_db_get_simple(TALLOC_CTX *mem_ctx,
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn static const char *attrs[] = { "secret", "enctype", NULL };
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
427bffc7a10c9015dc78ef52543f7b8cb9414359Serge Hallyn ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser attr_secret = ldb_msg_find_attr_as_string(res->msgs[0], "secret", NULL);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser ret = local_decrypt(lctx, mem_ctx, attr_secret, attr_enctype, secret);
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber static const char *attrs[] = { "secret", NULL };
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
8a63c0a9d9089e6365e5a696455476febed39d6aStéphane Graber ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn keys = talloc_array(mem_ctx, char *, res->count);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn keys[i] = local_dn_to_path(keys, dn, res->msgs[i]->dn);
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moserint local_db_check_containers(TALLOC_CTX *mem_ctx,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn /* We need to exclude the leaf as that will be the new child entry,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn * We also do not care for the synthetic containers that constitute the
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn * base path (cn=<uidnumber>,cn=users,cn=secrets), so in total we remove
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn * 4 components */
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn for (int i = 0; i < num; i++) {
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn /* remove the child first (we do not want to check the leaf) */
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn if (!ldb_dn_remove_child_components(dn, 1)) return EFAULT;
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn /* and check the parent container exists */
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn ret = ldb_search(lctx->ldb, mem_ctx, &res, dn, LDB_SCOPE_BASE,
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn /* make sure containers exist */
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn ret = local_db_check_containers(msg, lctx, msg->dn);
3eecde703e9ac3af788ac17357f378d6b6d7c658Serge Hallyn ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = ldb_msg_add_string(msg, "type", "simple");
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = ldb_msg_add_string(msg, "enctype", enctype);
f1ccde27c038e7fb7e538913505248b36ddd9e65Serge Hallyn ret = ldb_msg_add_string(msg, "secret", enc_secret);
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) ret = EEXIST;
65d8ae9c4a66f5ca85289c02dc06d63261c84619Scott Moser ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn);
c01c25fcdd1e0cacad8075bcfcef4c8e8d4b8cb6Stéphane Graber ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
d1458ac8d13880f83fa2d1e08623b97c50d311d7Serge Hallyn ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
goto done;
done:
return ret;
const char *req_path)
int ret;
if (!msg) {
goto done;
goto done;
done:
return ret;
char **local_db_path)
int ret;
return EINVAL;
return EINVAL;
if (ret != 0) {
return EINVAL;
if (!*local_db_path) {
return ENOMEM;
return EOK;
struct local_secret_state {
void *provider_ctx,
const char *content_type;
bool body_is_json;
char *req_path;
char *secret;
char **keys;
int nkeys;
int plen;
int ret;
if (!lctx) {
goto done;
"application/json")) {
body_is_json = true;
"application/octet-stream")) {
body_is_json = false;
goto done;
case HTTP_GET:
if (body_is_json) {
case HTTP_PUT:
if (body_is_json) {
&secret);
case HTTP_DELETE:
case HTTP_POST:
goto done;
goto done;
done:
int ret;
int fd;
return EFAULT;
return EOK;
int mfd;
int ret;
return EIO;
return EOK;