Annotation of src/usr.bin/ssh/auth-krb5.c, Revision 1.2
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.2 ! dugsong 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;
1.2 ! dugsong 55: int fd, ret;
! 56:
! 57: ret = 0;
1.1 dugsong 58: server = NULL;
59: ticket = NULL;
60: reply.length = 0;
61:
62: problem = krb5_init(authctxt);
63: if (problem)
64: goto err;
65:
66: problem = krb5_auth_con_init(authctxt->krb5_ctx,
67: &authctxt->krb5_auth_ctx);
68: if (problem)
69: goto err;
70:
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;
76:
77: problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
78: KRB5_NT_SRV_HST, &server);
79: if (problem)
80: goto err;
81:
82: problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
83: auth, server, NULL, NULL, &ticket);
84: if (problem)
85: goto err;
86:
87: problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
88: &authctxt->krb5_user);
89: if (problem)
90: goto err;
91:
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;
97:
98: /* Check .k5login authorization now. */
99: if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
100: authctxt->pw->pw_name))
101: goto err;
102:
103: if (client)
104: krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
105: client);
106:
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);
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;
134:
135: if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
136: return (0);
137:
138: temporarily_use_uid(authctxt->pw);
139:
140: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
141: if (problem)
142: goto fail;
143:
144: problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
145: authctxt->krb5_user);
146: if (problem)
147: goto fail;
148:
149: problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
150: ccache, tgt);
151: if (problem)
152: goto fail;
153:
154: authctxt->krb5_fwd_ccache = ccache;
155: ccache = NULL;
156:
157: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
158:
159: problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
160: &pname);
161: if (problem)
162: goto fail;
163:
164: debug("Kerberos v5 TGT accepted (%s)", pname);
165:
166: restore_uid();
167:
168: return (1);
169:
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);
176:
177: restore_uid();
178:
179: return (0);
180: }
181:
182: int
183: auth_krb5_password(Authctxt *authctxt, const char *password)
184: {
185: krb5_error_code problem;
186:
187: if (authctxt->pw == NULL)
188: return (0);
189:
190: temporarily_use_uid(authctxt->pw);
191:
192: problem = krb5_init(authctxt);
193: if (problem)
194: goto out;
195:
196: problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
197: &authctxt->krb5_user);
198: if (problem)
199: goto out;
200:
201: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
202: &authctxt->krb5_fwd_ccache);
203: if (problem)
204: goto out;
205:
206: problem = krb5_cc_initialize(authctxt->krb5_ctx,
207: authctxt->krb5_fwd_ccache, authctxt->krb5_user);
208: if (problem)
209: goto out;
210:
211: problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
212: authctxt->krb5_fwd_ccache, password, 1, NULL);
213: if (problem)
214: goto out;
215:
216: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
217:
218: out:
219: restore_uid();
220:
221: if (problem) {
222: debug("Kerberos password authentication failed: %s",
223: krb5_get_err_text(authctxt->krb5_ctx, problem));
224:
225: krb5_cleanup_proc(authctxt);
226:
227: if (options.kerberos_or_local_passwd)
228: return (-1);
229: else
230: return (0);
231: }
232: return (1);
233: }
234:
235: void
236: krb5_cleanup_proc(void *context)
237: {
238: Authctxt *authctxt = (Authctxt *)context;
239:
240: debug("krb5_cleanup_proc called");
241: if (authctxt->krb5_fwd_ccache) {
242: krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
243: authctxt->krb5_fwd_ccache = NULL;
244: }
245: if (authctxt->krb5_user) {
246: krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
247: authctxt->krb5_user = NULL;
248: }
249: if (authctxt->krb5_auth_ctx) {
250: krb5_auth_con_free(authctxt->krb5_ctx,
251: authctxt->krb5_auth_ctx);
252: authctxt->krb5_auth_ctx = NULL;
253: }
254: if (authctxt->krb5_ctx) {
255: krb5_free_context(authctxt->krb5_ctx);
256: authctxt->krb5_ctx = NULL;
257: }
258: }
259:
260: #endif /* KRB5 */