providers.c revision e625eb47a3091d92eda2271b123f8aab06227b63
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek/*
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek SSSD
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek Secrets Responder
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek This program is free software; you can redistribute it and/or modify
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek it under the terms of the GNU General Public License as published by
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek the Free Software Foundation; either version 3 of the License, or
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek (at your option) any later version.
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek This program is distributed in the hope that it will be useful,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek but WITHOUT ANY WARRANTY; without even the implied warranty of
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek GNU General Public License for more details.
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek You should have received a copy of the GNU General Public License
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek along with this program. If not, see <http://www.gnu.org/licenses/>.
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek*/
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "responder/secrets/secsrv_private.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "responder/secrets/secsrv_local.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "responder/secrets/secsrv_proxy.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include <jansson.h>
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_map_url_to_user_path(struct sec_req_ctx *secreq, char **mapped_path)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uid_t c_euid;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek c_euid = client_euid(secreq->cctx->creds);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* change path to be user specific */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *mapped_path =
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek talloc_asprintf(secreq, SEC_BASEPATH"users/%"SPRIuid"/%s",
50c9d542e8bf641412debaa82a4dcf67ddb72258Lukas Slebodnik c_euid,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &secreq->parsed_url.path[sizeof(SEC_BASEPATH) - 1]);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!*mapped_path) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Failed to map request to user specific url\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_req_routing(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct provider_handle **handle)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct sec_ctx *sctx;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char **sections;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *def_provider;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *provider;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int num_sections;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sctx = talloc_get_type(secreq->cctx->rctx->pvt_ctx, struct sec_ctx);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* patch must start with /secrets/ for now */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = strncasecmp(secreq->parsed_url.path,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek SEC_BASEPATH, sizeof(SEC_BASEPATH) - 1);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret != 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Path [%s] does not start with "SEC_BASEPATH"\n",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek secreq->parsed_url.path);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EPERM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = sec_map_url_to_user_path(secreq, &secreq->mapped_path);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret) return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* source default provider */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = confdb_get_string(secreq->cctx->rctx->cdb, mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek CONFDB_SEC_CONF_ENTRY, "provider", "LOCAL",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &def_provider);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret) return EIO;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = confdb_get_sub_sections(mem_ctx, secreq->cctx->rctx->cdb,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek CONFDB_SEC_CONF_ENTRY, &sections,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &num_sections);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret != EOK) return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek provider = def_provider;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek // TODO order by length ?
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov for (int i = 0; i < num_sections; i++) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int slen;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek secreq->base_path = talloc_asprintf(secreq, SEC_BASEPATH"%s/", sections[i]);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!secreq->base_path) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek slen = strlen(secreq->base_path);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (strncmp(secreq->base_path, secreq->mapped_path, slen) == 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *secname;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek secname = talloc_asprintf(mem_ctx, CONFDB_SEC_CONF_ENTRY"/%s",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sections[i]);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!secname) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek provider = NULL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = confdb_get_string(secreq->cctx->rctx->cdb, mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek secname, "provider", def_provider,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &provider);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret || !provider) return EIO;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek secreq->cfg_section = talloc_steal(secreq, secname);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!secreq->cfg_section) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek break;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek talloc_zfree(secreq->base_path);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!secreq->base_path) secreq->base_path = SEC_BASEPATH;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = sec_get_provider(sctx, provider, handle);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret == ENOENT) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (strcasecmp(provider, "LOCAL") == 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = local_secrets_provider_handle(sctx, handle);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek } else if (strcasecmp(provider, "PROXY") == 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = proxy_secrets_provider_handle(sctx, handle);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek } else {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_FATAL_FAILURE,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Unknown provider type: %s\n", provider);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EIO;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret == EOK) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = sec_add_provider(sctx, *handle);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ret;
234958be042980242fff6da936af674da877c5efSimo Sorce}
234958be042980242fff6da936af674da877c5efSimo Sorce
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_provider_recv(struct tevent_req *req) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek TEVENT_REQ_RETURN_ON_ERROR(req);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
234958be042980242fff6da936af674da877c5efSimo Sorcestatic struct sec_http_status_format_table {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int status;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const char *text;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const char *description;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek} sec_http_status_format_table[] = {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 200, "OK", "Success" },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 400, "Bad Request",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "The request format is invalid." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 401, "Unauthorized",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Access to the requested resource requires authentication." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 403, "Forbidden",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Access to the requested resource is forbidden." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 404, "Not Found",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "The requested resource was not found." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 405, "Method Not Allowed",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Request method not allowed for this resource." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 406, "Not Acceptable",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "The request cannot be accepted." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 409, "Conflict",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "The requested resource already exists." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek { 500, "Internal Server Error",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "The server encountered an internal error." },
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek};
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_http_status_reply(TALLOC_CTX *mem_ctx, struct sec_data *reply,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek enum sec_http_status_codes code)
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *body = talloc_asprintf(mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "<html>\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "<head>\r\n<title>%d %s</title></head>\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "<body>\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "<h1>%s</h1>\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "<p>%s</p>\r\n"
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta "</body>",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].status,
19d8bc19b5b5597427878645644fa354ef6cb54dMichal Zidek sec_http_status_format_table[code].text,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].text,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].description);
3ac7c4fe618ede980a4df8d90341ef1fd0f1f62fWilliam B if (!body) return ENOMEM;
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_asprintf(mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "HTTP/1.1 %d %s\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Content-Length: %u\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Content-Type: text/html\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "%s",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].status,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].text,
19d8bc19b5b5597427878645644fa354ef6cb54dMichal Zidek (unsigned)strlen(body), body);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek talloc_free(body);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta reply->length = strlen(reply->data);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
19d8bc19b5b5597427878645644fa354ef6cb54dMichal Zidekint sec_http_reply_with_body(TALLOC_CTX *mem_ctx, struct sec_data *reply,
19d8bc19b5b5597427878645644fa354ef6cb54dMichal Zidek enum sec_http_status_codes code,
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta const char *content_type,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct sec_data *body)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int head_size;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_asprintf(mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "HTTP/1.1 %d %s\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Content-Type: %s\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Content-Length: %lu\r\n"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "\r\n",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].status,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sec_http_status_format_table[code].text,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek content_type, body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek head_size = strlen(reply->data);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_realloc(mem_ctx, reply->data, char,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek head_size + body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek memcpy(&reply->data[head_size], body->data, body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->length = head_size + body->length;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_http_append_header(TALLOC_CTX *mem_ctx, char **dest,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *field, char *value)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (*dest == NULL) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *dest = talloc_asprintf(mem_ctx, "%s: %s\r\n", field, value);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek } else {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *dest = talloc_asprintf_append_buffer(*dest, "%s: %s\r\n",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek field, value);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!*dest) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int status_code, const char *reason,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct sec_kvp *headers, int num_headers,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct sec_data *body)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const char *reason_phrase = reason ? reason : "";
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek bool add_content_length = true;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek bool has_content_type = false;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* Status-Line */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_asprintf(mem_ctx, "HTTP/1.1 %d %s\r\n",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek status_code, reason_phrase);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* Headers */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek for (int i = 0; i < num_headers; i++) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (strcasecmp(headers[i].name, "Content-Length") == 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek add_content_length = false;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek } else if (strcasecmp(headers[i].name, "Content-Type") == 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek has_content_type = true;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = sec_http_append_header(mem_ctx, &reply->data,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek headers[i].name, headers[i].value);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret) return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!has_content_type) return EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (add_content_length) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_asprintf_append_buffer(reply->data,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Content-Length: %u\r\n", (unsigned)body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* CRLF separator before body */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_strdup_append_buffer(reply->data, "\r\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->length = strlen(reply->data);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* Message-Body */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (body && body->length) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->data = talloc_realloc(mem_ctx, reply->data, char,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->length + body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!reply->data) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek memcpy(&reply->data[reply->length], body->data, body->length);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek reply->length += body->length;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekenum sec_http_status_codes sec_errno_to_http_status(errno_t err)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek switch (err) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EOK:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_200;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EINVAL:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_400;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EACCES:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_401;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EPERM:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_403;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case ENOENT:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_404;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EISDIR:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_405;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EMEDIUMTYPE:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_406;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek case EEXIST:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_409;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek default:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return STATUS_500;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_json_to_simple_secret(TALLOC_CTX *mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const char *input,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char **secret)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_t *root;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_t *element;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_error_t error;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek root = json_loads(input, 0, &error);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!root) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek "Failed to parse JSON payload on line %d: %s\n",
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek error.line, error.text);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!json_is_object(root)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Json data is not an object.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek element = json_object_get(root, "type");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!element) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Json data key 'type' not found.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!json_is_string(element)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Json object 'type' is not a string.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (strcmp(json_string_value(element), "simple") != 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Token type is not 'simple'.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EMEDIUMTYPE;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta element = json_object_get(root, "value");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!element) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Json key 'value' not found.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!json_is_string(element)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek DEBUG(SSSDBG_CRIT_FAILURE, "Json object 'value' is not a string.\n");
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = EINVAL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *secret = talloc_strdup(mem_ctx, json_string_value(element));
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!*secret) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek } else {
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta ret = EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekdone:
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_decref(root);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_simple_secret_to_json(TALLOC_CTX *mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const char *secret,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char **output)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *jsonized = NULL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_t *root;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek root = json_pack("{s:s, s:s}", "type", "simple", "value", secret);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!root) return ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek jsonized = json_dumps(root, JSON_INDENT(4));
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!jsonized) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *output = talloc_strdup(mem_ctx, jsonized);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!*output) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = ENOMEM;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek goto done;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
6b57784f0f175275fd900eca21c77415e3a5ea52Jakub Hrozek ret = EOK;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
dfe84158c49e44f2207b94d25e61ab4f3fe38366Michal Zidekdone:
dfe84158c49e44f2207b94d25e61ab4f3fe38366Michal Zidek json_decref(root);
dfe84158c49e44f2207b94d25e61ab4f3fe38366Michal Zidek free(jsonized);
dfe84158c49e44f2207b94d25e61ab4f3fe38366Michal Zidek return ret;
dfe84158c49e44f2207b94d25e61ab4f3fe38366Michal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint sec_array_to_json(TALLOC_CTX *mem_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char **array, int count,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char **output)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek char *jsonized = NULL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_t *root;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek root = json_array();
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek for (int i = 0; i < count; i++) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek // FIXME: json_string mem leak ?
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek // FIXME: Error checking
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek json_array_append_new(root, json_string(array[i]));
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
jsonized = json_dumps(root, JSON_INDENT(4));
if (!jsonized) {
ret = ENOMEM;
goto done;
}
*output = talloc_strdup(mem_ctx, jsonized);
if (!*output) {
ret = ENOMEM;
goto done;
}
ret = EOK;
done:
json_decref(root);
free(jsonized);
return ret;
}
int sec_get_provider(struct sec_ctx *sctx, const char *name,
struct provider_handle **out_handle)
{
struct provider_handle *handle;
for (int i = 0; sctx->providers && sctx->providers[i]; i++) {
handle = sctx->providers[i];
if (strcasecmp(handle->name, name) != 0) {
continue;
}
*out_handle = handle;
return EOK;
}
return ENOENT;
}
int sec_add_provider(struct sec_ctx *sctx, struct provider_handle *handle)
{
int c;
for (c = 0; sctx->providers && sctx->providers[c]; c++)
continue;
sctx->providers = talloc_realloc(sctx, sctx->providers,
struct provider_handle *, c + 2);
if (!sctx->providers) return ENOMEM;
sctx->providers[c] = talloc_steal(sctx, handle);
sctx->providers[c + 1] = NULL;
return EOK;
}
bool sec_req_has_header(struct sec_req_ctx *req,
const char *name, const char *value)
{
for (int i = 0; i < req->num_headers; i++) {
if (strcasecmp(name, req->headers[i].name) == 0) {
if (value == NULL) return true;
return (strcasecmp(value, req->headers[i].value) == 0);
}
}
return false;
}