Annotation of src/usr.bin/ssh/auth-krb5.c, Revision 1.1.2.3
1.1 dugsong 1: /*
2: * Kerberos v5 authentication and ticket-passing routines.
3: *
4: * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
5: */
6:
7: #include "includes.h"
1.1.2.3 ! brad 8: RCSID("$OpenBSD: auth-krb5.c,v 1.6 2002/03/04 17:27:39 stevesk Exp $");
! 9:
1.1 dugsong 10: #include "ssh.h"
11: #include "ssh1.h"
12: #include "packet.h"
13: #include "xmalloc.h"
14: #include "log.h"
15: #include "servconf.h"
16: #include "uidswap.h"
17: #include "auth.h"
18:
19: #ifdef KRB5
20: #include <krb5.h>
21:
22: extern ServerOptions options;
23:
24: static int
25: krb5_init(void *context)
26: {
27: Authctxt *authctxt = (Authctxt *)context;
28: krb5_error_code problem;
29: static int cleanup_registered = 0;
1.1.2.3 ! brad 30:
1.1 dugsong 31: if (authctxt->krb5_ctx == NULL) {
32: problem = krb5_init_context(&authctxt->krb5_ctx);
33: if (problem)
34: return (problem);
35: krb5_init_ets(authctxt->krb5_ctx);
36: }
37: if (!cleanup_registered) {
38: fatal_add_cleanup(krb5_cleanup_proc, authctxt);
39: cleanup_registered = 1;
40: }
41: return (0);
42: }
43:
44: /*
45: * Try krb5 authentication. server_user is passed for logging purposes
46: * only, in auth is received ticket, in client is returned principal
47: * from the ticket
48: */
1.1.2.3 ! brad 49: int
1.1 dugsong 50: auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
51: {
52: krb5_error_code problem;
53: krb5_principal server;
54: krb5_data reply;
55: krb5_ticket *ticket;
1.1.2.2 miod 56: int fd, ret;
57:
58: ret = 0;
1.1 dugsong 59: server = NULL;
60: ticket = NULL;
61: reply.length = 0;
1.1.2.3 ! brad 62:
1.1 dugsong 63: problem = krb5_init(authctxt);
1.1.2.3 ! brad 64: if (problem)
1.1 dugsong 65: goto err;
1.1.2.3 ! brad 66:
1.1 dugsong 67: problem = krb5_auth_con_init(authctxt->krb5_ctx,
68: &authctxt->krb5_auth_ctx);
69: if (problem)
70: goto err;
1.1.2.3 ! brad 71:
1.1 dugsong 72: fd = packet_get_connection_in();
73: problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
74: authctxt->krb5_auth_ctx, &fd);
75: if (problem)
76: goto err;
1.1.2.3 ! brad 77:
1.1 dugsong 78: problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
79: KRB5_NT_SRV_HST, &server);
80: if (problem)
81: goto err;
1.1.2.3 ! brad 82:
1.1 dugsong 83: problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
84: auth, server, NULL, NULL, &ticket);
85: if (problem)
86: goto err;
1.1.2.3 ! brad 87:
1.1 dugsong 88: problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
89: &authctxt->krb5_user);
90: if (problem)
91: goto err;
1.1.2.3 ! brad 92:
1.1 dugsong 93: /* if client wants mutual auth */
94: problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
95: &reply);
96: if (problem)
97: goto err;
1.1.2.3 ! brad 98:
1.1 dugsong 99: /* Check .k5login authorization now. */
100: if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
101: authctxt->pw->pw_name))
102: goto err;
1.1.2.3 ! brad 103:
1.1 dugsong 104: if (client)
105: krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
106: client);
1.1.2.3 ! brad 107:
1.1 dugsong 108: packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
109: packet_put_string((char *) reply.data, reply.length);
110: packet_send();
111: packet_write_wait();
1.1.2.2 miod 112:
113: ret = 1;
1.1 dugsong 114: err:
115: if (server)
116: krb5_free_principal(authctxt->krb5_ctx, server);
117: if (ticket)
118: krb5_free_ticket(authctxt->krb5_ctx, ticket);
119: if (reply.length)
120: xfree(reply.data);
1.1.2.3 ! brad 121:
! 122: if (problem) {
! 123: if (authctxt->krb5_ctx != NULL)
! 124: debug("Kerberos v5 authentication failed: %s",
! 125: krb5_get_err_text(authctxt->krb5_ctx, problem));
! 126: else
! 127: debug("Kerberos v5 authentication failed: %d",
! 128: problem);
! 129: }
1.1.2.2 miod 130:
131: return (ret);
1.1 dugsong 132: }
133:
134: int
135: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
136: {
137: krb5_error_code problem;
138: krb5_ccache ccache = NULL;
139: char *pname;
1.1.2.3 ! brad 140:
1.1 dugsong 141: if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
142: return (0);
1.1.2.3 ! brad 143:
1.1 dugsong 144: temporarily_use_uid(authctxt->pw);
1.1.2.3 ! brad 145:
1.1 dugsong 146: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
147: if (problem)
148: goto fail;
1.1.2.3 ! brad 149:
1.1 dugsong 150: problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
151: authctxt->krb5_user);
152: if (problem)
153: goto fail;
1.1.2.3 ! brad 154:
1.1 dugsong 155: problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
156: ccache, tgt);
157: if (problem)
158: goto fail;
1.1.2.3 ! brad 159:
1.1 dugsong 160: authctxt->krb5_fwd_ccache = ccache;
161: ccache = NULL;
1.1.2.3 ! brad 162:
1.1 dugsong 163: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.1.2.3 ! brad 164:
1.1 dugsong 165: problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
166: &pname);
167: if (problem)
168: goto fail;
1.1.2.3 ! brad 169:
1.1 dugsong 170: debug("Kerberos v5 TGT accepted (%s)", pname);
1.1.2.3 ! brad 171:
1.1 dugsong 172: restore_uid();
1.1.2.3 ! brad 173:
1.1 dugsong 174: return (1);
1.1.2.3 ! brad 175:
1.1 dugsong 176: fail:
177: if (problem)
178: debug("Kerberos v5 TGT passing failed: %s",
179: krb5_get_err_text(authctxt->krb5_ctx, problem));
180: if (ccache)
181: krb5_cc_destroy(authctxt->krb5_ctx, ccache);
1.1.2.3 ! brad 182:
1.1 dugsong 183: restore_uid();
1.1.2.3 ! brad 184:
1.1 dugsong 185: return (0);
186: }
187:
188: int
189: auth_krb5_password(Authctxt *authctxt, const char *password)
190: {
191: krb5_error_code problem;
1.1.2.3 ! brad 192:
1.1 dugsong 193: if (authctxt->pw == NULL)
194: return (0);
1.1.2.3 ! brad 195:
1.1 dugsong 196: temporarily_use_uid(authctxt->pw);
1.1.2.3 ! brad 197:
1.1 dugsong 198: problem = krb5_init(authctxt);
199: if (problem)
200: goto out;
1.1.2.3 ! brad 201:
1.1 dugsong 202: problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
203: &authctxt->krb5_user);
204: if (problem)
205: goto out;
1.1.2.3 ! brad 206:
1.1 dugsong 207: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
208: &authctxt->krb5_fwd_ccache);
209: if (problem)
210: goto out;
1.1.2.3 ! brad 211:
1.1 dugsong 212: problem = krb5_cc_initialize(authctxt->krb5_ctx,
213: authctxt->krb5_fwd_ccache, authctxt->krb5_user);
214: if (problem)
215: goto out;
1.1.2.3 ! brad 216:
! 217: restore_uid();
1.1 dugsong 218: problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
219: authctxt->krb5_fwd_ccache, password, 1, NULL);
1.1.2.3 ! brad 220: temporarily_use_uid(authctxt->pw);
! 221:
1.1 dugsong 222: if (problem)
223: goto out;
1.1.2.3 ! brad 224:
1.1 dugsong 225: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.1.2.3 ! brad 226:
1.1 dugsong 227: out:
228: restore_uid();
1.1.2.3 ! brad 229:
1.1 dugsong 230: if (problem) {
1.1.2.3 ! brad 231: if (authctxt->krb5_ctx != NULL)
! 232: debug("Kerberos password authentication failed: %s",
! 233: krb5_get_err_text(authctxt->krb5_ctx, problem));
! 234: else
! 235: debug("Kerberos password authentication failed: %d",
! 236: problem);
! 237:
1.1 dugsong 238: krb5_cleanup_proc(authctxt);
1.1.2.3 ! brad 239:
1.1 dugsong 240: if (options.kerberos_or_local_passwd)
241: return (-1);
242: else
243: return (0);
244: }
245: return (1);
246: }
247:
248: void
249: krb5_cleanup_proc(void *context)
250: {
251: Authctxt *authctxt = (Authctxt *)context;
1.1.2.3 ! brad 252:
1.1 dugsong 253: debug("krb5_cleanup_proc called");
254: if (authctxt->krb5_fwd_ccache) {
255: krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
256: authctxt->krb5_fwd_ccache = NULL;
257: }
258: if (authctxt->krb5_user) {
259: krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
260: authctxt->krb5_user = NULL;
261: }
262: if (authctxt->krb5_auth_ctx) {
263: krb5_auth_con_free(authctxt->krb5_ctx,
264: authctxt->krb5_auth_ctx);
265: authctxt->krb5_auth_ctx = NULL;
266: }
267: if (authctxt->krb5_ctx) {
268: krb5_free_context(authctxt->krb5_ctx);
269: authctxt->krb5_ctx = NULL;
270: }
271: }
272:
273: #endif /* KRB5 */