1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | #include <krb5/krb5.h> |
25 | #include <errno(*__errno_location ()).h> |
26 | |
27 | #include "krb5_authdata_int.h" |
28 | #include "sss_cli.h" |
29 | |
30 | |
31 | struct sssd_context { |
32 | krb5_data data; |
33 | }; |
34 | |
35 | static krb5_error_code |
36 | sssdpac_init(krb5_context kcontext, void **plugin_context) |
37 | { |
38 | *plugin_context = NULL((void*)0); |
39 | return 0; |
40 | } |
41 | |
42 | static void |
43 | sssdpac_flags(krb5_context kcontext, |
44 | void *plugin_context, |
45 | krb5_authdatatype ad_type, |
46 | krb5_flags *flags) |
47 | { |
48 | *flags = AD_USAGE_KDC_ISSUED0x08 | AD_USAGE_TGS_REQ0x02; |
49 | } |
50 | |
51 | static void |
52 | sssdpac_fini(krb5_context kcontext, void *plugin_context) |
53 | { |
54 | return; |
55 | } |
56 | |
57 | static krb5_error_code |
58 | sssdpac_request_init(krb5_context kcontext, |
59 | krb5_authdata_context context, |
60 | void *plugin_context, |
61 | void **request_context) |
62 | { |
63 | struct sssd_context *sssdctx; |
64 | |
65 | sssdctx = (struct sssd_context *)calloc(1, sizeof(*sssdctx)); |
66 | if (sssdctx == NULL((void*)0)) { |
67 | return ENOMEM12; |
68 | } |
69 | |
70 | *request_context = sssdctx; |
71 | |
72 | return 0; |
73 | } |
74 | |
75 | static krb5_error_code |
76 | sssdpac_import_authdata(krb5_context kcontext, |
77 | krb5_authdata_context context, |
78 | void *plugin_context, |
79 | void *request_context, |
80 | krb5_authdata **authdata, |
81 | krb5_boolean kdc_issued, |
82 | krb5_const_principal kdc_issuer) |
83 | { |
84 | char *data = NULL((void*)0); |
85 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
86 | |
87 | if (authdata[0] == NULL((void*)0)) { |
88 | return EINVAL22; |
89 | } |
90 | |
91 | if (authdata[0]->length > 0) { |
92 | data = malloc(sizeof(char) * authdata[0]->length); |
93 | if (data == NULL((void*)0)) { |
94 | return ENOMEM12; |
95 | } |
96 | memcpy(data, authdata[0]->contents, authdata[0]->length); |
97 | } |
98 | |
99 | if (sssdctx->data.data != NULL((void*)0)) { |
100 | krb5_free_data_contents(kcontext, &sssdctx->data); |
101 | } |
102 | |
103 | sssdctx->data.length = authdata[0]->length; |
104 | sssdctx->data.data = data; |
105 | return 0; |
106 | } |
107 | |
108 | static void |
109 | sssdpac_request_fini(krb5_context kcontext, |
110 | krb5_authdata_context context, |
111 | void *plugin_context, |
112 | void *request_context) |
113 | { |
114 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
115 | |
116 | if (sssdctx != NULL((void*)0)) { |
117 | if (sssdctx->data.data != NULL((void*)0)) { |
118 | krb5_free_data_contents(kcontext, &sssdctx->data); |
119 | } |
120 | |
121 | free(sssdctx); |
122 | } |
123 | } |
124 | |
125 | static krb5_error_code sssdpac_verify(krb5_context kcontext, |
126 | krb5_authdata_context context, |
127 | void *plugin_context, |
128 | void *request_context, |
129 | const krb5_auth_context *auth_context, |
130 | const krb5_keyblock *key, |
131 | const krb5_ap_req *req) |
132 | { |
133 | krb5_error_code kerr; |
134 | int ret; |
135 | krb5_pac pac; |
136 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
137 | struct sss_cli_req_data sss_data; |
138 | int errnop; |
139 | |
140 | if (sssdctx == NULL((void*)0) || sssdctx->data.data == NULL((void*)0)) { |
141 | return EINVAL22; |
142 | } |
143 | |
144 | kerr = krb5_pac_parse(kcontext, sssdctx->data.data, |
145 | sssdctx->data.length, &pac); |
146 | if (kerr != 0) { |
147 | return EINVAL22; |
148 | } |
149 | |
150 | kerr = krb5_pac_verify(kcontext, pac, |
151 | req->ticket->enc_part2->times.authtime, |
152 | req->ticket->enc_part2->client, key, NULL((void*)0)); |
153 | if (kerr != 0) { |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | |
162 | |
163 | return 0; |
164 | } |
165 | |
166 | sss_data.len = sssdctx->data.length; |
167 | sss_data.data = sssdctx->data.data; |
168 | |
169 | ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data, |
170 | NULL((void*)0), NULL((void*)0), &errnop); |
171 | if (ret != 0) { |
172 | |
173 | } |
174 | |
175 | return 0; |
176 | } |
177 | |
178 | static krb5_error_code |
179 | sssdpac_size(krb5_context kcontext, |
180 | krb5_authdata_context context, |
181 | void *plugin_context, |
182 | void *request_context, |
183 | size_t *sizep) |
184 | { |
185 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
186 | |
187 | *sizep += sizeof(krb5_int32); |
188 | |
189 | *sizep += sssdctx->data.length; |
190 | |
191 | *sizep += sizeof(krb5_int32); |
192 | |
193 | return 0; |
194 | } |
195 | |
196 | static krb5_error_code |
197 | sssdpac_externalize(krb5_context kcontext, |
198 | krb5_authdata_context context, |
199 | void *plugin_context, |
200 | void *request_context, |
201 | krb5_octet **buffer, |
202 | size_t *lenremain) |
203 | { |
204 | krb5_error_code code = 0; |
205 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
206 | size_t required = 0; |
207 | krb5_octet *bp; |
208 | size_t remain; |
209 | |
210 | bp = *buffer; |
211 | remain = *lenremain; |
212 | |
213 | if (sssdctx->data.data != NULL((void*)0)) { |
214 | sssdpac_size(kcontext, context, plugin_context, |
215 | request_context, &required); |
216 | |
217 | if (required <= remain) { |
218 | krb5_ser_pack_int32((krb5_int32)sssdctx->data.length, |
219 | &bp, &remain); |
220 | krb5_ser_pack_bytes((krb5_octet *)sssdctx->data.data, |
221 | (size_t)sssdctx->data.length, |
222 | &bp, &remain); |
223 | krb5_ser_pack_int32(0, |
224 | &bp, &remain); |
225 | } else { |
226 | code = ENOMEM12; |
227 | } |
228 | } else { |
229 | krb5_ser_pack_int32(0, &bp, &remain); |
230 | krb5_ser_pack_int32(0, &bp, &remain); |
231 | } |
232 | |
233 | *buffer = bp; |
234 | *lenremain = remain; |
235 | |
236 | return code; |
237 | } |
238 | |
239 | static krb5_error_code |
240 | sssdpac_internalize(krb5_context kcontext, |
241 | krb5_authdata_context context, |
242 | void *plugin_context, |
243 | void *request_context, |
244 | krb5_octet **buffer, |
245 | size_t *lenremain) |
246 | { |
247 | struct sssd_context *sssdctx = (struct sssd_context *)request_context; |
248 | krb5_error_code code; |
249 | krb5_int32 ibuf; |
250 | krb5_octet *bp; |
251 | size_t remain; |
252 | krb5_data data; |
253 | |
254 | bp = *buffer; |
255 | remain = *lenremain; |
256 | |
257 | |
258 | code = krb5_ser_unpack_int32(&ibuf, &bp, &remain); |
259 | if (code != 0) { |
| 1 | Assuming 'code' is equal to 0 | |
|
| |
260 | return code; |
261 | } |
262 | |
263 | if (ibuf != 0) { |
| 3 | | Assuming 'ibuf' is not equal to 0 | |
|
| |
264 | |
265 | data.length = ibuf; |
266 | data.data = malloc(sizeof(char) * ibuf); |
| |
267 | if (data.data == NULL((void*)0)) { |
| |
268 | return ENOMEM12; |
269 | } |
270 | memcpy(data.data, bp, ibuf); |
271 | |
272 | bp += ibuf; |
273 | remain -= ibuf; |
274 | } else { |
275 | data.length = 0; |
276 | data.data = NULL((void*)0); |
277 | } |
278 | |
279 | |
280 | code = krb5_ser_unpack_int32(&ibuf, &bp, &remain); |
281 | if (code != 0) { |
| 7 | | Assuming 'code' is not equal to 0 | |
|
| |
282 | return code; |
| 9 | | Potential leak of memory pointed to by 'data.data' |
|
283 | } |
284 | |
285 | if (sssdctx->data.data != NULL((void*)0)) { |
286 | krb5_free_data_contents(kcontext, &sssdctx->data); |
287 | } |
288 | |
289 | sssdctx->data.length = data.length; |
290 | sssdctx->data.data = data.data; |
291 | |
292 | *buffer = bp; |
293 | *lenremain = remain; |
294 | |
295 | return 0; |
296 | } |
297 | |
298 | static krb5_authdatatype sssdpac_ad_types[] = { KRB5_AUTHDATA_WIN2K_PAC128, 0 }; |
299 | |
300 | krb5plugin_authdata_client_ftable_v0 authdata_client_0 = { |
301 | ((void *)((uintptr_t)("sssd_sssdpac"))), |
302 | sssdpac_ad_types, |
303 | sssdpac_init, |
304 | sssdpac_fini, |
305 | sssdpac_flags, |
306 | sssdpac_request_init, |
307 | sssdpac_request_fini, |
308 | NULL((void*)0), |
309 | NULL((void*)0), |
310 | NULL((void*)0), |
311 | NULL((void*)0), |
312 | NULL((void*)0), |
313 | sssdpac_import_authdata, |
314 | NULL((void*)0), |
315 | NULL((void*)0), |
316 | sssdpac_verify, |
317 | sssdpac_size, |
318 | sssdpac_externalize, |
319 | sssdpac_internalize, |
320 | NULL((void*)0) |
321 | }; |