ssl_client_cert_providers.c revision 299742
1/* 2 * ssl_client_cert_providers.c: providers for 3 * SVN_AUTH_CRED_SSL_CLIENT_CERT 4 * 5 * ==================================================================== 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 * ==================================================================== 23 */ 24 25/* ==================================================================== */ 26 27 28 29/*** Includes. ***/ 30 31#include <apr_pools.h> 32#include "svn_hash.h" 33#include "svn_auth.h" 34#include "svn_error.h" 35#include "svn_config.h" 36 37 38/*-----------------------------------------------------------------------*/ 39/* File provider */ 40/*-----------------------------------------------------------------------*/ 41 42/* retrieve and load the ssl client certificate file from servers 43 config */ 44static svn_error_t * 45ssl_client_cert_file_first_credentials(void **credentials_p, 46 void **iter_baton, 47 void *provider_baton, 48 apr_hash_t *parameters, 49 const char *realmstring, 50 apr_pool_t *pool) 51{ 52 svn_config_t *cfg = svn_hash_gets(parameters, 53 SVN_AUTH_PARAM_CONFIG_CATEGORY_SERVERS); 54 const char *server_group = svn_hash_gets(parameters, 55 SVN_AUTH_PARAM_SERVER_GROUP); 56 const char *cert_file; 57 58 cert_file = 59 svn_config_get_server_setting(cfg, server_group, 60 SVN_CONFIG_OPTION_SSL_CLIENT_CERT_FILE, 61 NULL); 62 63 if (cert_file != NULL) 64 { 65 svn_auth_cred_ssl_client_cert_t *cred = 66 apr_palloc(pool, sizeof(*cred)); 67 68 cred->cert_file = cert_file; 69 cred->may_save = FALSE; 70 *credentials_p = cred; 71 } 72 else 73 { 74 *credentials_p = NULL; 75 } 76 77 *iter_baton = NULL; 78 return SVN_NO_ERROR; 79} 80 81 82static const svn_auth_provider_t ssl_client_cert_file_provider = { 83 SVN_AUTH_CRED_SSL_CLIENT_CERT, 84 ssl_client_cert_file_first_credentials, 85 NULL, 86 NULL 87}; 88 89 90/*** Public API to SSL file providers. ***/ 91void svn_auth_get_ssl_client_cert_file_provider 92 (svn_auth_provider_object_t **provider, apr_pool_t *pool) 93{ 94 svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 95 po->vtable = &ssl_client_cert_file_provider; 96 *provider = po; 97} 98 99 100/*-----------------------------------------------------------------------*/ 101/* Prompt provider */ 102/*-----------------------------------------------------------------------*/ 103 104/* Baton type for prompting to send client ssl creds. 105 There is no iteration baton type. */ 106typedef struct ssl_client_cert_prompt_provider_baton_t 107{ 108 svn_auth_ssl_client_cert_prompt_func_t prompt_func; 109 void *prompt_baton; 110 111 /* how many times to re-prompt after the first one fails */ 112 int retry_limit; 113} ssl_client_cert_prompt_provider_baton_t; 114 115/* Iteration baton. */ 116typedef struct ssl_client_cert_prompt_iter_baton_t 117{ 118 /* The original provider baton */ 119 ssl_client_cert_prompt_provider_baton_t *pb; 120 121 /* The original realmstring */ 122 const char *realmstring; 123 124 /* how many times we've reprompted */ 125 int retries; 126} ssl_client_cert_prompt_iter_baton_t; 127 128 129static svn_error_t * 130ssl_client_cert_prompt_first_cred(void **credentials_p, 131 void **iter_baton, 132 void *provider_baton, 133 apr_hash_t *parameters, 134 const char *realmstring, 135 apr_pool_t *pool) 136{ 137 ssl_client_cert_prompt_provider_baton_t *pb = provider_baton; 138 ssl_client_cert_prompt_iter_baton_t *ib = 139 apr_pcalloc(pool, sizeof(*ib)); 140 const char *no_auth_cache = svn_hash_gets(parameters, 141 SVN_AUTH_PARAM_NO_AUTH_CACHE); 142 143 SVN_ERR(pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) credentials_p, 144 pb->prompt_baton, realmstring, ! no_auth_cache, 145 pool)); 146 147 ib->pb = pb; 148 ib->realmstring = apr_pstrdup(pool, realmstring); 149 ib->retries = 0; 150 *iter_baton = ib; 151 152 return SVN_NO_ERROR; 153} 154 155 156static svn_error_t * 157ssl_client_cert_prompt_next_cred(void **credentials_p, 158 void *iter_baton, 159 void *provider_baton, 160 apr_hash_t *parameters, 161 const char *realmstring, 162 apr_pool_t *pool) 163{ 164 ssl_client_cert_prompt_iter_baton_t *ib = iter_baton; 165 const char *no_auth_cache = svn_hash_gets(parameters, 166 SVN_AUTH_PARAM_NO_AUTH_CACHE); 167 168 if ((ib->pb->retry_limit >= 0) && (ib->retries >= ib->pb->retry_limit)) 169 { 170 /* give up, go on to next provider. */ 171 *credentials_p = NULL; 172 return SVN_NO_ERROR; 173 } 174 ib->retries++; 175 176 return ib->pb->prompt_func((svn_auth_cred_ssl_client_cert_t **) 177 credentials_p, ib->pb->prompt_baton, 178 ib->realmstring, ! no_auth_cache, pool); 179} 180 181 182static const svn_auth_provider_t ssl_client_cert_prompt_provider = { 183 SVN_AUTH_CRED_SSL_CLIENT_CERT, 184 ssl_client_cert_prompt_first_cred, 185 ssl_client_cert_prompt_next_cred, 186 NULL 187}; 188 189 190/*** Public API to SSL prompting providers. ***/ 191void svn_auth_get_ssl_client_cert_prompt_provider 192 (svn_auth_provider_object_t **provider, 193 svn_auth_ssl_client_cert_prompt_func_t prompt_func, 194 void *prompt_baton, 195 int retry_limit, 196 apr_pool_t *pool) 197{ 198 svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po)); 199 ssl_client_cert_prompt_provider_baton_t *pb = apr_palloc(pool, sizeof(*pb)); 200 201 pb->prompt_func = prompt_func; 202 pb->prompt_baton = prompt_baton; 203 pb->retry_limit = retry_limit; 204 205 po->vtable = &ssl_client_cert_prompt_provider; 206 po->provider_baton = pb; 207 *provider = po; 208} 209