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 82251881Speterstatic const svn_auth_provider_t ssl_client_cert_file_provider = 83251881Speter { 84251881Speter SVN_AUTH_CRED_SSL_CLIENT_CERT, 85251881Speter ssl_client_cert_file_first_credentials, 86251881Speter NULL, 87251881Speter NULL 88251881Speter }; 89251881Speter 90251881Speter 91251881Speter/*** Public API to SSL file providers. ***/ 92251881Spetervoid svn_auth_get_ssl_client_cert_file_provider 93251881Speter (svn_auth_provider_object_t **provider, apr_pool_t *pool) 94251881Speter{ 95251881Speter svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 96251881Speter po->vtable = &ssl_client_cert_file_provider; 97251881Speter *provider = po; 98251881Speter} 99251881Speter 100251881Speter 101251881Speter/*-----------------------------------------------------------------------*/ 102251881Speter/* Prompt provider */ 103251881Speter/*-----------------------------------------------------------------------*/ 104251881Speter 105251881Speter/* Baton type for prompting to send client ssl creds. 106251881Speter There is no iteration baton type. */ 107251881Spetertypedef struct ssl_client_cert_prompt_provider_baton_t 108251881Speter{ 109251881Speter svn_auth_ssl_client_cert_prompt_func_t prompt_func; 110251881Speter void *prompt_baton; 111251881Speter 112251881Speter /* how many times to re-prompt after the first one fails */ 113251881Speter int retry_limit; 114251881Speter} ssl_client_cert_prompt_provider_baton_t; 115251881Speter 116251881Speter/* Iteration baton. */ 117251881Spetertypedef struct ssl_client_cert_prompt_iter_baton_t 118251881Speter{ 119251881Speter /* The original provider baton */ 120251881Speter ssl_client_cert_prompt_provider_baton_t *pb; 121251881Speter 122251881Speter /* The original realmstring */ 123251881Speter const char *realmstring; 124251881Speter 125251881Speter /* how many times we've reprompted */ 126251881Speter int retries; 127251881Speter} ssl_client_cert_prompt_iter_baton_t; 128251881Speter 129251881Speter 130251881Speterstatic svn_error_t * 131251881Speterssl_client_cert_prompt_first_cred(void **credentials_p, 132251881Speter void **iter_baton, 133251881Speter void *provider_baton, 134251881Speter apr_hash_t *parameters, 135251881Speter const char *realmstring, 136251881Speter apr_pool_t *pool) 137251881Speter{ 138251881Speter ssl_client_cert_prompt_provider_baton_t *pb = provider_baton; 139251881Speter ssl_client_cert_prompt_iter_baton_t *ib = 140251881Speter apr_pcalloc(pool, sizeof(*ib)); 141251881Speter const char *no_auth_cache = svn_hash_gets(parameters, 142251881Speter SVN_AUTH_PARAM_NO_AUTH_CACHE); 143251881Speter 144251881Speter SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) credentials_p, 145251881Speter pb->prompt_baton, realmstring, ! no_auth_cache, 146251881Speter pool)); 147251881Speter 148251881Speter ib->pb = pb; 149251881Speter ib->realmstring = apr_pstrdup(pool, realmstring); 150251881Speter ib->retries = 0; 151251881Speter *iter_baton = ib; 152251881Speter 153251881Speter return SVN_NO_ERROR; 154251881Speter} 155251881Speter 156251881Speter 157251881Speterstatic svn_error_t * 158251881Speterssl_client_cert_prompt_next_cred(void **credentials_p, 159251881Speter void *iter_baton, 160251881Speter void *provider_baton, 161251881Speter apr_hash_t *parameters, 162251881Speter const char *realmstring, 163251881Speter apr_pool_t *pool) 164251881Speter{ 165251881Speter ssl_client_cert_prompt_iter_baton_t *ib = iter_baton; 166251881Speter const char *no_auth_cache = svn_hash_gets(parameters, 167251881Speter SVN_AUTH_PARAM_NO_AUTH_CACHE); 168251881Speter 169251881Speter if ((ib->pb->retry_limit >= 0) && (ib->retries >= ib->pb->retry_limit)) 170251881Speter { 171251881Speter /* give up, go on to next provider. */ 172251881Speter *credentials_p = NULL; 173251881Speter return SVN_NO_ERROR; 174251881Speter } 175251881Speter ib->retries++; 176251881Speter 177251881Speter return ib->pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) 178251881Speter credentials_p, ib->pb->prompt_baton, 179251881Speter ib->realmstring, ! no_auth_cache, pool); 180251881Speter} 181251881Speter 182251881Speter 183251881Speterstatic const svn_auth_provider_t ssl_client_cert_prompt_provider = { 184251881Speter SVN_AUTH_CRED_SSL_CLIENT_CERT, 185251881Speter ssl_client_cert_prompt_first_cred, 186251881Speter ssl_client_cert_prompt_next_cred, 187251881Speter NULL 188251881Speter}; 189251881Speter 190251881Speter 191251881Speter/*** Public API to SSL prompting providers. ***/ 192251881Spetervoid svn_auth_get_ssl_client_cert_prompt_provider 193251881Speter (svn_auth_provider_object_t **provider, 194251881Speter svn_auth_ssl_client_cert_prompt_func_t prompt_func, 195251881Speter void *prompt_baton, 196251881Speter int retry_limit, 197251881Speter apr_pool_t *pool) 198251881Speter{ 199251881Speter svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 200251881Speter ssl_client_cert_prompt_provider_baton_t *pb = apr_palloc(pool, sizeof(*pb)); 201251881Speter 202251881Speter pb->prompt_func = prompt_func; 203251881Speter pb->prompt_baton = prompt_baton; 204251881Speter pb->retry_limit = retry_limit; 205251881Speter 206251881Speter po->vtable = &ssl_client_cert_prompt_provider; 207251881Speter po->provider_baton = pb; 208251881Speter *provider = po; 209251881Speter} 210