1178825Sdfr/*
2233294Sstas * Copyright (c) 1997-2007 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7178825Sdfr *
8233294Sstas * Redistribution and use in source and binary forms, with or without
9233294Sstas * modification, are permitted provided that the following conditions
10233294Sstas * are met:
11178825Sdfr *
12233294Sstas * 1. Redistributions of source code must retain the above copyright
13233294Sstas *    notice, this list of conditions and the following disclaimer.
14178825Sdfr *
15233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
16233294Sstas *    notice, this list of conditions and the following disclaimer in the
17233294Sstas *    documentation and/or other materials provided with the distribution.
18178825Sdfr *
19233294Sstas * 3. Neither the name of the Institute nor the names of its contributors
20233294Sstas *    may be used to endorse or promote products derived from this software
21233294Sstas *    without specific prior written permission.
22178825Sdfr *
23233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33233294Sstas * SUCH DAMAGE.
34178825Sdfr */
35178825Sdfr
36178825Sdfr#include "kdc_locl.h"
37178825Sdfr#include <getarg.h>
38178825Sdfr#include <parse_bytes.h>
39178825Sdfr
40178825Sdfrkrb5_error_code
41178825Sdfrkrb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
42178825Sdfr{
43178825Sdfr    krb5_kdc_configuration *c;
44178825Sdfr
45178825Sdfr    c = calloc(1, sizeof(*c));
46178825Sdfr    if (c == NULL) {
47233294Sstas	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
48178825Sdfr	return ENOMEM;
49178825Sdfr    }
50178825Sdfr
51178825Sdfr    c->require_preauth = TRUE;
52178825Sdfr    c->kdc_warn_pwexpire = 0;
53178825Sdfr    c->encode_as_rep_as_tgs_rep = FALSE;
54234027Sstas    c->tgt_use_strongest_session_key = FALSE;
55233294Sstas    c->preauth_use_strongest_session_key = FALSE;
56234027Sstas    c->svc_use_strongest_session_key = FALSE;
57233294Sstas    c->use_strongest_server_key = TRUE;
58178825Sdfr    c->check_ticket_addresses = TRUE;
59178825Sdfr    c->allow_null_ticket_addresses = TRUE;
60178825Sdfr    c->allow_anonymous = FALSE;
61178825Sdfr    c->trpolicy = TRPOLICY_ALWAYS_CHECK;
62178825Sdfr    c->enable_pkinit = FALSE;
63178825Sdfr    c->pkinit_princ_in_cert = TRUE;
64178825Sdfr    c->pkinit_require_binding = TRUE;
65178825Sdfr    c->db = NULL;
66178825Sdfr    c->num_db = 0;
67178825Sdfr    c->logf = NULL;
68178825Sdfr
69178825Sdfr    c->require_preauth =
70233294Sstas	krb5_config_get_bool_default(context, NULL,
71178825Sdfr				     c->require_preauth,
72178825Sdfr				     "kdc", "require-preauth", NULL);
73233294Sstas#ifdef DIGEST
74233294Sstas    c->enable_digest =
75178825Sdfr	krb5_config_get_bool_default(context, NULL,
76178825Sdfr				     FALSE,
77178825Sdfr				     "kdc", "enable-digest", NULL);
78178825Sdfr
79178825Sdfr    {
80178825Sdfr	const char *digests;
81178825Sdfr
82233294Sstas	digests = krb5_config_get_string(context, NULL,
83233294Sstas					 "kdc",
84178825Sdfr					 "digests_allowed", NULL);
85178825Sdfr	if (digests == NULL)
86178825Sdfr	    digests = "ntlm-v2";
87178825Sdfr	c->digests_allowed = parse_flags(digests,_kdc_digestunits, 0);
88178825Sdfr	if (c->digests_allowed == -1) {
89178825Sdfr	    kdc_log(context, c, 0,
90178825Sdfr		    "unparsable digest units (%s), turning off digest",
91178825Sdfr		    digests);
92178825Sdfr	    c->enable_digest = 0;
93178825Sdfr	} else if (c->digests_allowed == 0) {
94178825Sdfr	    kdc_log(context, c, 0,
95178825Sdfr		    "no digest enable, turning digest off",
96178825Sdfr		    digests);
97178825Sdfr	    c->enable_digest = 0;
98178825Sdfr	}
99178825Sdfr    }
100233294Sstas#endif
101178825Sdfr
102233294Sstas#ifdef KX509
103233294Sstas    c->enable_kx509 =
104233294Sstas	krb5_config_get_bool_default(context, NULL,
105233294Sstas				     FALSE,
106178825Sdfr				     "kdc", "enable-kx509", NULL);
107178825Sdfr
108178825Sdfr    if (c->enable_kx509) {
109178825Sdfr	c->kx509_template =
110233294Sstas	    krb5_config_get_string(context, NULL,
111178825Sdfr				   "kdc", "kx509_template", NULL);
112178825Sdfr	c->kx509_ca =
113233294Sstas	    krb5_config_get_string(context, NULL,
114178825Sdfr				   "kdc", "kx509_ca", NULL);
115178825Sdfr	if (c->kx509_ca == NULL || c->kx509_template == NULL) {
116178825Sdfr	    kdc_log(context, c, 0,
117178825Sdfr		    "missing kx509 configuration, turning off");
118178825Sdfr	    c->enable_kx509 = FALSE;
119178825Sdfr	}
120178825Sdfr    }
121233294Sstas#endif
122178825Sdfr
123234027Sstas    c->tgt_use_strongest_session_key =
124233294Sstas	krb5_config_get_bool_default(context, NULL,
125234027Sstas				     c->tgt_use_strongest_session_key,
126233294Sstas				     "kdc",
127234027Sstas				     "tgt-use-strongest-session-key", NULL);
128233294Sstas    c->preauth_use_strongest_session_key =
129233294Sstas	krb5_config_get_bool_default(context, NULL,
130233294Sstas				     c->preauth_use_strongest_session_key,
131233294Sstas				     "kdc",
132233294Sstas				     "preauth-use-strongest-session-key", NULL);
133234027Sstas    c->svc_use_strongest_session_key =
134233294Sstas	krb5_config_get_bool_default(context, NULL,
135234027Sstas				     c->svc_use_strongest_session_key,
136233294Sstas				     "kdc",
137234027Sstas				     "svc-use-strongest-session-key", NULL);
138233294Sstas    c->use_strongest_server_key =
139233294Sstas	krb5_config_get_bool_default(context, NULL,
140233294Sstas				     c->use_strongest_server_key,
141233294Sstas				     "kdc",
142233294Sstas				     "use-strongest-server-key", NULL);
143233294Sstas
144233294Sstas    c->check_ticket_addresses =
145233294Sstas	krb5_config_get_bool_default(context, NULL,
146233294Sstas				     c->check_ticket_addresses,
147233294Sstas				     "kdc",
148178825Sdfr				     "check-ticket-addresses", NULL);
149233294Sstas    c->allow_null_ticket_addresses =
150233294Sstas	krb5_config_get_bool_default(context, NULL,
151233294Sstas				     c->allow_null_ticket_addresses,
152233294Sstas				     "kdc",
153178825Sdfr				     "allow-null-ticket-addresses", NULL);
154178825Sdfr
155233294Sstas    c->allow_anonymous =
156233294Sstas	krb5_config_get_bool_default(context, NULL,
157178825Sdfr				     c->allow_anonymous,
158233294Sstas				     "kdc",
159178825Sdfr				     "allow-anonymous", NULL);
160178825Sdfr
161178825Sdfr    c->max_datagram_reply_length =
162233294Sstas	krb5_config_get_int_default(context,
163233294Sstas				    NULL,
164178825Sdfr				    1400,
165178825Sdfr				    "kdc",
166178825Sdfr				    "max-kdc-datagram-reply-length",
167178825Sdfr				    NULL);
168178825Sdfr
169178825Sdfr    {
170178825Sdfr	const char *trpolicy_str;
171178825Sdfr
172233294Sstas	trpolicy_str =
173233294Sstas	    krb5_config_get_string_default(context, NULL, "DEFAULT", "kdc",
174178825Sdfr					   "transited-policy", NULL);
175178825Sdfr	if(strcasecmp(trpolicy_str, "always-check") == 0) {
176178825Sdfr	    c->trpolicy = TRPOLICY_ALWAYS_CHECK;
177178825Sdfr	} else if(strcasecmp(trpolicy_str, "allow-per-principal") == 0) {
178178825Sdfr	    c->trpolicy = TRPOLICY_ALLOW_PER_PRINCIPAL;
179178825Sdfr	} else if(strcasecmp(trpolicy_str, "always-honour-request") == 0) {
180178825Sdfr	    c->trpolicy = TRPOLICY_ALWAYS_HONOUR_REQUEST;
181233294Sstas	} else if(strcasecmp(trpolicy_str, "DEFAULT") == 0) {
182178825Sdfr	    /* default */
183178825Sdfr	} else {
184178825Sdfr	    kdc_log(context, c, 0,
185178825Sdfr		    "unknown transited-policy: %s, "
186233294Sstas		    "reverting to default (always-check)",
187178825Sdfr		    trpolicy_str);
188178825Sdfr	}
189178825Sdfr    }
190178825Sdfr
191178825Sdfr    c->encode_as_rep_as_tgs_rep =
192233294Sstas	krb5_config_get_bool_default(context, NULL,
193233294Sstas				     c->encode_as_rep_as_tgs_rep,
194233294Sstas				     "kdc",
195178825Sdfr				     "encode_as_rep_as_tgs_rep", NULL);
196233294Sstas
197178825Sdfr    c->kdc_warn_pwexpire =
198178825Sdfr	krb5_config_get_time_default (context, NULL,
199178825Sdfr				      c->kdc_warn_pwexpire,
200178825Sdfr				      "kdc", "kdc_warn_pwexpire", NULL);
201178825Sdfr
202178825Sdfr
203233294Sstas    c->enable_pkinit =
204233294Sstas	krb5_config_get_bool_default(context,
205233294Sstas				     NULL,
206178825Sdfr				     c->enable_pkinit,
207178825Sdfr				     "kdc",
208178825Sdfr				     "enable-pkinit",
209178825Sdfr				     NULL);
210178825Sdfr
211178825Sdfr
212233294Sstas    c->pkinit_kdc_identity =
213233294Sstas	krb5_config_get_string(context, NULL,
214233294Sstas			       "kdc", "pkinit_identity", NULL);
215233294Sstas    c->pkinit_kdc_anchors =
216233294Sstas	krb5_config_get_string(context, NULL,
217233294Sstas			       "kdc", "pkinit_anchors", NULL);
218233294Sstas    c->pkinit_kdc_cert_pool =
219233294Sstas	krb5_config_get_strings(context, NULL,
220233294Sstas				"kdc", "pkinit_pool", NULL);
221233294Sstas    c->pkinit_kdc_revoke =
222233294Sstas	krb5_config_get_strings(context, NULL,
223233294Sstas				"kdc", "pkinit_revoke", NULL);
224233294Sstas    c->pkinit_kdc_ocsp_file =
225233294Sstas	krb5_config_get_string(context, NULL,
226233294Sstas			       "kdc", "pkinit_kdc_ocsp", NULL);
227233294Sstas    c->pkinit_kdc_friendly_name =
228233294Sstas	krb5_config_get_string(context, NULL,
229233294Sstas			       "kdc", "pkinit_kdc_friendly_name", NULL);
230233294Sstas    c->pkinit_princ_in_cert =
231233294Sstas	krb5_config_get_bool_default(context, NULL,
232233294Sstas				     c->pkinit_princ_in_cert,
233233294Sstas				     "kdc",
234233294Sstas				     "pkinit_principal_in_certificate",
235233294Sstas				     NULL);
236233294Sstas    c->pkinit_require_binding =
237233294Sstas	krb5_config_get_bool_default(context, NULL,
238233294Sstas				     c->pkinit_require_binding,
239233294Sstas				     "kdc",
240233294Sstas				     "pkinit_win2k_require_binding",
241233294Sstas				     NULL);
242233294Sstas    c->pkinit_dh_min_bits =
243233294Sstas	krb5_config_get_int_default(context, NULL,
244233294Sstas				    0,
245233294Sstas				    "kdc", "pkinit_dh_min_bits", NULL);
246178825Sdfr
247233294Sstas    *config = c;
248178825Sdfr
249233294Sstas    return 0;
250233294Sstas}
251178825Sdfr
252233294Sstaskrb5_error_code
253233294Sstaskrb5_kdc_pkinit_config(krb5_context context, krb5_kdc_configuration *config)
254233294Sstas{
255233294Sstas#ifdef PKINIT
256233294Sstas#ifdef __APPLE__
257233294Sstas    config->enable_pkinit = 1;
258178825Sdfr
259233294Sstas    if (config->pkinit_kdc_identity == NULL) {
260233294Sstas	if (config->pkinit_kdc_friendly_name == NULL)
261233294Sstas	    config->pkinit_kdc_friendly_name =
262233294Sstas		strdup("O=System Identity,CN=com.apple.kerberos.kdc");
263233294Sstas	config->pkinit_kdc_identity = strdup("KEYCHAIN:");
264233294Sstas    }
265233294Sstas    if (config->pkinit_kdc_anchors == NULL)
266233294Sstas	config->pkinit_kdc_anchors = strdup("KEYCHAIN:");
267178825Sdfr
268233294Sstas#endif /* __APPLE__ */
269178825Sdfr
270233294Sstas    if (config->enable_pkinit) {
271233294Sstas	if (config->pkinit_kdc_identity == NULL)
272233294Sstas	    krb5_errx(context, 1, "pkinit enabled but no identity");
273178825Sdfr
274233294Sstas	if (config->pkinit_kdc_anchors == NULL)
275233294Sstas	    krb5_errx(context, 1, "pkinit enabled but no X509 anchors");
276178825Sdfr
277233294Sstas	krb5_kdc_pk_initialize(context, config,
278233294Sstas			       config->pkinit_kdc_identity,
279233294Sstas			       config->pkinit_kdc_anchors,
280233294Sstas			       config->pkinit_kdc_cert_pool,
281233294Sstas			       config->pkinit_kdc_revoke);
282178825Sdfr
283233294Sstas    }
284178825Sdfr
285178825Sdfr    return 0;
286233294Sstas#endif /* PKINIT */
287178825Sdfr}
288