1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce/*
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce SSSD
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce Secrets Responder
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce This program is free software; you can redistribute it and/or modify
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce it under the terms of the GNU General Public License as published by
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce the Free Software Foundation; either version 3 of the License, or
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce (at your option) any later version.
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce This program is distributed in the hope that it will be useful,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce but WITHOUT ANY WARRANTY; without even the implied warranty of
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce GNU General Public License for more details.
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce You should have received a copy of the GNU General Public License
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce along with this program. If not, see <http://www.gnu.org/licenses/>.
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce*/
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#include "responder/secrets/secsrv_private.h"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#include "responder/secrets/secsrv_local.h"
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#include "responder/secrets/secsrv_proxy.h"
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina#include "util/sss_iobuf.h"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce#include <jansson.h>
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozektypedef int (*url_mapper_fn)(struct sec_req_ctx *secreq,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek char **mapped_path);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozekstruct url_pfx_router {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek const char *prefix;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek url_mapper_fn mapper_fn;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek};
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
cf902c2b247c1b5793ae0ba58fd2dcbb0f78b686Jakub Hrozekstatic int sec_map_url_to_user_path(struct sec_req_ctx *secreq,
cf902c2b247c1b5793ae0ba58fd2dcbb0f78b686Jakub Hrozek char **mapped_path)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce uid_t c_euid;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce c_euid = client_euid(secreq->cctx->creds);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* change path to be user specific */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce *mapped_path =
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce talloc_asprintf(secreq, SEC_BASEPATH"users/%"SPRIuid"/%s",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce c_euid,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce &secreq->parsed_url.path[sizeof(SEC_BASEPATH) - 1]);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!*mapped_path) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Failed to map request to user specific url\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "User-specific secrets path is [%s]\n", *mapped_path);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek return EOK;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek}
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozekstatic int kcm_map_url_to_path(struct sec_req_ctx *secreq,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek char **mapped_path)
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek{
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek uid_t c_euid;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek c_euid = client_euid(secreq->cctx->creds);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek if (c_euid != KCM_PEER_UID) {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "UID %"SPRIuid" is not allowed to access "
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "the "SEC_KCM_BASEPATH" hive\n",
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek c_euid);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek return EPERM;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek }
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek *mapped_path = talloc_strdup(secreq, secreq->parsed_url.path );
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek if (!*mapped_path) {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "Failed to map request to user specific url\n");
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek return ENOMEM;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek }
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "User-specific KCM path is [%s]\n", *mapped_path);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozekstatic struct url_pfx_router secrets_url_mapping[] = {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek { SEC_BASEPATH, sec_map_url_to_user_path },
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek { SEC_KCM_BASEPATH, kcm_map_url_to_path },
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek { NULL, NULL },
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek};
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_req_routing(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce struct provider_handle **handle)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_ctx *sctx;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char **sections;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *def_provider;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *provider;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int num_sections;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int ret;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek url_mapper_fn mapper_fn = NULL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce sctx = talloc_get_type(secreq->cctx->rctx->pvt_ctx, struct sec_ctx);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek for (int i = 0; secrets_url_mapping[i].prefix != NULL; i++) {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek if (strncasecmp(secreq->parsed_url.path,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek secrets_url_mapping[i].prefix,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek strlen(secrets_url_mapping[i].prefix)) == 0) {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "Mapping prefix %s\n", secrets_url_mapping[i].prefix);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek mapper_fn = secrets_url_mapping[i].mapper_fn;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek break;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek }
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek }
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek if (mapper_fn == NULL) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "Path [%s] does not start with any allowed prefix\n",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce secreq->parsed_url.path);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EPERM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek ret = mapper_fn(secreq, &secreq->mapped_path);
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek if (ret != EOK) {
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek "Failed to map the user path [%d]: %s\n",
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek ret, sss_strerror(ret));
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek return ret;
60612b5fbdaaa62ebe6c7f4c27200316f08506d6Jakub Hrozek }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce /* source default provider */
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = confdb_get_string(secreq->cctx->rctx->cdb, mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce CONFDB_SEC_CONF_ENTRY, "provider", "LOCAL",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce &def_provider);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (ret) return EIO;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "The default provider is '%s'\n", def_provider);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = confdb_get_sub_sections(mem_ctx, secreq->cctx->rctx->cdb,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce CONFDB_SEC_CONF_ENTRY, &sections,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce &num_sections);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (ret != EOK) return ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "confdb section %s has %d sub-sections\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek CONFDB_SEC_CONF_ENTRY, num_sections);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce provider = def_provider;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
677a31351c80453d9ce006481364399a96312052René Genz // TODO order by length?
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce for (int i = 0; i < num_sections; i++) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int slen;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce secreq->base_path = talloc_asprintf(secreq, SEC_BASEPATH"%s/", sections[i]);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!secreq->base_path) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce slen = strlen(secreq->base_path);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "matching subsection [%s]\n", sections[i]);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (strncmp(secreq->base_path, secreq->mapped_path, slen) == 0) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *secname;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce secname = talloc_asprintf(mem_ctx, CONFDB_SEC_CONF_ENTRY"/%s",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sections[i]);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!secname) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce provider = NULL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = confdb_get_string(secreq->cctx->rctx->cdb, mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce secname, "provider", def_provider,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce &provider);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (ret || !provider) return EIO;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "matched subsection %s with provider %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sections[i], provider);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce secreq->cfg_section = talloc_steal(secreq, secname);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!secreq->cfg_section) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce break;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce talloc_zfree(secreq->base_path);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!secreq->base_path) secreq->base_path = SEC_BASEPATH;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Request base path is [%s]\n", secreq->base_path);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Request provider is [%s]\n", provider);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = sec_get_provider(sctx, provider, handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret == ENOENT) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (strcasecmp(provider, "LOCAL") == 0) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = local_secrets_provider_handle(sctx, handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else if (strcasecmp(provider, "PROXY") == 0) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_secrets_provider_handle(sctx, handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce DEBUG(SSSDBG_FATAL_FAILURE,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "Unknown provider type: %s\n", provider);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = EIO;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret == EOK) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = sec_add_provider(sctx, *handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_provider_recv(struct tevent_req *req) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce TEVENT_REQ_RETURN_ON_ERROR(req);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Request finished\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcestatic struct sec_http_status_format_table {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int status;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *text;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *description;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce} sec_http_status_format_table[] = {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 200, "OK", "Success" },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 400, "Bad Request",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "The request format is invalid." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 401, "Unauthorized",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Access to the requested resource requires authentication." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 403, "Forbidden",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Access to the requested resource is forbidden." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 404, "Not Found",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "The requested resource was not found." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 405, "Method Not Allowed",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Request method not allowed for this resource." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 406, "Not Acceptable",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "The request cannot be accepted." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 409, "Conflict",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "The requested resource already exists." },
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio { 413, "Payload Too Large",
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio "The secret payload is too large." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce { 500, "Internal Server Error",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "The server encountered an internal error." },
41cd6072648bb7a9e14e56ed38004a2947f67657Jakub Hrozek { 504, "Gateway timeout",
41cd6072648bb7a9e14e56ed38004a2947f67657Jakub Hrozek "No response from a proxy server." },
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio { 507, "Insufficient Storage",
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio "The server is unable to store the resource needed to complete the request." },
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce};
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_http_status_reply(TALLOC_CTX *mem_ctx, struct sec_data *reply,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce enum sec_http_status_codes code)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *body = talloc_asprintf(mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "<html>\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "<head>\r\n<title>%d %s</title></head>\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "<body>\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "<h1>%s</h1>\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "<p>%s</p>\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "</body>",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].status,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].text,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].text,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].description);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!body) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce reply->data = talloc_asprintf(mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "HTTP/1.1 %d %s\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Content-Length: %u\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Content-Type: text/html\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "%s",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].status,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].text,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce (unsigned)strlen(body), body);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce talloc_free(body);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!reply->data) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce reply->length = strlen(reply->data);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "HTTP reply %d: %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sec_http_status_format_table[code].status,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sec_http_status_format_table[code].text);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_http_reply_with_body(TALLOC_CTX *mem_ctx, struct sec_data *reply,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce enum sec_http_status_codes code,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *content_type,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce struct sec_data *body)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int head_size;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce reply->data = talloc_asprintf(mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "HTTP/1.1 %d %s\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Content-Type: %s\r\n"
3e81e71124c75fd8709704e38561fa1f9d5bfbc2Lukas Slebodnik "Content-Length: %zu\r\n"
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "\r\n",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].status,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce sec_http_status_format_table[code].text,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce content_type, body->length);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!reply->data) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce head_size = strlen(reply->data);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce reply->data = talloc_realloc(mem_ctx, reply->data, char,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce head_size + body->length);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!reply->data) return ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce memcpy(&reply->data[head_size], body->data, body->length);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce reply->length = head_size + body->length;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "HTTP reply %d: %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sec_http_status_format_table[code].status,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek sec_http_status_format_table[code].text);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint sec_http_append_header(TALLOC_CTX *mem_ctx, char **dest,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *field, char *value)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (*dest == NULL) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce *dest = talloc_asprintf(mem_ctx, "%s: %s\r\n", field, value);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce *dest = talloc_asprintf_append_buffer(*dest, "%s: %s\r\n",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce field, value);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!*dest) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int status_code, const char *reason,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_kvp *headers, int num_headers,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_data *body)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce const char *reason_phrase = reason ? reason : "";
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce bool add_content_length = true;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce bool has_content_type = false;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* Status-Line */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->data = talloc_asprintf(mem_ctx, "HTTP/1.1 %d %s\r\n",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce status_code, reason_phrase);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!reply->data) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "HTTP reply %d: %s\n", status_code, reason_phrase);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* Headers */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce for (int i = 0; i < num_headers; i++) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (strcasecmp(headers[i].name, "Content-Length") == 0) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce add_content_length = false;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce } else if (strcasecmp(headers[i].name, "Content-Type") == 0) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce has_content_type = true;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = sec_http_append_header(mem_ctx, &reply->data,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce headers[i].name, headers[i].value);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) return ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (!has_content_type) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "No Content-Type header\n");
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek return EINVAL;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (add_content_length) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce reply->data = talloc_asprintf_append_buffer(reply->data,
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce "Content-Length: %u\r\n", (unsigned)body->length);
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (!reply->data) return ENOMEM;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce }
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* CRLF separator before body */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->data = talloc_strdup_append_buffer(reply->data, "\r\n");
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->length = strlen(reply->data);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* Message-Body */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (body && body->length) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->data = talloc_realloc(mem_ctx, reply->data, char,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->length + body->length);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!reply->data) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce memcpy(&reply->data[reply->length], body->data, body->length);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce reply->length += body->length;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
13d720de13e490850c1139eea865bcd5195a2630Pavel Březinastatic errno_t
13d720de13e490850c1139eea865bcd5195a2630Pavel Březinasec_http_iobuf_split(struct sss_iobuf *response,
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char **headers,
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char **body)
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina{
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char *data = (const char *)sss_iobuf_get_data(response);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina char *delim;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* The last header ends with \r\n and then comes \r\n again as a separator
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina * of body from headers. We can use this to find this point. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina delim = strstr(data, "\r\n\r\n");
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina if (delim == NULL) {
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return EINVAL;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina }
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* Skip to the body delimiter. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina delim = delim + sizeof("\r\n") - 1;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* Replace \r\n with zeros turning data into:
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina * from HEADER\r\nBODY into HEADER\0\0BODY format. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina delim[0] = '\0';
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina delim[1] = '\0';
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* Split the buffer. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina *headers = data;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina *body = delim + 2;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return 0;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina}
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březinastatic const char *
13d720de13e490850c1139eea865bcd5195a2630Pavel Březinasec_http_iobuf_add_content_length(TALLOC_CTX *mem_ctx,
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char *headers,
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina size_t body_len)
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina{
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* If Content-Length is already present we do nothing. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina if (strstr(headers, "Content-Length:") != NULL) {
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return headers;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina }
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return talloc_asprintf(mem_ctx, "%sContent-Length: %zu\r\n",
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina headers, body_len);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina}
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinaerrno_t sec_http_reply_iobuf(TALLOC_CTX *mem_ctx,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sec_data *reply,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina int response_code,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sss_iobuf *response)
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina{
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char *headers;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina const char *body;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina size_t body_len;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina errno_t ret;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_TRACE_LIBS, "HTTP reply %d\n", response_code);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina ret = sec_http_iobuf_split(response, &headers, &body);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina if (ret != EOK) {
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina "Unexpected HTTP reply, returning what we got from server\n");
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina reply->data = (char *)sss_iobuf_get_data(response);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina reply->length = sss_iobuf_get_len(response);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return EOK;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina /* Add Content-Length header if not present so client does not await
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina * not-existing incoming data. */
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina body_len = strlen(body);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina headers = sec_http_iobuf_add_content_length(mem_ctx, headers, body_len);
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina if (headers == NULL) {
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return ENOMEM;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina }
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina reply->length = strlen(headers) + sizeof("\r\n") - 1 + body_len;
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina reply->data = talloc_asprintf(mem_ctx, "%s\r\n%s", headers, body);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (reply->data == NULL) {
13d720de13e490850c1139eea865bcd5195a2630Pavel Březina return ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return EOK;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina}
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceenum sec_http_status_codes sec_errno_to_http_status(errno_t err)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_LIBS, "Request errno: %d\n", err);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce switch (err) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EOK:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_200;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EINVAL:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_400;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EACCES:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_401;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EPERM:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_403;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case ENOENT:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_404;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EISDIR:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_405;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EMEDIUMTYPE:
efc65e78fa4e01e6cecc8690a9899af61213be62Fabiano Fidêncio case ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_406;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce case EEXIST:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_409;
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio case ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE:
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidêncio return STATUS_413;
41cd6072648bb7a9e14e56ed38004a2947f67657Jakub Hrozek case ERR_SEC_NO_PROXY:
41cd6072648bb7a9e14e56ed38004a2947f67657Jakub Hrozek return STATUS_504;
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio case ERR_SEC_INVALID_TOO_MANY_SECRETS:
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio return STATUS_507;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce default:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return STATUS_500;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_json_to_simple_secret(TALLOC_CTX *mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *input,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char **secret)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_t *root;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_t *element;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_error_t error;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce root = json_loads(input, 0, &error);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!root) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce "Failed to parse JSON payload on line %d: %s\n",
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce error.line, error.text);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!json_is_object(root)) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Json data is not an object.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce element = json_object_get(root, "type");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!element) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Json data key 'type' not found.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!json_is_string(element)) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Json object 'type' is not a string.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (strcmp(json_string_value(element), "simple") != 0) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Token type is not 'simple'.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EMEDIUMTYPE;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce element = json_object_get(root, "value");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!element) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Json key 'value' not found.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!json_is_string(element)) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, "Json object 'value' is not a string.\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EINVAL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce *secret = talloc_strdup(mem_ctx, json_string_value(element));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!*secret) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce } else {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcedone:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_decref(root);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_simple_secret_to_json(TALLOC_CTX *mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce const char *secret,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char **output)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *jsonized = NULL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_t *root;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce root = json_pack("{s:s, s:s}", "type", "simple", "value", secret);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (!root) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Failed to pack Json object\n");
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek return ENOMEM;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce jsonized = json_dumps(root, JSON_INDENT(4));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!jsonized) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Failed to dump Json object\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce *output = talloc_strdup(mem_ctx, jsonized);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!*output) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcedone:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_decref(root);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce free(jsonized);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorceint sec_array_to_json(TALLOC_CTX *mem_ctx,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char **array, int count,
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char **output)
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce{
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce char *jsonized = NULL;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_t *root;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce int ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce root = json_array();
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (root == NULL) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Failed to create Json array\n");
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek ret = ENOMEM;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce for (int i = 0; i < count; i++) {
677a31351c80453d9ce006481364399a96312052René Genz // FIXME: json_string mem leak?
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce // FIXME: Error checking
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_array_append_new(root, json_string(array[i]));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce jsonized = json_dumps(root, JSON_INDENT(4));
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!jsonized) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Failed to dump Json object\n");
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce *output = talloc_strdup(mem_ctx, jsonized);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce if (!*output) {
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = ENOMEM;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce goto done;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce }
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce ret = EOK;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorcedone:
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce json_decref(root);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce free(jsonized);
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce return ret;
1dd679584241a0f9b29072c7eed1c5c5e4a577e4Simo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint sec_get_provider(struct sec_ctx *sctx, const char *name,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct provider_handle **out_handle)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct provider_handle *handle;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce for (int i = 0; sctx->providers && sctx->providers[i]; i++) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce handle = sctx->providers[i];
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (strcasecmp(handle->name, name) != 0) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce continue;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce *out_handle = handle;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, "No handle for provider %s\n", name);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return ENOENT;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint sec_add_provider(struct sec_ctx *sctx, struct provider_handle *handle)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int c;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce for (c = 0; sctx->providers && sctx->providers[c]; c++)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce continue;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce sctx->providers = talloc_realloc(sctx, sctx->providers,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct provider_handle *, c + 2);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!sctx->providers) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce sctx->providers[c] = talloc_steal(sctx, handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce sctx->providers[c + 1] = NULL;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorcebool sec_req_has_header(struct sec_req_ctx *req,
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce const char *name, const char *value)
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce{
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce for (int i = 0; i < req->num_headers; i++) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (strcasecmp(name, req->headers[i].name) == 0) {
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce if (value == NULL) return true;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce return (strcasecmp(value, req->headers[i].value) == 0);
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce }
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce }
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce return false;
e625eb47a3091d92eda2271b123f8aab06227b63Simo Sorce}