Annotation of src/usr.bin/ssh/auth-krb5.c, Revision 1.1.2.1
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.1.2.1 ! miod 5: * $OpenBSD: auth-krb5.c,v 1.1 2001/06/26 16:15:23 dugsong 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;
29:
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: */
48: int
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;
55: int fd;
56:
57: server = NULL;
58: ticket = NULL;
59: reply.length = 0;
60:
61: problem = krb5_init(authctxt);
62: if (problem)
63: goto err;
64:
65: problem = krb5_auth_con_init(authctxt->krb5_ctx,
66: &authctxt->krb5_auth_ctx);
67: if (problem)
68: goto err;
69:
70: fd = packet_get_connection_in();
71: problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
72: authctxt->krb5_auth_ctx, &fd);
73: if (problem)
74: goto err;
75:
76: problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
77: KRB5_NT_SRV_HST, &server);
78: if (problem)
79: goto err;
80:
81: problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
82: auth, server, NULL, NULL, &ticket);
83: if (problem)
84: goto err;
85:
86: problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
87: &authctxt->krb5_user);
88: if (problem)
89: goto err;
90:
91: /* if client wants mutual auth */
92: problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
93: &reply);
94: if (problem)
95: goto err;
96:
97: /* Check .k5login authorization now. */
98: if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
99: authctxt->pw->pw_name))
100: goto err;
101:
102: if (client)
103: krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
104: client);
105:
106: packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
107: packet_put_string((char *) reply.data, reply.length);
108: packet_send();
109: packet_write_wait();
110:
111: err:
112: if (server)
113: krb5_free_principal(authctxt->krb5_ctx, server);
114: if (ticket)
115: krb5_free_ticket(authctxt->krb5_ctx, ticket);
116: if (reply.length)
117: xfree(reply.data);
118:
119: if (problem) {
120: debug("Kerberos v5 authentication failed: %s",
121: krb5_get_err_text(authctxt->krb5_ctx, problem));
122: return (0);
123: }
124: return (1);
125: }
126:
127: int
128: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
129: {
130: krb5_error_code problem;
131: krb5_ccache ccache = NULL;
132: char *pname;
133:
134: if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
135: return (0);
136:
137: temporarily_use_uid(authctxt->pw);
138:
139: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
140: if (problem)
141: goto fail;
142:
143: problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
144: authctxt->krb5_user);
145: if (problem)
146: goto fail;
147:
148: problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
149: ccache, tgt);
150: if (problem)
151: goto fail;
152:
153: authctxt->krb5_fwd_ccache = ccache;
154: ccache = NULL;
155:
156: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
157:
158: problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
159: &pname);
160: if (problem)
161: goto fail;
162:
163: debug("Kerberos v5 TGT accepted (%s)", pname);
164:
165: restore_uid();
166:
167: return (1);
168:
169: fail:
170: if (problem)
171: debug("Kerberos v5 TGT passing failed: %s",
172: krb5_get_err_text(authctxt->krb5_ctx, problem));
173: if (ccache)
174: krb5_cc_destroy(authctxt->krb5_ctx, ccache);
175:
176: restore_uid();
177:
178: return (0);
179: }
180:
181: int
182: auth_krb5_password(Authctxt *authctxt, const char *password)
183: {
184: krb5_error_code problem;
185:
186: if (authctxt->pw == NULL)
187: return (0);
188:
189: temporarily_use_uid(authctxt->pw);
190:
191: problem = krb5_init(authctxt);
192: if (problem)
193: goto out;
194:
195: problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
196: &authctxt->krb5_user);
197: if (problem)
198: goto out;
199:
200: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
201: &authctxt->krb5_fwd_ccache);
202: if (problem)
203: goto out;
204:
205: problem = krb5_cc_initialize(authctxt->krb5_ctx,
206: authctxt->krb5_fwd_ccache, authctxt->krb5_user);
207: if (problem)
208: goto out;
209:
210: problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
211: authctxt->krb5_fwd_ccache, password, 1, NULL);
212: if (problem)
213: goto out;
214:
215: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
216:
217: out:
218: restore_uid();
219:
220: if (problem) {
221: debug("Kerberos password authentication failed: %s",
222: krb5_get_err_text(authctxt->krb5_ctx, problem));
223:
224: krb5_cleanup_proc(authctxt);
225:
226: if (options.kerberos_or_local_passwd)
227: return (-1);
228: else
229: return (0);
230: }
231: return (1);
232: }
233:
234: void
235: krb5_cleanup_proc(void *context)
236: {
237: Authctxt *authctxt = (Authctxt *)context;
238:
239: debug("krb5_cleanup_proc called");
240: if (authctxt->krb5_fwd_ccache) {
241: krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
242: authctxt->krb5_fwd_ccache = NULL;
243: }
244: if (authctxt->krb5_user) {
245: krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
246: authctxt->krb5_user = NULL;
247: }
248: if (authctxt->krb5_auth_ctx) {
249: krb5_auth_con_free(authctxt->krb5_ctx,
250: authctxt->krb5_auth_ctx);
251: authctxt->krb5_auth_ctx = NULL;
252: }
253: if (authctxt->krb5_ctx) {
254: krb5_free_context(authctxt->krb5_ctx);
255: authctxt->krb5_ctx = NULL;
256: }
257: }
258:
259: #endif /* KRB5 */