[PATCH] USB: ioctl compat for usblp.c
[linux-2.6/mini2440.git] / security / keys / request_key.c
blob5cc4bba70db61eab5157bb0bb7ffe6b673a11ab3
1 /* request_key.c: request a key from userspace
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * See Documentation/keys-request-key.txt
14 #include <linux/module.h>
15 #include <linux/sched.h>
16 #include <linux/kmod.h>
17 #include <linux/err.h>
18 #include <linux/keyctl.h>
19 #include "internal.h"
21 struct key_construction {
22 struct list_head link; /* link in construction queue */
23 struct key *key; /* key being constructed */
26 /* when waiting for someone else's keys, you get added to this */
27 DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
29 /*****************************************************************************/
31 * request userspace finish the construction of a key
32 * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
34 static int call_request_key(struct key *key,
35 const char *op,
36 const char *callout_info)
38 struct task_struct *tsk = current;
39 key_serial_t prkey, sskey;
40 struct key *session_keyring, *rkakey;
41 char *argv[10], *envp[3], uid_str[12], gid_str[12];
42 char key_str[12], keyring_str[3][12];
43 int ret, i;
45 kenter("{%d},%s,%s", key->serial, op, callout_info);
47 /* generate a new session keyring with an auth key in it */
48 session_keyring = request_key_auth_new(key, &rkakey);
49 if (IS_ERR(session_keyring)) {
50 ret = PTR_ERR(session_keyring);
51 goto error;
54 /* record the UID and GID */
55 sprintf(uid_str, "%d", current->fsuid);
56 sprintf(gid_str, "%d", current->fsgid);
58 /* we say which key is under construction */
59 sprintf(key_str, "%d", key->serial);
61 /* we specify the process's default keyrings */
62 sprintf(keyring_str[0], "%d",
63 tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
65 prkey = 0;
66 if (tsk->signal->process_keyring)
67 prkey = tsk->signal->process_keyring->serial;
69 sprintf(keyring_str[1], "%d", prkey);
71 if (tsk->signal->session_keyring) {
72 rcu_read_lock();
73 sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
74 rcu_read_unlock();
76 else {
77 sskey = tsk->user->session_keyring->serial;
80 sprintf(keyring_str[2], "%d", sskey);
82 /* set up a minimal environment */
83 i = 0;
84 envp[i++] = "HOME=/";
85 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
86 envp[i] = NULL;
88 /* set up the argument list */
89 i = 0;
90 argv[i++] = "/sbin/request-key";
91 argv[i++] = (char *) op;
92 argv[i++] = key_str;
93 argv[i++] = uid_str;
94 argv[i++] = gid_str;
95 argv[i++] = keyring_str[0];
96 argv[i++] = keyring_str[1];
97 argv[i++] = keyring_str[2];
98 argv[i++] = (char *) callout_info;
99 argv[i] = NULL;
101 /* do it */
102 ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
104 /* dispose of the special keys */
105 key_revoke(rkakey);
106 key_put(rkakey);
107 key_put(session_keyring);
109 error:
110 kleave(" = %d", ret);
111 return ret;
113 } /* end call_request_key() */
115 /*****************************************************************************/
117 * call out to userspace for the key
118 * - called with the construction sem held, but the sem is dropped here
119 * - we ignore program failure and go on key status instead
121 static struct key *__request_key_construction(struct key_type *type,
122 const char *description,
123 const char *callout_info)
125 struct key_construction cons;
126 struct timespec now;
127 struct key *key;
128 int ret, negated;
130 kenter("%s,%s,%s", type->name, description, callout_info);
132 /* create a key and add it to the queue */
133 key = key_alloc(type, description,
134 current->fsuid, current->fsgid, KEY_POS_ALL, 0);
135 if (IS_ERR(key))
136 goto alloc_failed;
138 set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
140 cons.key = key;
141 list_add_tail(&cons.link, &key->user->consq);
143 /* we drop the construction sem here on behalf of the caller */
144 up_write(&key_construction_sem);
146 /* make the call */
147 ret = call_request_key(key, "create", callout_info);
148 if (ret < 0)
149 goto request_failed;
151 /* if the key wasn't instantiated, then we want to give an error */
152 ret = -ENOKEY;
153 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154 goto request_failed;
156 down_write(&key_construction_sem);
157 list_del(&cons.link);
158 up_write(&key_construction_sem);
160 /* also give an error if the key was negatively instantiated */
161 check_not_negative:
162 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
163 key_put(key);
164 key = ERR_PTR(-ENOKEY);
167 out:
168 kleave(" = %p", key);
169 return key;
171 request_failed:
172 /* it wasn't instantiated
173 * - remove from construction queue
174 * - mark the key as dead
176 negated = 0;
177 down_write(&key_construction_sem);
179 list_del(&cons.link);
181 /* check it didn't get instantiated between the check and the down */
182 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
183 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
184 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
185 negated = 1;
188 clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
190 up_write(&key_construction_sem);
192 if (!negated)
193 goto check_not_negative; /* surprisingly, the key got
194 * instantiated */
196 /* set the timeout and store in the session keyring if we can */
197 now = current_kernel_time();
198 key->expiry = now.tv_sec + key_negative_timeout;
200 if (current->signal->session_keyring) {
201 struct key *keyring;
203 rcu_read_lock();
204 keyring = rcu_dereference(current->signal->session_keyring);
205 atomic_inc(&keyring->usage);
206 rcu_read_unlock();
208 key_link(keyring, key);
209 key_put(keyring);
212 key_put(key);
214 /* notify anyone who was waiting */
215 wake_up_all(&request_key_conswq);
217 key = ERR_PTR(ret);
218 goto out;
220 alloc_failed:
221 up_write(&key_construction_sem);
222 goto out;
224 } /* end __request_key_construction() */
226 /*****************************************************************************/
228 * call out to userspace to request the key
229 * - we check the construction queue first to see if an appropriate key is
230 * already being constructed by userspace
232 static struct key *request_key_construction(struct key_type *type,
233 const char *description,
234 struct key_user *user,
235 const char *callout_info)
237 struct key_construction *pcons;
238 struct key *key, *ckey;
240 DECLARE_WAITQUEUE(myself, current);
242 kenter("%s,%s,{%d},%s",
243 type->name, description, user->uid, callout_info);
245 /* see if there's such a key under construction already */
246 down_write(&key_construction_sem);
248 list_for_each_entry(pcons, &user->consq, link) {
249 ckey = pcons->key;
251 if (ckey->type != type)
252 continue;
254 if (type->match(ckey, description))
255 goto found_key_under_construction;
258 /* see about getting userspace to construct the key */
259 key = __request_key_construction(type, description, callout_info);
260 error:
261 kleave(" = %p", key);
262 return key;
264 /* someone else has the same key under construction
265 * - we want to keep an eye on their key
267 found_key_under_construction:
268 atomic_inc(&ckey->usage);
269 up_write(&key_construction_sem);
271 /* wait for the key to be completed one way or another */
272 add_wait_queue(&request_key_conswq, &myself);
274 for (;;) {
275 set_current_state(TASK_INTERRUPTIBLE);
276 if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
277 break;
278 if (signal_pending(current))
279 break;
280 schedule();
283 set_current_state(TASK_RUNNING);
284 remove_wait_queue(&request_key_conswq, &myself);
286 /* we'll need to search this process's keyrings to see if the key is
287 * now there since we can't automatically assume it's also available
288 * there */
289 key_put(ckey);
290 ckey = NULL;
292 key = NULL; /* request a retry */
293 goto error;
295 } /* end request_key_construction() */
297 /*****************************************************************************/
299 * link a freshly minted key to an appropriate destination keyring
301 static void request_key_link(struct key *key, struct key *dest_keyring)
303 struct task_struct *tsk = current;
304 struct key *drop = NULL;
306 kenter("{%d},%p", key->serial, dest_keyring);
308 /* find the appropriate keyring */
309 if (!dest_keyring) {
310 switch (tsk->jit_keyring) {
311 case KEY_REQKEY_DEFL_DEFAULT:
312 case KEY_REQKEY_DEFL_THREAD_KEYRING:
313 dest_keyring = tsk->thread_keyring;
314 if (dest_keyring)
315 break;
317 case KEY_REQKEY_DEFL_PROCESS_KEYRING:
318 dest_keyring = tsk->signal->process_keyring;
319 if (dest_keyring)
320 break;
322 case KEY_REQKEY_DEFL_SESSION_KEYRING:
323 rcu_read_lock();
324 dest_keyring = key_get(
325 rcu_dereference(tsk->signal->session_keyring));
326 rcu_read_unlock();
327 drop = dest_keyring;
329 if (dest_keyring)
330 break;
332 case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
333 dest_keyring = current->user->session_keyring;
334 break;
336 case KEY_REQKEY_DEFL_USER_KEYRING:
337 dest_keyring = current->user->uid_keyring;
338 break;
340 case KEY_REQKEY_DEFL_GROUP_KEYRING:
341 default:
342 BUG();
346 /* and attach the key to it */
347 key_link(dest_keyring, key);
349 key_put(drop);
351 kleave("");
353 } /* end request_key_link() */
355 /*****************************************************************************/
357 * request a key
358 * - search the process's keyrings
359 * - check the list of keys being created or updated
360 * - call out to userspace for a key if supplementary info was provided
361 * - cache the key in an appropriate keyring
363 struct key *request_key_and_link(struct key_type *type,
364 const char *description,
365 const char *callout_info,
366 struct key *dest_keyring)
368 struct key_user *user;
369 struct key *key;
370 key_ref_t key_ref;
372 kenter("%s,%s,%s,%p",
373 type->name, description, callout_info, dest_keyring);
375 /* search all the process keyrings for a key */
376 key_ref = search_process_keyrings(type, description, type->match,
377 current);
379 kdebug("search 1: %p", key_ref);
381 if (!IS_ERR(key_ref)) {
382 key = key_ref_to_ptr(key_ref);
384 else if (PTR_ERR(key_ref) != -EAGAIN) {
385 key = ERR_PTR(PTR_ERR(key_ref));
387 else {
388 /* the search failed, but the keyrings were searchable, so we
389 * should consult userspace if we can */
390 key = ERR_PTR(-ENOKEY);
391 if (!callout_info)
392 goto error;
394 /* - get hold of the user's construction queue */
395 user = key_user_lookup(current->fsuid);
396 if (!user)
397 goto nomem;
399 for (;;) {
400 if (signal_pending(current))
401 goto interrupted;
403 /* ask userspace (returns NULL if it waited on a key
404 * being constructed) */
405 key = request_key_construction(type, description,
406 user, callout_info);
407 if (key)
408 break;
410 /* someone else made the key we want, so we need to
411 * search again as it might now be available to us */
412 key_ref = search_process_keyrings(type, description,
413 type->match,
414 current);
416 kdebug("search 2: %p", key_ref);
418 if (!IS_ERR(key_ref)) {
419 key = key_ref_to_ptr(key_ref);
420 break;
423 if (PTR_ERR(key_ref) != -EAGAIN) {
424 key = ERR_PTR(PTR_ERR(key_ref));
425 break;
429 key_user_put(user);
431 /* link the new key into the appropriate keyring */
432 if (!IS_ERR(key))
433 request_key_link(key, dest_keyring);
436 error:
437 kleave(" = %p", key);
438 return key;
440 nomem:
441 key = ERR_PTR(-ENOMEM);
442 goto error;
444 interrupted:
445 key_user_put(user);
446 key = ERR_PTR(-EINTR);
447 goto error;
449 } /* end request_key_and_link() */
451 /*****************************************************************************/
453 * request a key
454 * - search the process's keyrings
455 * - check the list of keys being created or updated
456 * - call out to userspace for a key if supplementary info was provided
458 struct key *request_key(struct key_type *type,
459 const char *description,
460 const char *callout_info)
462 return request_key_and_link(type, description, callout_info, NULL);
464 } /* end request_key() */
466 EXPORT_SYMBOL(request_key);
468 /*****************************************************************************/
470 * validate a key
472 int key_validate(struct key *key)
474 struct timespec now;
475 int ret = 0;
477 if (key) {
478 /* check it's still accessible */
479 ret = -EKEYREVOKED;
480 if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
481 test_bit(KEY_FLAG_DEAD, &key->flags))
482 goto error;
484 /* check it hasn't expired */
485 ret = 0;
486 if (key->expiry) {
487 now = current_kernel_time();
488 if (now.tv_sec >= key->expiry)
489 ret = -EKEYEXPIRED;
493 error:
494 return ret;
496 } /* end key_validate() */
498 EXPORT_SYMBOL(key_validate);