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