Try and get a lock on the semaphore, if not then just move on as some housekeeping...
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / normal / auth.c
blobc6bd96e28ec28a6906791e8461ee8ea41387b436
1 /*
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2009 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19 #include <grub/auth.h>
20 #include <grub/list.h>
21 #include <grub/mm.h>
22 #include <grub/misc.h>
23 #include <grub/env.h>
24 #include <grub/normal.h>
25 #include <grub/time.h>
26 #include <grub/i18n.h>
28 struct grub_auth_user
30 struct grub_auth_user *next;
31 struct grub_auth_user **prev;
32 char *name;
33 grub_auth_callback_t callback;
34 void *arg;
35 int authenticated;
38 static struct grub_auth_user *users = NULL;
40 grub_err_t
41 grub_auth_register_authentication (const char *user,
42 grub_auth_callback_t callback,
43 void *arg)
45 struct grub_auth_user *cur;
47 cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
48 if (!cur)
49 cur = grub_zalloc (sizeof (*cur));
50 if (!cur)
51 return grub_errno;
52 cur->callback = callback;
53 cur->arg = arg;
54 if (! cur->name)
56 cur->name = grub_strdup (user);
57 if (!cur->name)
59 grub_free (cur);
60 return grub_errno;
62 grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
64 return GRUB_ERR_NONE;
67 grub_err_t
68 grub_auth_unregister_authentication (const char *user)
70 struct grub_auth_user *cur;
71 cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
72 if (!cur)
73 return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
74 if (!cur->authenticated)
76 grub_free (cur->name);
77 grub_list_remove (GRUB_AS_LIST (cur));
78 grub_free (cur);
80 else
82 cur->callback = NULL;
83 cur->arg = NULL;
85 return GRUB_ERR_NONE;
88 grub_err_t
89 grub_auth_authenticate (const char *user)
91 struct grub_auth_user *cur;
93 cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
94 if (!cur)
95 cur = grub_zalloc (sizeof (*cur));
96 if (!cur)
97 return grub_errno;
99 cur->authenticated = 1;
101 if (! cur->name)
103 cur->name = grub_strdup (user);
104 if (!cur->name)
106 grub_free (cur);
107 return grub_errno;
109 grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
112 return GRUB_ERR_NONE;
115 grub_err_t
116 grub_auth_deauthenticate (const char *user)
118 struct grub_auth_user *cur;
119 cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
120 if (!cur)
121 return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
122 if (!cur->callback)
124 grub_free (cur->name);
125 grub_list_remove (GRUB_AS_LIST (cur));
126 grub_free (cur);
128 else
129 cur->authenticated = 0;
130 return GRUB_ERR_NONE;
133 static int
134 is_authenticated (const char *userlist)
136 const char *superusers;
137 struct grub_auth_user *user;
139 superusers = grub_env_get ("superusers");
141 if (!superusers)
142 return 1;
144 FOR_LIST_ELEMENTS (user, users)
146 if (!(user->authenticated))
147 continue;
149 if ((userlist && grub_strword (userlist, user->name))
150 || grub_strword (superusers, user->name))
151 return 1;
154 return 0;
157 static int
158 grub_username_get (char buf[], unsigned buf_size)
160 unsigned cur_len = 0;
161 int key;
163 while (1)
165 key = grub_getkey ();
166 if (key == '\n' || key == '\r')
167 break;
169 if (key == '\e')
171 cur_len = 0;
172 break;
175 if (key == '\b')
177 cur_len--;
178 grub_printf ("\b");
179 continue;
182 if (!grub_isprint (key))
183 continue;
185 if (cur_len + 2 < buf_size)
187 buf[cur_len++] = key;
188 grub_printf ("%c", key);
192 grub_memset (buf + cur_len, 0, buf_size - cur_len);
194 grub_xputs ("\n");
195 grub_refresh ();
197 return (key != '\e');
200 grub_err_t
201 grub_auth_check_authentication (const char *userlist)
203 char login[1024];
204 struct grub_auth_user *cur = NULL;
205 static unsigned long punishment_delay = 1;
206 char entered[GRUB_AUTH_MAX_PASSLEN];
207 struct grub_auth_user *user;
209 grub_memset (login, 0, sizeof (login));
211 if (is_authenticated (userlist))
213 punishment_delay = 1;
214 return GRUB_ERR_NONE;
217 grub_puts_ (N_("Enter username: "));
219 if (!grub_username_get (login, sizeof (login) - 1))
220 goto access_denied;
222 grub_puts_ (N_("Enter password: "));
224 if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
225 goto access_denied;
227 FOR_LIST_ELEMENTS (user, users)
229 if (grub_strcmp (login, user->name) == 0)
230 cur = user;
233 if (!cur || ! cur->callback)
234 goto access_denied;
236 cur->callback (login, entered, cur->arg);
237 if (is_authenticated (userlist))
239 punishment_delay = 1;
240 return GRUB_ERR_NONE;
243 access_denied:
244 grub_sleep (punishment_delay);
246 if (punishment_delay < GRUB_ULONG_MAX / 2)
247 punishment_delay *= 2;
249 return GRUB_ACCESS_DENIED;
252 static grub_err_t
253 grub_cmd_authenticate (struct grub_command *cmd __attribute__ ((unused)),
254 int argc, char **args)
256 return grub_auth_check_authentication ((argc >= 1) ? args[0] : "");
259 static grub_command_t cmd;
261 void
262 grub_normal_auth_init (void)
264 cmd = grub_register_command ("authenticate",
265 grub_cmd_authenticate,
266 N_("[USERLIST]"),
267 N_("Check whether user is in USERLIST."));
271 void
272 grub_normal_auth_fini (void)
274 grub_unregister_command (cmd);