1251881Speter/* 2251881Speter * ssl_client_cert_providers.c: providers for 3251881Speter * SVN_AUTH_CRED_SSL_CLIENT_CERT 4251881Speter * 5251881Speter * ==================================================================== 6251881Speter * Licensed to the Apache Software Foundation (ASF) under one 7251881Speter * or more contributor license agreements. See the NOTICE file 8251881Speter * distributed with this work for additional information 9251881Speter * regarding copyright ownership. The ASF licenses this file 10251881Speter * to you under the Apache License, Version 2.0 (the 11251881Speter * "License"); you may not use this file except in compliance 12251881Speter * with the License. You may obtain a copy of the License at 13251881Speter * 14251881Speter * http://www.apache.org/licenses/LICENSE-2.0 15251881Speter * 16251881Speter * Unless required by applicable law or agreed to in writing, 17251881Speter * software distributed under the License is distributed on an 18251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19251881Speter * KIND, either express or implied. See the License for the 20251881Speter * specific language governing permissions and limitations 21251881Speter * under the License. 22251881Speter * ==================================================================== 23251881Speter */ 24251881Speter 25251881Speter/* ==================================================================== */ 26251881Speter 27251881Speter 28251881Speter 29251881Speter/*** Includes. ***/ 30251881Speter 31251881Speter#include <apr_pools.h> 32251881Speter#include "svn_hash.h" 33251881Speter#include "svn_auth.h" 34251881Speter#include "svn_error.h" 35251881Speter#include "svn_config.h" 36251881Speter 37251881Speter 38251881Speter/*-----------------------------------------------------------------------*/ 39251881Speter/* File provider */ 40251881Speter/*-----------------------------------------------------------------------*/ 41251881Speter 42251881Speter/* retrieve and load the ssl client certificate file from servers 43251881Speter config */ 44251881Speterstatic svn_error_t * 45251881Speterssl_client_cert_file_first_credentials(void **credentials_p, 46251881Speter void **iter_baton, 47251881Speter void *provider_baton, 48251881Speter apr_hash_t *parameters, 49251881Speter const char *realmstring, 50251881Speter apr_pool_t *pool) 51251881Speter{ 52251881Speter svn_config_t *cfg = svn_hash_gets(parameters, 53251881Speter SVN_AUTH_PARAM_CONFIG_CATEGORY_SERVERS); 54251881Speter const char *server_group = svn_hash_gets(parameters, 55251881Speter SVN_AUTH_PARAM_SERVER_GROUP); 56251881Speter const char *cert_file; 57251881Speter 58251881Speter cert_file = 59251881Speter svn_config_get_server_setting(cfg, server_group, 60251881Speter SVN_CONFIG_OPTION_SSL_CLIENT_CERT_FILE, 61251881Speter NULL); 62251881Speter 63251881Speter if (cert_file != NULL) 64251881Speter { 65251881Speter svn_auth_cred_ssl_client_cert_t *cred = 66251881Speter apr_palloc(pool, sizeof(*cred)); 67251881Speter 68251881Speter cred->cert_file = cert_file; 69251881Speter cred->may_save = FALSE; 70251881Speter *credentials_p = cred; 71251881Speter } 72251881Speter else 73251881Speter { 74251881Speter *credentials_p = NULL; 75251881Speter } 76251881Speter 77251881Speter *iter_baton = NULL; 78251881Speter return SVN_NO_ERROR; 79251881Speter} 80251881Speter 81251881Speter 82289180Speterstatic const svn_auth_provider_t ssl_client_cert_file_provider = { 83289180Speter SVN_AUTH_CRED_SSL_CLIENT_CERT, 84289180Speter ssl_client_cert_file_first_credentials, 85289180Speter NULL, 86289180Speter NULL 87289180Speter}; 88251881Speter 89251881Speter 90251881Speter/*** Public API to SSL file providers. ***/ 91251881Spetervoid svn_auth_get_ssl_client_cert_file_provider 92251881Speter (svn_auth_provider_object_t **provider, apr_pool_t *pool) 93251881Speter{ 94251881Speter svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 95251881Speter po->vtable = &ssl_client_cert_file_provider; 96251881Speter *provider = po; 97251881Speter} 98251881Speter 99251881Speter 100251881Speter/*-----------------------------------------------------------------------*/ 101251881Speter/* Prompt provider */ 102251881Speter/*-----------------------------------------------------------------------*/ 103251881Speter 104251881Speter/* Baton type for prompting to send client ssl creds. 105251881Speter There is no iteration baton type. */ 106251881Spetertypedef struct ssl_client_cert_prompt_provider_baton_t 107251881Speter{ 108251881Speter svn_auth_ssl_client_cert_prompt_func_t prompt_func; 109251881Speter void *prompt_baton; 110251881Speter 111251881Speter /* how many times to re-prompt after the first one fails */ 112251881Speter int retry_limit; 113251881Speter} ssl_client_cert_prompt_provider_baton_t; 114251881Speter 115251881Speter/* Iteration baton. */ 116251881Spetertypedef struct ssl_client_cert_prompt_iter_baton_t 117251881Speter{ 118251881Speter /* The original provider baton */ 119251881Speter ssl_client_cert_prompt_provider_baton_t *pb; 120251881Speter 121251881Speter /* The original realmstring */ 122251881Speter const char *realmstring; 123251881Speter 124251881Speter /* how many times we've reprompted */ 125251881Speter int retries; 126251881Speter} ssl_client_cert_prompt_iter_baton_t; 127251881Speter 128251881Speter 129251881Speterstatic svn_error_t * 130251881Speterssl_client_cert_prompt_first_cred(void **credentials_p, 131251881Speter void **iter_baton, 132251881Speter void *provider_baton, 133251881Speter apr_hash_t *parameters, 134251881Speter const char *realmstring, 135251881Speter apr_pool_t *pool) 136251881Speter{ 137251881Speter ssl_client_cert_prompt_provider_baton_t *pb = provider_baton; 138251881Speter ssl_client_cert_prompt_iter_baton_t *ib = 139251881Speter apr_pcalloc(pool, sizeof(*ib)); 140251881Speter const char *no_auth_cache = svn_hash_gets(parameters, 141251881Speter SVN_AUTH_PARAM_NO_AUTH_CACHE); 142251881Speter 143251881Speter SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) credentials_p, 144251881Speter pb->prompt_baton, realmstring, ! no_auth_cache, 145251881Speter pool)); 146251881Speter 147251881Speter ib->pb = pb; 148251881Speter ib->realmstring = apr_pstrdup(pool, realmstring); 149251881Speter ib->retries = 0; 150251881Speter *iter_baton = ib; 151251881Speter 152251881Speter return SVN_NO_ERROR; 153251881Speter} 154251881Speter 155251881Speter 156251881Speterstatic svn_error_t * 157251881Speterssl_client_cert_prompt_next_cred(void **credentials_p, 158251881Speter void *iter_baton, 159251881Speter void *provider_baton, 160251881Speter apr_hash_t *parameters, 161251881Speter const char *realmstring, 162251881Speter apr_pool_t *pool) 163251881Speter{ 164251881Speter ssl_client_cert_prompt_iter_baton_t *ib = iter_baton; 165251881Speter const char *no_auth_cache = svn_hash_gets(parameters, 166251881Speter SVN_AUTH_PARAM_NO_AUTH_CACHE); 167251881Speter 168251881Speter if ((ib->pb->retry_limit >= 0) && (ib->retries >= ib->pb->retry_limit)) 169251881Speter { 170251881Speter /* give up, go on to next provider. */ 171251881Speter *credentials_p = NULL; 172251881Speter return SVN_NO_ERROR; 173251881Speter } 174251881Speter ib->retries++; 175251881Speter 176251881Speter return ib->pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) 177251881Speter credentials_p, ib->pb->prompt_baton, 178251881Speter ib->realmstring, ! no_auth_cache, pool); 179251881Speter} 180251881Speter 181251881Speter 182251881Speterstatic const svn_auth_provider_t ssl_client_cert_prompt_provider = { 183251881Speter SVN_AUTH_CRED_SSL_CLIENT_CERT, 184251881Speter ssl_client_cert_prompt_first_cred, 185251881Speter ssl_client_cert_prompt_next_cred, 186251881Speter NULL 187251881Speter}; 188251881Speter 189251881Speter 190251881Speter/*** Public API to SSL prompting providers. ***/ 191251881Spetervoid svn_auth_get_ssl_client_cert_prompt_provider 192251881Speter (svn_auth_provider_object_t **provider, 193251881Speter svn_auth_ssl_client_cert_prompt_func_t prompt_func, 194251881Speter void *prompt_baton, 195251881Speter int retry_limit, 196251881Speter apr_pool_t *pool) 197251881Speter{ 198251881Speter svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 199251881Speter ssl_client_cert_prompt_provider_baton_t *pb = apr_palloc(pool, sizeof(*pb)); 200251881Speter 201251881Speter pb->prompt_func = prompt_func; 202251881Speter pb->prompt_baton = prompt_baton; 203251881Speter pb->retry_limit = retry_limit; 204251881Speter 205251881Speter po->vtable = &ssl_client_cert_prompt_provider; 206251881Speter po->provider_baton = pb; 207251881Speter *provider = po; 208251881Speter} 209