Line 0
Link Here
|
|
|
1 |
/* Copyright (c) 2005 |
2 |
* Fredrik Tolf (fredrik@dolda2000.com) |
3 |
* |
4 |
* This program is free software; you can redistribute it and/or modify |
5 |
* it under the terms of the GNU General Public License as published by |
6 |
* the Free Software Foundation; either version 2, or (at your option) |
7 |
* any later version. |
8 |
* |
9 |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
* GNU General Public License for more details. |
13 |
* |
14 |
* You should have received a copy of the GNU General Public License |
15 |
* along with this program (see the file COPYING); if not, write to the |
16 |
* Free Software Foundation, Inc., |
17 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
18 |
* |
19 |
**************************************************************** |
20 |
*/ |
21 |
|
22 |
#include "config.h" |
23 |
#ifdef HAVE_KRB5 |
24 |
|
25 |
#include <stdlib.h> |
26 |
#include <stdio.h> |
27 |
#include <unistd.h> |
28 |
#include <krb5.h> |
29 |
#include <com_err.h> |
30 |
|
31 |
#include "screen.h" |
32 |
|
33 |
/* |
34 |
* I do not like the coding style of screen... =( |
35 |
*/ |
36 |
|
37 |
static krb5_context context; |
38 |
static krb5_ccache ccache; |
39 |
static int usingkrb = 0; |
40 |
static struct event renewev; |
41 |
|
42 |
#include "extern.h" |
43 |
|
44 |
static void |
45 |
krb_renew(ev, data) |
46 |
struct event *ev; |
47 |
char *data; |
48 |
{ |
49 |
int ret; |
50 |
krb5_principal myprinc; |
51 |
krb5_creds creds; |
52 |
krb5_cc_cursor cur; |
53 |
time_t now; |
54 |
int renew; |
55 |
|
56 |
SetTimeout(&renewev, 60000); |
57 |
evenq(&renewev); |
58 |
|
59 |
if((ret = krb5_cc_get_principal(context, ccache, &myprinc)) != 0) |
60 |
{ |
61 |
Msg(0, "Could not get principal to renew: %s", error_message(ret)); |
62 |
return; |
63 |
} |
64 |
|
65 |
if((ret = krb5_cc_start_seq_get(context, ccache, &cur)) != 0) |
66 |
{ |
67 |
Msg(0, "Could not open current credentials cache: %s", error_message(ret)); |
68 |
krb5_free_principal(context, myprinc); |
69 |
return; |
70 |
} |
71 |
time(&now); |
72 |
renew = 0; |
73 |
while(!krb5_cc_next_cred(context, ccache, &cur, &creds)) |
74 |
{ |
75 |
if(!strcmp(krb5_princ_component(context, creds.server, 0)->data, KRB5_TGS_NAME) && |
76 |
!strcmp(krb5_princ_component(context, creds.server, 1)->data, myprinc->realm.data)) |
77 |
{ |
78 |
if(!creds.times.starttime) |
79 |
creds.times.starttime = creds.times.authtime; |
80 |
if(now > (creds.times.starttime + (((creds.times.endtime - creds.times.starttime) * 9) / 10))) |
81 |
renew = 1; |
82 |
break; |
83 |
} |
84 |
krb5_free_cred_contents(context, &creds); |
85 |
} |
86 |
krb5_cc_end_seq_get(context, ccache, &cur); |
87 |
if(!renew) |
88 |
{ |
89 |
krb5_free_principal(context, myprinc); |
90 |
return; |
91 |
} |
92 |
|
93 |
memset(&creds, 0, sizeof(creds)); |
94 |
if((ret = krb5_get_renewed_creds(context, &creds, myprinc, ccache, NULL)) != 0) |
95 |
{ |
96 |
Msg(0, "Could not get renewed credentials: %s", error_message(ret)); |
97 |
krb5_free_principal(context, myprinc); |
98 |
return; |
99 |
} |
100 |
if((ret = krb5_cc_initialize(context, ccache, myprinc)) != 0) |
101 |
{ |
102 |
Msg(0, "Could not re-initialize credentials cache: %s", error_message(ret)); |
103 |
krb5_free_principal(context, myprinc); |
104 |
krb5_free_cred_contents(context, &creds); |
105 |
return; |
106 |
} |
107 |
if((ret = krb5_cc_store_cred(context, ccache, &creds)) != 0) |
108 |
{ |
109 |
Msg(0, "Could not store renewed TGT: %s", error_message(ret)); |
110 |
krb5_free_principal(context, myprinc); |
111 |
krb5_free_cred_contents(context, &creds); |
112 |
return; |
113 |
} |
114 |
|
115 |
krb5_free_principal(context, myprinc); |
116 |
krb5_free_cred_contents(context, &creds); |
117 |
Msg(0, "Renewed Kerberos credentials successfully."); |
118 |
} |
119 |
|
120 |
int |
121 |
krb_copycc() |
122 |
{ |
123 |
int ret, fd; |
124 |
krb5_ccache prevcache; |
125 |
krb5_principal myprinc; |
126 |
krb5_creds creds; |
127 |
krb5_cc_cursor cur; |
128 |
char buf[100]; |
129 |
char *ccfile; |
130 |
|
131 |
if((ret = krb5_init_context(&context)) != 0) |
132 |
{ |
133 |
Msg(0, "Could not initialize Kerberos library: %s", error_message(ret)); |
134 |
return(-1); |
135 |
} |
136 |
if((ret = krb5_cc_default(context, &prevcache)) != 0) |
137 |
{ |
138 |
Msg(0, "Could not get Kerberos credential cache: %s", error_message(ret)); |
139 |
krb5_free_context(context); |
140 |
return(-1); |
141 |
} |
142 |
if((ret = krb5_cc_get_principal(context, prevcache, &myprinc)) != 0) |
143 |
{ |
144 |
Msg(0, "Could not get principal of current ccache: %s", error_message(ret)); |
145 |
krb5_cc_close(context, prevcache); |
146 |
krb5_free_context(context); |
147 |
return(-1); |
148 |
} |
149 |
|
150 |
sprintf(buf, "FILE:/tmp/krb5cc_scr_%i_XXXXXX", getuid()); |
151 |
ccfile = buf + 5; |
152 |
if((fd = mkstemp(ccfile)) < 0) |
153 |
{ |
154 |
Msg(errno, "Could not create temporary file."); |
155 |
krb5_cc_close(context, prevcache); |
156 |
krb5_free_context(context); |
157 |
return(-1); |
158 |
} |
159 |
close(fd); |
160 |
if((ret = krb5_cc_resolve(context, buf, &ccache)) != 0) |
161 |
{ |
162 |
Msg(0, "Could not resolve new credential cache: %s", error_message(ret)); |
163 |
krb5_cc_close(context, prevcache); |
164 |
krb5_free_context(context); |
165 |
return(-1); |
166 |
} |
167 |
if((ret = krb5_cc_initialize(context, ccache, myprinc)) != 0) |
168 |
{ |
169 |
Msg(0, "Could not initialize new credential cache: %s", error_message(ret)); |
170 |
krb5_cc_close(context, prevcache); |
171 |
krb5_free_context(context); |
172 |
return(-1); |
173 |
} |
174 |
|
175 |
if((ret = krb5_cc_start_seq_get(context, prevcache, &cur)) != 0) |
176 |
{ |
177 |
Msg(0, "Could not get ccache cursor: %s", error_message(ret)); |
178 |
krb5_cc_destroy(context, ccache); |
179 |
krb5_cc_close(context, prevcache); |
180 |
krb5_free_context(context); |
181 |
return(-1); |
182 |
} |
183 |
while(!krb5_cc_next_cred(context, prevcache, &cur, &creds)) |
184 |
{ |
185 |
if((ret = krb5_cc_store_cred(context, ccache, &creds)) != 0) |
186 |
{ |
187 |
Msg(0, "Could not store credential: %s", error_message(ret)); |
188 |
krb5_cc_destroy(context, ccache); |
189 |
krb5_cc_close(context, prevcache); |
190 |
krb5_free_context(context); |
191 |
return(-1); |
192 |
} |
193 |
} |
194 |
krb5_cc_end_seq_get(context, prevcache, &cur); |
195 |
|
196 |
krb5_free_principal(context, myprinc); |
197 |
krb5_cc_close(context, prevcache); |
198 |
xsetenv("KRB5CCNAME", buf); |
199 |
MakeNewEnv(); |
200 |
memset(&renewev, 0, sizeof(renewev)); |
201 |
renewev.type = EV_TIMEOUT; |
202 |
renewev.handler = krb_renew; |
203 |
SetTimeout(&renewev, 60000); |
204 |
evenq(&renewev); |
205 |
usingkrb = 1; |
206 |
return(0); |
207 |
} |
208 |
|
209 |
void |
210 |
krb_cleanup() |
211 |
{ |
212 |
if(!usingkrb) |
213 |
return; |
214 |
krb5_cc_destroy(context, ccache); |
215 |
krb5_free_context(context); |
216 |
} |
217 |
|
218 |
#endif |