Annotation of src/usr.bin/ssh/auth-krb5.c, Revision 1.8.2.1
1.1 dugsong 1: /*
2: * Kerberos v5 authentication and ticket-passing routines.
1.8 markus 3: *
1.1 dugsong 4: * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
5: */
1.7 stevesk 6: /*
7: * Copyright (c) 2002 Daniel Kouril. All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
1.1 dugsong 29:
30: #include "includes.h"
1.8.2.1 ! miod 31: RCSID("$OpenBSD: auth-krb5.c,v 1.9 2002/09/09 06:48:06 itojun Exp $");
1.6 stevesk 32:
1.1 dugsong 33: #include "ssh.h"
34: #include "ssh1.h"
35: #include "packet.h"
36: #include "xmalloc.h"
37: #include "log.h"
38: #include "servconf.h"
39: #include "uidswap.h"
40: #include "auth.h"
41:
42: #ifdef KRB5
43: #include <krb5.h>
44:
45: extern ServerOptions options;
46:
47: static int
48: krb5_init(void *context)
49: {
50: Authctxt *authctxt = (Authctxt *)context;
51: krb5_error_code problem;
52: static int cleanup_registered = 0;
1.3 deraadt 53:
1.1 dugsong 54: if (authctxt->krb5_ctx == NULL) {
55: problem = krb5_init_context(&authctxt->krb5_ctx);
56: if (problem)
57: return (problem);
58: krb5_init_ets(authctxt->krb5_ctx);
59: }
60: if (!cleanup_registered) {
61: fatal_add_cleanup(krb5_cleanup_proc, authctxt);
62: cleanup_registered = 1;
63: }
64: return (0);
65: }
66:
67: /*
68: * Try krb5 authentication. server_user is passed for logging purposes
69: * only, in auth is received ticket, in client is returned principal
70: * from the ticket
71: */
1.3 deraadt 72: int
1.8.2.1 ! miod 73: auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
1.1 dugsong 74: {
75: krb5_error_code problem;
76: krb5_principal server;
77: krb5_ticket *ticket;
1.2 dugsong 78: int fd, ret;
79:
80: ret = 0;
1.1 dugsong 81: server = NULL;
82: ticket = NULL;
1.8.2.1 ! miod 83: reply->length = 0;
1.3 deraadt 84:
1.1 dugsong 85: problem = krb5_init(authctxt);
1.3 deraadt 86: if (problem)
1.1 dugsong 87: goto err;
1.3 deraadt 88:
1.1 dugsong 89: problem = krb5_auth_con_init(authctxt->krb5_ctx,
90: &authctxt->krb5_auth_ctx);
91: if (problem)
92: goto err;
1.3 deraadt 93:
1.1 dugsong 94: fd = packet_get_connection_in();
95: problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
96: authctxt->krb5_auth_ctx, &fd);
97: if (problem)
98: goto err;
1.3 deraadt 99:
1.1 dugsong 100: problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
101: KRB5_NT_SRV_HST, &server);
102: if (problem)
103: goto err;
1.3 deraadt 104:
1.1 dugsong 105: problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
106: auth, server, NULL, NULL, &ticket);
107: if (problem)
108: goto err;
1.3 deraadt 109:
1.1 dugsong 110: problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
111: &authctxt->krb5_user);
112: if (problem)
113: goto err;
1.3 deraadt 114:
1.1 dugsong 115: /* if client wants mutual auth */
116: problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
1.8.2.1 ! miod 117: reply);
1.1 dugsong 118: if (problem)
119: goto err;
1.3 deraadt 120:
1.1 dugsong 121: /* Check .k5login authorization now. */
122: if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
123: authctxt->pw->pw_name))
124: goto err;
1.3 deraadt 125:
1.1 dugsong 126: if (client)
127: krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
128: client);
1.3 deraadt 129:
1.2 dugsong 130: ret = 1;
1.1 dugsong 131: err:
132: if (server)
133: krb5_free_principal(authctxt->krb5_ctx, server);
134: if (ticket)
135: krb5_free_ticket(authctxt->krb5_ctx, ticket);
1.8.2.1 ! miod 136: if (!ret && reply->length) {
! 137: xfree(reply->data);
! 138: memset(reply, 0, sizeof(*reply));
! 139: }
1.3 deraadt 140:
1.5 markus 141: if (problem) {
142: if (authctxt->krb5_ctx != NULL)
143: debug("Kerberos v5 authentication failed: %s",
144: krb5_get_err_text(authctxt->krb5_ctx, problem));
145: else
146: debug("Kerberos v5 authentication failed: %d",
147: problem);
148: }
1.2 dugsong 149:
150: return (ret);
1.1 dugsong 151: }
152:
153: int
154: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
155: {
156: krb5_error_code problem;
157: krb5_ccache ccache = NULL;
158: char *pname;
1.3 deraadt 159:
1.1 dugsong 160: if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
161: return (0);
1.3 deraadt 162:
1.1 dugsong 163: temporarily_use_uid(authctxt->pw);
1.3 deraadt 164:
1.1 dugsong 165: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
166: if (problem)
167: goto fail;
1.3 deraadt 168:
1.1 dugsong 169: problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
170: authctxt->krb5_user);
171: if (problem)
172: goto fail;
1.3 deraadt 173:
1.1 dugsong 174: problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
175: ccache, tgt);
176: if (problem)
177: goto fail;
1.3 deraadt 178:
1.1 dugsong 179: authctxt->krb5_fwd_ccache = ccache;
180: ccache = NULL;
1.3 deraadt 181:
1.1 dugsong 182: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3 deraadt 183:
1.1 dugsong 184: problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
185: &pname);
186: if (problem)
187: goto fail;
1.3 deraadt 188:
1.1 dugsong 189: debug("Kerberos v5 TGT accepted (%s)", pname);
1.3 deraadt 190:
1.1 dugsong 191: restore_uid();
1.3 deraadt 192:
1.1 dugsong 193: return (1);
1.3 deraadt 194:
1.1 dugsong 195: fail:
196: if (problem)
197: debug("Kerberos v5 TGT passing failed: %s",
198: krb5_get_err_text(authctxt->krb5_ctx, problem));
199: if (ccache)
200: krb5_cc_destroy(authctxt->krb5_ctx, ccache);
1.3 deraadt 201:
1.1 dugsong 202: restore_uid();
1.3 deraadt 203:
1.1 dugsong 204: return (0);
205: }
206:
207: int
208: auth_krb5_password(Authctxt *authctxt, const char *password)
209: {
210: krb5_error_code problem;
1.3 deraadt 211:
1.1 dugsong 212: if (authctxt->pw == NULL)
213: return (0);
1.3 deraadt 214:
1.1 dugsong 215: temporarily_use_uid(authctxt->pw);
1.3 deraadt 216:
1.1 dugsong 217: problem = krb5_init(authctxt);
218: if (problem)
219: goto out;
1.3 deraadt 220:
1.1 dugsong 221: problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
222: &authctxt->krb5_user);
223: if (problem)
224: goto out;
1.3 deraadt 225:
1.1 dugsong 226: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
227: &authctxt->krb5_fwd_ccache);
228: if (problem)
229: goto out;
1.3 deraadt 230:
1.1 dugsong 231: problem = krb5_cc_initialize(authctxt->krb5_ctx,
232: authctxt->krb5_fwd_ccache, authctxt->krb5_user);
233: if (problem)
234: goto out;
1.3 deraadt 235:
1.4 markus 236: restore_uid();
1.1 dugsong 237: problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
238: authctxt->krb5_fwd_ccache, password, 1, NULL);
1.4 markus 239: temporarily_use_uid(authctxt->pw);
240:
1.1 dugsong 241: if (problem)
242: goto out;
1.3 deraadt 243:
1.1 dugsong 244: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3 deraadt 245:
1.1 dugsong 246: out:
247: restore_uid();
1.3 deraadt 248:
1.1 dugsong 249: if (problem) {
1.5 markus 250: if (authctxt->krb5_ctx != NULL)
251: debug("Kerberos password authentication failed: %s",
252: krb5_get_err_text(authctxt->krb5_ctx, problem));
253: else
254: debug("Kerberos password authentication failed: %d",
255: problem);
1.3 deraadt 256:
1.1 dugsong 257: krb5_cleanup_proc(authctxt);
1.3 deraadt 258:
1.1 dugsong 259: if (options.kerberos_or_local_passwd)
260: return (-1);
261: else
262: return (0);
263: }
264: return (1);
265: }
266:
267: void
268: krb5_cleanup_proc(void *context)
269: {
270: Authctxt *authctxt = (Authctxt *)context;
1.3 deraadt 271:
1.1 dugsong 272: debug("krb5_cleanup_proc called");
273: if (authctxt->krb5_fwd_ccache) {
274: krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
275: authctxt->krb5_fwd_ccache = NULL;
276: }
277: if (authctxt->krb5_user) {
278: krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
279: authctxt->krb5_user = NULL;
280: }
281: if (authctxt->krb5_auth_ctx) {
282: krb5_auth_con_free(authctxt->krb5_ctx,
283: authctxt->krb5_auth_ctx);
284: authctxt->krb5_auth_ctx = NULL;
285: }
286: if (authctxt->krb5_ctx) {
287: krb5_free_context(authctxt->krb5_ctx);
288: authctxt->krb5_ctx = NULL;
289: }
290: }
291:
292: #endif /* KRB5 */