2 * Copyright (c) 2005,2006 Secure Endpoints Inc.
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 /* supported API versions */
32 #define AFS_PLUGIN_VERSION_MIN 0x00000001
33 #define AFS_PLUGIN_VERSION_MAX AFS_PLUGIN_VERSION
35 #define MAX_EXTENSIONS 8
37 afs_extension extensions
[MAX_EXTENSIONS
];
38 khm_size n_extensions
= 0;
39 khm_int32 next_method_id
= AFS_TOKEN_USER
;
41 /* not threadsafe. should only be called from the plugin thread */
43 afs_add_extension(afs_msg_announce
* ann
) {
50 if (ann
->cbsize
!= sizeof(afs_msg_announce
) ||
51 FAILED(StringCbLength(ann
->name
, KHUI_MAXCB_NAME
, &cbname
)) ||
53 (ann
->provide_token_acq
&&
54 ((FAILED(StringCbLength(ann
->token_acq
.short_desc
,
55 KHUI_MAXCB_SHORT_DESC
,
57 (ann
->token_acq
.long_desc
&&
58 FAILED(StringCbLength(ann
->token_acq
.long_desc
,
61 ann
->version
< AFS_PLUGIN_VERSION_MIN
||
62 ann
->version
> AFS_PLUGIN_VERSION_MAX
)
64 return KHM_ERROR_INVALID_PARAM
;
66 if (n_extensions
== MAX_EXTENSIONS
)
67 return KHM_ERROR_NO_RESOURCES
;
69 cbname
+= sizeof(wchar_t);
70 cbtashort
+= sizeof(wchar_t);
71 cbtalong
+= sizeof(wchar_t);
73 ext
= &extensions
[n_extensions
];
77 tmp
= PMALLOC(cbname
);
81 StringCbCopy(tmp
, cbname
, ann
->name
);
84 if (ann
->provide_token_acq
) {
85 tmp
= PMALLOC(cbtashort
);
89 StringCbCopy(tmp
, cbtashort
, ann
->token_acq
.short_desc
);
90 ext
->token_acq
.short_desc
= tmp
;
92 if (ann
->token_acq
.long_desc
) {
93 tmp
= PMALLOC(cbtalong
);
97 StringCbCopy(tmp
, cbtalong
,
98 ann
->token_acq
.long_desc
);
99 ext
->token_acq
.long_desc
= tmp
;
101 ext
->token_acq
.long_desc
= NULL
;
104 ann
->token_acq
.method_id
= next_method_id
++;
105 ext
->token_acq
.method_id
= ann
->token_acq
.method_id
;
107 ZeroMemory(&ext
->token_acq
, sizeof(ext
->token_acq
));
112 return KHM_ERROR_SUCCESS
;
116 afs_free_extension(khm_int32 idx
) {
120 assert(idx
>= 0 && idx
< (khm_int32
) n_extensions
);
123 ext
= &extensions
[idx
];
126 PFREE((void *) ext
->name
);
127 if (ext
->token_acq
.short_desc
)
128 PFREE((void *) ext
->token_acq
.short_desc
);
129 if (ext
->token_acq
.long_desc
)
130 PFREE((void *) ext
->token_acq
.long_desc
);
132 kmq_delete_subscription(ext
->sub
);
134 ZeroMemory(ext
, sizeof(*ext
));
137 /* not thread safe. only call from plugin thread */
139 afs_remove_extension(khm_int32 idx
) {
140 if (idx
< 0 || idx
> (khm_int32
) n_extensions
)
143 afs_free_extension(idx
);
145 if (idx
== n_extensions
-1) {
148 MoveMemory(&extensions
[idx
], &extensions
[idx
+ 1],
149 (n_extensions
- (idx
+1)) * sizeof(*extensions
));
153 /* not thread safe. only call from the plugin thread */
155 afs_find_extension(const wchar_t * name
) {
158 for (i
=0; i
< n_extensions
; i
++) {
159 if (extensions
[i
].name
&&
160 !wcscmp(extensions
[i
].name
, name
))
161 return &extensions
[i
];
167 /* not thread safe. only call from the plugin thread */
169 afs_is_valid_method_id(afs_tk_method method
) {
172 if (method
== AFS_TOKEN_AUTO
||
173 method
== AFS_TOKEN_KRB5
||
174 method
== AFS_TOKEN_KRB524
||
175 method
== AFS_TOKEN_KRB4
)
178 for (i
=0; i
< n_extensions
; i
++) {
179 if (extensions
[i
].provide_token_acq
&&
180 extensions
[i
].token_acq
.method_id
== method
)
188 afs_method_describe(afs_tk_method method
, khm_int32 flags
,
189 wchar_t * wbuf
, khm_size cbbuf
) {
194 return LoadString(hResModule
,
195 ((flags
& KCDB_TS_SHORT
)?
197 IDS_NC_METHODL_AUTO
),
198 wbuf
, (int) cbbuf
/ sizeof(wchar_t));
201 return LoadString(hResModule
,
202 ((flags
& KCDB_TS_SHORT
)?
204 IDS_NC_METHODL_KRB5
),
205 wbuf
, (int) cbbuf
/ sizeof(wchar_t));
207 case AFS_TOKEN_KRB524
:
208 return LoadString(hResModule
,
209 ((flags
& KCDB_TS_SHORT
)?
210 IDS_NC_METHOD_KRB524
:
211 IDS_NC_METHODL_KRB524
),
212 wbuf
, (int) cbbuf
/ sizeof(wchar_t));
215 return LoadString(hResModule
,
216 ((flags
& KCDB_TS_SHORT
)?
218 IDS_NC_METHODL_KRB4
),
219 wbuf
, (int) cbbuf
/ sizeof(wchar_t));
222 for (idx
= 0; idx
< n_extensions
; idx
++) {
223 if(!extensions
[idx
].provide_token_acq
||
224 extensions
[idx
].token_acq
.method_id
!= method
)
227 if ((flags
& KCDB_TS_SHORT
) ||
228 extensions
[idx
].token_acq
.long_desc
== NULL
)
229 return SUCCEEDED(StringCbCopy(wbuf
, cbbuf
,
230 extensions
[idx
].token_acq
.short_desc
));
232 return SUCCEEDED(StringCbCopy(wbuf
, cbbuf
,
233 extensions
[idx
].token_acq
.long_desc
));
241 afs_get_next_method_id(afs_tk_method method
) {
246 return AFS_TOKEN_AUTO
;
248 return AFS_TOKEN_KRB5
;
250 return AFS_TOKEN_KRB524
;
251 case AFS_TOKEN_KRB524
:
252 return AFS_TOKEN_KRB4
;
257 for(idx
= 0; idx
< n_extensions
; idx
++) {
258 if (extensions
[idx
].provide_token_acq
&&
259 extensions
[idx
].token_acq
.method_id
== method
)
265 for(; idx
< n_extensions
; idx
++) {
266 if (extensions
[idx
].provide_token_acq
)
267 return extensions
[idx
].token_acq
.method_id
;
273 /* not thread safe. only call from the plugin thread */
275 afs_get_next_token_acq(afs_extension
* f
) {
281 idx
= (f
- extensions
) + 1;
283 for(; idx
< n_extensions
; idx
++) {
284 if (extensions
[idx
].provide_token_acq
)
285 return &extensions
[idx
];
292 afs_get_extension(khm_size i
) {
293 if (i
>= n_extensions
)
296 return &extensions
[i
];
300 afs_get_method_id(wchar_t * name
) {
301 if (!wcscmp(name
, AFS_TOKENNAME_AUTO
))
302 return AFS_TOKEN_AUTO
;
303 else if (!wcscmp(name
, AFS_TOKENNAME_KRB5
))
304 return AFS_TOKEN_KRB5
;
305 else if (!wcscmp(name
, AFS_TOKENNAME_KRB524
))
306 return AFS_TOKEN_KRB524
;
307 else if (!wcscmp(name
, AFS_TOKENNAME_KRB4
))
308 return AFS_TOKEN_KRB4
;
312 for (i
=0; i
< n_extensions
; i
++) {
313 if (!extensions
[i
].provide_token_acq
)
316 if (!wcscmp(extensions
[i
].name
, name
))
317 return extensions
[i
].token_acq
.method_id
;
321 return AFS_TOKEN_AUTO
;
325 afs_get_method_name(afs_tk_method method
, wchar_t * buf
, khm_size cbbuf
) {
326 if (method
== AFS_TOKEN_AUTO
)
327 return SUCCEEDED(StringCbCopy(buf
, cbbuf
, AFS_TOKENNAME_AUTO
));
328 else if (method
== AFS_TOKEN_KRB5
)
329 return SUCCEEDED(StringCbCopy(buf
, cbbuf
, AFS_TOKENNAME_KRB5
));
330 else if (method
== AFS_TOKEN_KRB524
)
331 return SUCCEEDED(StringCbCopy(buf
, cbbuf
, AFS_TOKENNAME_KRB524
));
332 else if (method
== AFS_TOKEN_KRB4
)
333 return SUCCEEDED(StringCbCopy(buf
, cbbuf
, AFS_TOKENNAME_KRB4
));
337 for (i
=0; i
< n_extensions
; i
++) {
338 if (!extensions
[i
].provide_token_acq
)
340 if (extensions
[i
].token_acq
.method_id
== method
)
341 return SUCCEEDED(StringCbCopy(buf
, cbbuf
,
342 extensions
[i
].name
));
349 /* not thread safe. only call from the plugin thread */
351 afs_ext_resolve_token(const wchar_t * cell
,
352 const struct ktc_token
* token
,
353 const struct ktc_principal
* serverp
,
354 const struct ktc_principal
* clientp
,
356 afs_tk_method
* pmethod
) {
358 afs_msg_resolve_token rt
;
362 ZeroMemory(&rt
, sizeof(rt
));
364 rt
.cbsize
= sizeof(rt
);
368 rt
.serverp
= serverp
;
369 rt
.clientp
= clientp
;
370 rt
.method
= AFS_TOKEN_AUTO
;
373 for (idx
= 0; idx
< n_extensions
; idx
++) {
374 if (!extensions
[idx
].provide_token_acq
)
377 rv
= kmq_send_sub_msg(extensions
[idx
].sub
,
379 AFS_MSG_RESOLVE_TOKEN
,
383 if (KHM_SUCCEEDED(rv
)) {
384 assert(rt
.ident
!= NULL
);
387 *pmethod
= rt
.method
;
396 /* not thread safe. only call from the plugin thread */
398 afs_ext_klog(afs_tk_method method
,
400 const char * service
,
403 const afs_conf_cell
* cell_config
,
404 khm_int32 lifetime
) {
407 khm_int32 rv
= KHM_ERROR_GENERAL
;
409 afs_conf_cell cellconfig
;
411 ZeroMemory(&msg
, sizeof(msg
));
412 ZeroMemory(&cellconfig
, sizeof(cellconfig
));
414 msg
.cbsize
= sizeof(msg
);
416 msg
.identity
= identity
;
417 msg
.service
= service
;
420 msg
.lifetime
= lifetime
;
422 msg
.cell_config
= &cellconfig
;
424 cellconfig
= *cell_config
;
425 cellconfig
.cbsize
= sizeof(cellconfig
);
427 for (idx
= 0; idx
< n_extensions
; idx
++) {
428 if (!extensions
[idx
].provide_token_acq
||
429 (method
!= AFS_TOKEN_AUTO
&&
430 extensions
[idx
].token_acq
.method_id
!= method
))
433 rv
= kmq_send_sub_msg(extensions
[idx
].sub
,
439 if (KHM_SUCCEEDED(rv
))
447 afs_msg_ext(khm_int32 msg_subtype
, khm_ui_4 uparam
, void * vparam
) {
448 switch(msg_subtype
) {
449 case AFS_MSG_ANNOUNCE
:
450 return afs_add_extension((afs_msg_announce
*) vparam
);
453 return KHM_ERROR_SUCCESS
;