~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to dttools/src/auth_kerberos.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
6
*/
 
7
 
 
8
#if defined(HAS_KRB5) && !defined(CCTOOLS_OPSYS_FREEBSD)
 
9
 
 
10
#include "krb5.h"
 
11
 
 
12
#include "auth.h"
 
13
#include "link.h"
 
14
#include "debug.h"
 
15
#include "xmalloc.h"
 
16
#include "domain_name_cache.h"
 
17
 
 
18
#include <string.h>
 
19
#include <stdlib.h>
 
20
#include <unistd.h>
 
21
 
 
22
#define SERVICE "host"
 
23
#define VERSION "dttools_auth_protocol_1"
 
24
 
 
25
int auth_kerberos_assert( struct link *link, struct hash_table *t, time_t stoptime )
 
26
{
 
27
        krb5_context context;
 
28
        krb5_ccache ccdef;
 
29
        krb5_principal client, server;
 
30
        krb5_data cksum;
 
31
        krb5_auth_context auth_context = 0;
 
32
        krb5_ap_rep_enc_part *rep_ret;
 
33
        krb5_error *err_ret;
 
34
        int success = 0;
 
35
        int port;
 
36
 
 
37
        char addr[LINK_ADDRESS_MAX];
 
38
        char dname[DOMAIN_NAME_MAX];
 
39
 
 
40
        debug(D_AUTH,"kerberos: determining service name");
 
41
 
 
42
        link_address_remote(link,addr,&port);
 
43
        if(domain_name_cache_lookup_reverse(addr,dname)) {
 
44
 
 
45
                debug(D_AUTH,"kerberos: name of %s is %s",addr,dname);
 
46
                cksum.data = dname;
 
47
                cksum.length = strlen(dname);
 
48
 
 
49
                debug(D_AUTH,"kerberos: creating context");
 
50
                if(!krb5_init_context(&context)) {
 
51
 
 
52
                        debug(D_AUTH,"kerberos: opening credential cache");
 
53
                        if(!krb5_cc_default(context,&ccdef)) {
 
54
 
 
55
                                debug(D_AUTH,"kerberos: loading my credentials");
 
56
                                if(!krb5_cc_get_principal(context,ccdef,&client)) {
 
57
 
 
58
                                        char *name;
 
59
                                        krb5_unparse_name(context,client,&name);
 
60
                                        debug(D_AUTH,"kerberos: I am %s",name);
 
61
                                        free(name);
 
62
 
 
63
                                        debug(D_AUTH,"kerberos: building server principal");
 
64
                                        if(!krb5_sname_to_principal(context,dname,SERVICE,KRB5_NT_SRV_HST,&server)) {
 
65
 
 
66
                                                krb5_unparse_name(context,server,&name);
 
67
                                                debug(D_AUTH,"kerberos: expecting server %s",name);
 
68
                                                free(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);
 
76
                                                        if(result==0) {
 
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);
 
80
                                                                success = 1;
 
81
                                                        } else {
 
82
                                                                debug(D_AUTH,"kerberos: couldn't authenticate to server");
 
83
                                                        }
 
84
                                                        krb5_free_principal(context,server);
 
85
                                                } else {
 
86
                                                        debug(D_AUTH,"kerberos: server couldn't load credentials");
 
87
                                                }
 
88
                                        } else {
 
89
                                                debug(D_AUTH,"kerberos: couldn't build server principal");
 
90
                                                auth_barrier(link,"no\n",stoptime);
 
91
                                        }
 
92
                                        krb5_free_principal(context,client);
 
93
                                } else {
 
94
                                        debug(D_AUTH,"kerberos: couldn't retrieve my credentials");
 
95
                                        auth_barrier(link,"no\n",stoptime);
 
96
                                }
 
97
                                krb5_cc_close(context,ccdef);
 
98
                        } else {
 
99
                                debug(D_AUTH,"kerberos: couldn't open the credential cache");
 
100
                                auth_barrier(link,"no\n",stoptime);
 
101
                        }
 
102
                        krb5_free_context(context);
 
103
                } else {
 
104
                        debug(D_AUTH,"kerberos: couldn't create a context");
 
105
                        auth_barrier(link,"no\n",stoptime);
 
106
                }
 
107
        } else {
 
108
                debug(D_AUTH,"kerberos: couldn't determine name of %s",addr);
 
109
                auth_barrier(link,"no\n",stoptime);
 
110
        }
 
111
 
 
112
        return success;
 
113
}
 
114
 
 
115
int auth_kerberos_accept( struct link *link, char **subject, struct hash_table *t, time_t stoptime )
 
116
{
 
117
        krb5_context context;
 
118
        krb5_auth_context auth_context = NULL;
 
119
        krb5_ticket *ticket;
 
120
        krb5_principal principal;
 
121
        krb5_keytab keytab;
 
122
        krb5_kt_cursor cursor;
 
123
 
 
124
        int success=0;
 
125
 
 
126
        debug(D_AUTH,"kerberos: creating a context");
 
127
        if(!krb5_init_context(&context)) {
 
128
 
 
129
                debug(D_AUTH,"kerberos: computing my service name");
 
130
                if(!krb5_sname_to_principal(context,NULL,SERVICE,KRB5_NT_SRV_HST,&principal)) {
 
131
                        char *name;
 
132
                        krb5_unparse_name(context,principal,&name);
 
133
                        debug(D_AUTH,"kerberos: I am %s",name);
 
134
                        free(name);
 
135
 
 
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);
 
141
 
 
142
                                        debug(D_AUTH,"kerberos: waiting for client");
 
143
                                        if(auth_barrier(link,"yes\n",stoptime)) {
 
144
 
 
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);
 
150
                                                if(result==0) {
 
151
 
 
152
                                                        char myrealm[AUTH_SUBJECT_MAX];
 
153
                                                        char userrealm[AUTH_SUBJECT_MAX];
 
154
                                                        char username[AUTH_SUBJECT_MAX];
 
155
 
 
156
                                                        debug(D_AUTH,"kerberos: parsing client name");
 
157
 
 
158
                                                        strncpy(myrealm,principal->realm.data,principal->realm.length);
 
159
                                                        myrealm[principal->realm.length] = 0;
 
160
 
 
161
                                                        strncpy(userrealm,ticket->enc_part2->client->realm.data,ticket->enc_part2->client->realm.length);
 
162
                                                        userrealm[ticket->enc_part2->client->realm.length] = 0;
 
163
                
 
164
                                                        strncpy(username,ticket->enc_part2->client->data->data,ticket->enc_part2->client->data->length);
 
165
                                                        username[ticket->enc_part2->client->data->length] = 0;
 
166
 
 
167
                                                        debug(D_AUTH,"kerberos: user is %s@%s\n",username,userrealm);
 
168
                                                        debug(D_AUTH,"kerberos: my realm is %s\n",myrealm);
 
169
 
 
170
                                                        if(strcmp(myrealm,userrealm)) {
 
171
                                                                debug(D_AUTH,"kerberos: sorry, you come from another realm\n");
 
172
                                                        } else {
 
173
                                                                debug(D_AUTH,"kerberos: local user is %s\n",username);
 
174
                                                                *subject = xstrdup(username);
 
175
                                                                success = 1;
 
176
                                                        }
 
177
                                                        krb5_auth_con_free(context,auth_context);
 
178
                                                } else {
 
179
                                                        debug(D_AUTH,"kerberos: couldn't receive client credentials");
 
180
                                                }
 
181
                                        } else {
 
182
                                                debug(D_AUTH,"kerberos: client couldn't load credentials");
 
183
                                        }
 
184
                                } else {
 
185
                                        debug(D_AUTH,"kerberos: couldn't find Kerberos keytab");
 
186
                                        auth_barrier(link,"no\n",stoptime);
 
187
                                }
 
188
                        } else {
 
189
                                debug(D_AUTH,"kerberos: couldn't find Kerberos keytab");
 
190
                                auth_barrier(link,"no\n",stoptime);
 
191
                        }
 
192
                } else {
 
193
                        debug(D_AUTH,"kerberos: couldn't figure out my service name");
 
194
                        auth_barrier(link,"no\n",stoptime);
 
195
                }
 
196
        } else {
 
197
                debug(D_AUTH,"kerberos: couldn't create kerberos context");
 
198
                auth_barrier(link,"no\n",stoptime);
 
199
        }
 
200
 
 
201
        if(getuid()!=0) {
 
202
                debug(D_AUTH,"kerberos: perhaps this didn't work because I am not run as root.");
 
203
        }
 
204
 
 
205
        return success;
 
206
}
 
207
 
 
208
int auth_kerberos_register()
 
209
{
 
210
        debug(D_AUTH,"kerberos: registered");
 
211
        return auth_register("kerberos",auth_kerberos_assert,auth_kerberos_accept);
 
212
}
 
213
 
 
214
#else
 
215
 
 
216
#include "debug.h"
 
217
 
 
218
int auth_kerberos_register()
 
219
{
 
220
        debug(D_AUTH,"kerberos: not compiled in");
 
221
        return 0;
 
222
}
 
223
 
 
224
#endif