8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce/*
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SSSD
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce Secrets Responder
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce This program is free software; you can redistribute it and/or modify
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce it under the terms of the GNU General Public License as published by
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce the Free Software Foundation; either version 3 of the License, or
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce (at your option) any later version.
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce This program is distributed in the hope that it will be useful,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce but WITHOUT ANY WARRANTY; without even the implied warranty of
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce GNU General Public License for more details.
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce You should have received a copy of the GNU General Public License
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce along with this program. If not, see <http://www.gnu.org/licenses/>.
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce*/
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#include "responder/secrets/secsrv_private.h"
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#include "util/crypto/sss_crypto.h"
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#include "resolv/async_resolv.h"
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#include "util/sss_sockets.h"
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina#include "util/sss_iobuf.h"
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina#include "util/tev_curl.h"
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina#define SEC_PROXY_TIMEOUT 5
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct proxy_context {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct confdb_ctx *cdb;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct tcurl_ctx *tcurl;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceenum proxy_auth_type {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce PAT_NONE = 0,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce PAT_BASIC_AUTH = 1,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce PAT_HEADER = 2,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct pat_basic_auth {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *username;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *password;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct pat_header {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *name;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *value;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct proxy_cfg {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *url;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char **fwd_headers;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int num_headers;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce enum proxy_auth_type auth_type;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce union {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct pat_basic_auth basic;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct pat_header header;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } auth;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina char *key;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina char *cert;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina char *cacert;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina char *capath;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina bool verify_peer;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina bool verify_host;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestatic int proxy_get_config_string(struct proxy_context *pctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce TALLOC_CTX *ctx, bool not_null,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_req_ctx *secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce const char *name, char **value)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = confdb_get_string(pctx->cdb, ctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce secreq->cfg_section, name, NULL, value);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (not_null && (ret == 0) && (*value == NULL)) ret = EINVAL;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestatic int proxy_sec_get_cfg(struct proxy_context *pctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce TALLOC_CTX *mem_ctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_req_ctx *secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_cfg **target)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_cfg *cfg;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *auth_type;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* find matching remote and build the URI */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg = talloc_zero(mem_ctx, struct proxy_cfg);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!cfg) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, true, secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "proxy_url", &cfg->url);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS, "proxy_url: %s\n", cfg->url);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, false, secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "auth_type", &auth_type);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS, "auth_type: %s\n", auth_type);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (auth_type) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (strcmp(auth_type, "basic_auth") == 0) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->auth_type = PAT_BASIC_AUTH;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, true, secreq, "username",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce &cfg->auth.basic.username);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "username: %s\n", cfg->auth.basic.username);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, true, secreq, "password",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce &cfg->auth.basic.password);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else if (strcmp(auth_type, "header") == 0) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->auth_type = PAT_HEADER;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, true, secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "auth_header_name",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce &cfg->auth.header.name);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "auth_header_name: %s\n", cfg->auth.basic.username);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_get_config_string(pctx, cfg, true, secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "auth_header_value",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce &cfg->auth.header.value);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Unknown auth type!\n");
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = EINVAL;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = confdb_get_bool(pctx->cdb, secreq->cfg_section, "verify_peer",
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina true, &cfg->verify_peer);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "verify_peer: %s\n",
074ded4cda2ce88563a3e7e5cc0eea808d3322b3Lukas Slebodnik cfg->verify_peer ? "true" : "false");
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = confdb_get_bool(pctx->cdb, secreq->cfg_section, "verify_host",
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina true, &cfg->verify_host);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "verify_host: %s\n",
074ded4cda2ce88563a3e7e5cc0eea808d3322b3Lukas Slebodnik cfg->verify_host ? "true" : "false");
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = proxy_get_config_string(pctx, cfg, false, secreq,
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina "capath", &cfg->capath);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "capath: %s\n", cfg->capath);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = proxy_get_config_string(pctx, cfg, false, secreq,
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina "cacert", &cfg->cacert);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "cacert: %s\n", cfg->cacert);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = proxy_get_config_string(pctx, cfg, false, secreq,
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina "cert", &cfg->cert);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "cert: %s\n", cfg->cert);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = proxy_get_config_string(pctx, cfg, false, secreq,
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina "key", &cfg->key);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret) goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina DEBUG(SSSDBG_CONF_SETTINGS, "key: %s\n", cfg->key);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = confdb_get_string_as_list(pctx->cdb, cfg, secreq->cfg_section,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce "forward_headers", &cfg->fwd_headers);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if ((ret != 0) && (ret != ENOENT)) goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce while (cfg->fwd_headers && cfg->fwd_headers[cfg->num_headers]) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CONF_SETTINGS,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "Forwarding header: %s\n", cfg->fwd_headers[cfg->num_headers]);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->num_headers++;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* Always whitelist Content-Type and Content-Length */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->fwd_headers = talloc_realloc(cfg, cfg->fwd_headers, char *,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->num_headers + 3);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!cfg->fwd_headers) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->fwd_headers[cfg->num_headers] = talloc_strdup(cfg, "Content-Type");
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!cfg->fwd_headers[cfg->num_headers]) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->num_headers++;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->fwd_headers[cfg->num_headers] = talloc_strdup(cfg, "Content-Length");
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!cfg->fwd_headers[cfg->num_headers]) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->num_headers++;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce cfg->fwd_headers[cfg->num_headers] = NULL;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcedone:
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret) talloc_free(cfg);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce else *target = cfg;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_SCHEMA(secreq) ((secreq)->parsed_url.schema != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_HOST(secreq) ((secreq)->parsed_url.host != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_PORT(secreq) ((secreq)->parsed_url.port != 0)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_PATH(secreq) ((secreq)->parsed_url.path != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_QUERY(secreq) ((secreq)->parsed_url.query != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_FRAGMENT(secreq) ((secreq)->parsed_url.fragment != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define REQ_HAS_USERINFO(secreq) ((secreq)->parsed_url.userinfo != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define SECREQ_HAS_PORT(secreq) ((secreq)->parsed_url.port != 0)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define SECREQ_PORT(secreq) ((secreq)->parsed_url.port)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define SECREQ_HAS_PART(secreq, part) ((secreq)->parsed_url.part != NULL)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce#define SECREQ_PART(secreq, part) \
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ((secreq)->parsed_url.part ? (secreq)->parsed_url.part : "")
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint proxy_sec_map_url(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_cfg *pcfg, char **req_url)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char port[6] = { 0 };
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *url;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int blen;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (SECREQ_HAS_PORT(secreq)) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = snprintf(port, 6, "%d", SECREQ_PORT(secreq));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (ret < 1 || ret > 5) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed\n");
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek return EINVAL;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce blen = strlen(secreq->base_path);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce url = talloc_asprintf(mem_ctx, "%s%s%s%s%s%s%s%s/%s%s%s%s%s",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_PART(secreq, schema),
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PART(secreq, schema) ? "://" : "",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_PART(secreq, userinfo),
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PART(secreq, userinfo) ? "@" : "",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_PART(secreq, host),
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PORT(secreq) ? ":" : "",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PORT(secreq) ? port : "",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce pcfg->url, &secreq->mapped_path[blen],
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PART(secreq, query) ? "?" :"",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_PART(secreq, query),
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_HAS_PART(secreq, fragment) ? "?" :"",
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce SECREQ_PART(secreq, fragment));
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!url) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "URL: %s\n", url);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce *req_url = url;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinastatic errno_t proxy_http_append_header(TALLOC_CTX *mem_ctx,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char *name,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char *value,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char ***_headers,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina size_t *_num_headers)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char **headers = *_headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina size_t num_headers = *_num_headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina num_headers++;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina headers = talloc_realloc(mem_ctx, headers, const char *,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina num_headers + 1);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (headers == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina headers[num_headers - 1] = talloc_asprintf(headers, "%s: %s", name, value);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (headers[num_headers - 1] == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina headers[num_headers] = NULL;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina *_headers = headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina *_num_headers = num_headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return EOK;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina}
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinastatic const char **
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinaproxy_http_create_headers(TALLOC_CTX *mem_ctx,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sec_req_ctx *secreq,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct proxy_cfg *pcfg)
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina{
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina TALLOC_CTX *tmp_ctx;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char **headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina size_t num_headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina errno_t ret;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina int i, j;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina tmp_ctx = talloc_new(NULL);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (tmp_ctx == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return NULL;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina headers = talloc_zero_array(tmp_ctx, const char *, 1);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (headers == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina num_headers = 0;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina for (i = 0; i < secreq->num_headers; i++) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina for (j = 0; pcfg->fwd_headers[j]; j++) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (strcasecmp(secreq->headers[i].name, pcfg->fwd_headers[j]) == 0) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_TRACE_LIBS, "Forwarding header %s: %s\n",
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina secreq->headers[i].name, secreq->headers[i].value);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = proxy_http_append_header(tmp_ctx, secreq->headers[i].name,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina secreq->headers[i].value,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina &headers, &num_headers);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (ret != EOK) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce break;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (pcfg->auth_type == PAT_HEADER) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_TRACE_LIBS, "Forwarding header %s\n",
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina pcfg->auth.header.name);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = proxy_http_append_header(tmp_ctx, pcfg->auth.header.name,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina pcfg->auth.header.value,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina &headers, &num_headers);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (ret != EOK) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina talloc_steal(mem_ctx, headers);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = EOK;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinadone:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina talloc_free(tmp_ctx);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (ret != EOK) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return NULL;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return headers;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březinastatic errno_t proxy_http_create_request(TALLOC_CTX *mem_ctx,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sec_req_ctx *secreq,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct proxy_cfg *pcfg,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char *url,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct tcurl_request **_tcurl_req)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina TALLOC_CTX *tmp_ctx;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct tcurl_request *tcurl_req;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina enum tcurl_http_method method;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sss_iobuf *body;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina const char **headers;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina errno_t ret;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina tmp_ctx = talloc_new(NULL);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (tmp_ctx == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina headers = proxy_http_create_headers(tmp_ctx, secreq, pcfg);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (headers == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to construct HTTP headers!\n");
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina body = sss_iobuf_init_readonly(tmp_ctx, (uint8_t *)secreq->body.data,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina secreq->body.length);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (body == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create HTTP body!\n");
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = ENOMEM;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina switch (secreq->method) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina case HTTP_GET:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina method = TCURL_HTTP_GET;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina break;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina case HTTP_PUT:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina method = TCURL_HTTP_PUT;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina break;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina case HTTP_POST:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina method = TCURL_HTTP_POST;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina break;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina case HTTP_DELETE:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina method = TCURL_HTTP_DELETE;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina break;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina default:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected HTTP method: %d\n",
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina secreq->method);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = EINVAL;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina tcurl_req = tcurl_http(tmp_ctx, method, NULL, url, headers, body);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (tcurl_req == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create TCURL request!\n");
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina /* TCURL will return response buffer also with headers. */
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = tcurl_req_enable_rawoutput(tcurl_req);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (ret != EOK) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina /* Set TLS settings to verify peer.
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina * This has no effect for HTTP protocol so we can set it anyway. */
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = tcurl_req_verify_peer(tcurl_req, pcfg->capath, pcfg->cacert,
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina pcfg->verify_peer, pcfg->verify_host);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret != EOK) {
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina }
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina /* Set client's certificate if required. */
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (pcfg->cert != NULL) {
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina ret = tcurl_req_set_client_cert(tcurl_req, pcfg->cert, pcfg->key);
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina if (ret != EOK) {
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina goto done;
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina }
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina }
720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417Pavel Březina
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina /* Set basic authentication if required. */
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina if (pcfg->auth_type == PAT_BASIC_AUTH) {
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina ret = tcurl_req_http_basic_auth(tcurl_req, pcfg->auth.basic.username,
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina pcfg->auth.basic.password);
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina if (ret != EOK) {
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina goto done;
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina }
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina }
af026ea6a6e812b7d6c5c889dda64ba7b7c433eePavel Březina
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina talloc_steal(tcurl_req, body);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina *_tcurl_req = talloc_steal(mem_ctx, tcurl_req);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcedone:
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina talloc_free(tmp_ctx);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct proxy_secret_state {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct tevent_context *ev;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_req_ctx *secreq;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_cfg *pcfg;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce};
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestatic void proxy_secret_req_done(struct tevent_req *subreq);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestruct tevent_req *proxy_secret_req(TALLOC_CTX *mem_ctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct tevent_context *ev,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce void *provider_ctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct sec_req_ctx *secreq)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct tevent_req *req, *subreq;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_secret_state *state;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct tcurl_request *tcurl_req;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_context *pctx;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce char *http_uri;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce req = tevent_req_create(mem_ctx, &state, struct proxy_secret_state);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!req) return NULL;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce state->ev = ev;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce state->secreq = secreq;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce pctx = talloc_get_type(provider_ctx, struct proxy_context);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!pctx) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = EIO;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_sec_get_cfg(pctx, state, state->secreq, &state->pcfg);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (ret) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "proxy_sec_get_cfg failed [%d]: %s\n", ret, sss_strerror(ret));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_sec_map_url(state, secreq, state->pcfg, &http_uri);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (ret) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "proxy_sec_map_url failed [%d]: %s\n", ret, sss_strerror(ret));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = proxy_http_create_request(state, state->secreq, state->pcfg,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina http_uri, &tcurl_req);
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek if (ret) {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek "proxy_http_create_request failed [%d]: %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek ret, sss_strerror(ret));
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek goto done;
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek }
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina subreq = tcurl_request_send(mem_ctx, ev, pctx->tcurl, tcurl_req,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina SEC_PROXY_TIMEOUT);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (subreq == NULL) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce ret = ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce goto done;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_set_callback(subreq, proxy_secret_req_done, req);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return req;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcedone:
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret != EOK) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_error(req, ret);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce /* shortcircuit the request here as all called functions are
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce * synchronous and final and no further subrequests have been
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce * made if we get here */
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_done(req);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return tevent_req_post(req, ev);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorcestatic void proxy_secret_req_done(struct tevent_req *subreq)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct tevent_req *req;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_secret_state *state;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina struct sss_iobuf *response;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina int http_code;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce int ret;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce req = tevent_req_callback_data(subreq, struct tevent_req);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce state = tevent_req_data(req, struct proxy_secret_state);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = tcurl_request_recv(state, subreq, &response, &http_code);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce talloc_zfree(subreq);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret != EOK) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina DEBUG(SSSDBG_OP_FAILURE, "proxy_http request failed [%d]: %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek ret, sss_strerror(ret));
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_error(req, ret);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina ret = sec_http_reply_iobuf(state->secreq, &state->secreq->reply,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina http_code, response);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (ret == EOK) {
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_done(req);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce } else {
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina "sec_http_reply_iobuf request failed [%d]: %s\n",
7128fadade544efcd86b113a5090b00d20993671Jakub Hrozek ret, sss_strerror(ret));
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce tevent_req_error(req, ret);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorceint proxy_secrets_provider_handle(struct sec_ctx *sctx,
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct provider_handle **out_handle)
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce{
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct provider_handle *handle;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce struct proxy_context *pctx;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce handle = talloc_zero(sctx, struct provider_handle);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!handle) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce handle->name = "PROXY";
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce handle->fn = proxy_secret_req;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce pctx = talloc(handle, struct proxy_context);
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce if (!pctx) return ENOMEM;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce pctx->cdb = sctx->rctx->cdb;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina pctx->tcurl = tcurl_init(pctx, sctx->rctx->ev);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina if (pctx->tcurl == NULL) {
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina talloc_free(pctx);
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina return ENOMEM;
df99d709c8cbef3c378c111944d83b7345e4c1eaPavel Březina }
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce handle->context = pctx;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce *out_handle = handle;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce return EOK;
8f2a34cc6964a1f80a1434e05315a7ae0bb5774eSimo Sorce}