2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
3
Copyright (C) 2005- The University of Notre Dame
4
This software is distributed under the GNU General Public License.
5
See the file COPYING for details.
8
#if defined(HAS_KRB5) && !defined(CCTOOLS_OPSYS_FREEBSD)
16
#include "domain_name_cache.h"
22
#define SERVICE "host"
23
#define VERSION "dttools_auth_protocol_1"
25
int auth_kerberos_assert( struct link *link, struct hash_table *t, time_t stoptime )
29
krb5_principal client, server;
31
krb5_auth_context auth_context = 0;
32
krb5_ap_rep_enc_part *rep_ret;
37
char addr[LINK_ADDRESS_MAX];
38
char dname[DOMAIN_NAME_MAX];
40
debug(D_AUTH,"kerberos: determining service name");
42
link_address_remote(link,addr,&port);
43
if(domain_name_cache_lookup_reverse(addr,dname)) {
45
debug(D_AUTH,"kerberos: name of %s is %s",addr,dname);
47
cksum.length = strlen(dname);
49
debug(D_AUTH,"kerberos: creating context");
50
if(!krb5_init_context(&context)) {
52
debug(D_AUTH,"kerberos: opening credential cache");
53
if(!krb5_cc_default(context,&ccdef)) {
55
debug(D_AUTH,"kerberos: loading my credentials");
56
if(!krb5_cc_get_principal(context,ccdef,&client)) {
59
krb5_unparse_name(context,client,&name);
60
debug(D_AUTH,"kerberos: I am %s",name);
63
debug(D_AUTH,"kerberos: building server principal");
64
if(!krb5_sname_to_principal(context,dname,SERVICE,KRB5_NT_SRV_HST,&server)) {
66
krb5_unparse_name(context,server,&name);
67
debug(D_AUTH,"kerberos: expecting server %s",name);
69
debug(D_AUTH,"kerberos: waiting for server");
70
if(auth_barrier(link,"yes\n",stoptime)) {
71
debug(D_AUTH,"kerberos: authenticating with server");
72
int fd = link_fd(link);
73
link_nonblocking(link,0);
74
int result = krb5_sendauth(context,&auth_context,&fd,VERSION,client,server,AP_OPTS_MUTUAL_REQUIRED,&cksum,0,ccdef,&err_ret,&rep_ret,0);
75
link_nonblocking(link,1);
77
debug(D_AUTH,"kerberos: credentials accepted!");
78
krb5_free_ap_rep_enc_part(context,rep_ret);
79
krb5_auth_con_free(context,auth_context);
82
debug(D_AUTH,"kerberos: couldn't authenticate to server");
84
krb5_free_principal(context,server);
86
debug(D_AUTH,"kerberos: server couldn't load credentials");
89
debug(D_AUTH,"kerberos: couldn't build server principal");
90
auth_barrier(link,"no\n",stoptime);
92
krb5_free_principal(context,client);
94
debug(D_AUTH,"kerberos: couldn't retrieve my credentials");
95
auth_barrier(link,"no\n",stoptime);
97
krb5_cc_close(context,ccdef);
99
debug(D_AUTH,"kerberos: couldn't open the credential cache");
100
auth_barrier(link,"no\n",stoptime);
102
krb5_free_context(context);
104
debug(D_AUTH,"kerberos: couldn't create a context");
105
auth_barrier(link,"no\n",stoptime);
108
debug(D_AUTH,"kerberos: couldn't determine name of %s",addr);
109
auth_barrier(link,"no\n",stoptime);
115
int auth_kerberos_accept( struct link *link, char **subject, struct hash_table *t, time_t stoptime )
117
krb5_context context;
118
krb5_auth_context auth_context = NULL;
120
krb5_principal principal;
122
krb5_kt_cursor cursor;
126
debug(D_AUTH,"kerberos: creating a context");
127
if(!krb5_init_context(&context)) {
129
debug(D_AUTH,"kerberos: computing my service name");
130
if(!krb5_sname_to_principal(context,NULL,SERVICE,KRB5_NT_SRV_HST,&principal)) {
132
krb5_unparse_name(context,principal,&name);
133
debug(D_AUTH,"kerberos: I am %s",name);
136
debug(D_AUTH,"kerberos: looking for a keytab");
137
if(!krb5_kt_default(context,&keytab)) {
138
debug(D_AUTH,"kerberos: attempting to open keytab");
139
if(!krb5_kt_start_seq_get(context,keytab,&cursor)) {
140
krb5_kt_close(context,keytab);
142
debug(D_AUTH,"kerberos: waiting for client");
143
if(auth_barrier(link,"yes\n",stoptime)) {
145
debug(D_AUTH,"kerberos: receiving client credentials");
146
int fd = link_fd(link);
147
link_nonblocking(link,0);
148
int result = krb5_recvauth(context,&auth_context,&fd,VERSION,principal,0,0,&ticket);
149
link_nonblocking(link,1);
152
char myrealm[AUTH_SUBJECT_MAX];
153
char userrealm[AUTH_SUBJECT_MAX];
154
char username[AUTH_SUBJECT_MAX];
156
debug(D_AUTH,"kerberos: parsing client name");
158
strncpy(myrealm,principal->realm.data,principal->realm.length);
159
myrealm[principal->realm.length] = 0;
161
strncpy(userrealm,ticket->enc_part2->client->realm.data,ticket->enc_part2->client->realm.length);
162
userrealm[ticket->enc_part2->client->realm.length] = 0;
164
strncpy(username,ticket->enc_part2->client->data->data,ticket->enc_part2->client->data->length);
165
username[ticket->enc_part2->client->data->length] = 0;
167
debug(D_AUTH,"kerberos: user is %s@%s\n",username,userrealm);
168
debug(D_AUTH,"kerberos: my realm is %s\n",myrealm);
170
if(strcmp(myrealm,userrealm)) {
171
debug(D_AUTH,"kerberos: sorry, you come from another realm\n");
173
debug(D_AUTH,"kerberos: local user is %s\n",username);
174
*subject = xstrdup(username);
177
krb5_auth_con_free(context,auth_context);
179
debug(D_AUTH,"kerberos: couldn't receive client credentials");
182
debug(D_AUTH,"kerberos: client couldn't load credentials");
185
debug(D_AUTH,"kerberos: couldn't find Kerberos keytab");
186
auth_barrier(link,"no\n",stoptime);
189
debug(D_AUTH,"kerberos: couldn't find Kerberos keytab");
190
auth_barrier(link,"no\n",stoptime);
193
debug(D_AUTH,"kerberos: couldn't figure out my service name");
194
auth_barrier(link,"no\n",stoptime);
197
debug(D_AUTH,"kerberos: couldn't create kerberos context");
198
auth_barrier(link,"no\n",stoptime);
202
debug(D_AUTH,"kerberos: perhaps this didn't work because I am not run as root.");
208
int auth_kerberos_register()
210
debug(D_AUTH,"kerberos: registered");
211
return auth_register("kerberos",auth_kerberos_assert,auth_kerberos_accept);
218
int auth_kerberos_register()
220
debug(D_AUTH,"kerberos: not compiled in");