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>
22 #include <grub/misc.h>
24 #include <grub/normal.h>
25 #include <grub/time.h>
26 #include <grub/i18n.h>
30 struct grub_auth_user
*next
;
31 struct grub_auth_user
**prev
;
33 grub_auth_callback_t callback
;
38 static struct grub_auth_user
*users
= NULL
;
41 grub_auth_register_authentication (const char *user
,
42 grub_auth_callback_t callback
,
45 struct grub_auth_user
*cur
;
47 cur
= grub_named_list_find (GRUB_AS_NAMED_LIST (users
), user
);
49 cur
= grub_zalloc (sizeof (*cur
));
52 cur
->callback
= callback
;
56 cur
->name
= grub_strdup (user
);
62 grub_list_push (GRUB_AS_LIST_P (&users
), GRUB_AS_LIST (cur
));
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
);
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
));
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
);
95 cur
= grub_zalloc (sizeof (*cur
));
99 cur
->authenticated
= 1;
103 cur
->name
= grub_strdup (user
);
109 grub_list_push (GRUB_AS_LIST_P (&users
), GRUB_AS_LIST (cur
));
112 return GRUB_ERR_NONE
;
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
);
121 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "user '%s' not found", user
);
124 grub_free (cur
->name
);
125 grub_list_remove (GRUB_AS_LIST (cur
));
129 cur
->authenticated
= 0;
130 return GRUB_ERR_NONE
;
134 is_authenticated (const char *userlist
)
136 const char *superusers
;
137 struct grub_auth_user
*user
;
139 superusers
= grub_env_get ("superusers");
144 FOR_LIST_ELEMENTS (user
, users
)
146 if (!(user
->authenticated
))
149 if ((userlist
&& grub_strword (userlist
, user
->name
))
150 || grub_strword (superusers
, user
->name
))
158 grub_username_get (char buf
[], unsigned buf_size
)
160 unsigned cur_len
= 0;
165 key
= grub_getkey ();
166 if (key
== '\n' || key
== '\r')
182 if (!grub_isprint (key
))
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
);
197 return (key
!= '\e');
201 grub_auth_check_authentication (const char *userlist
)
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))
222 grub_puts_ (N_("Enter password: "));
224 if (!grub_password_get (entered
, GRUB_AUTH_MAX_PASSLEN
))
227 FOR_LIST_ELEMENTS (user
, users
)
229 if (grub_strcmp (login
, user
->name
) == 0)
233 if (!cur
|| ! cur
->callback
)
236 cur
->callback (login
, entered
, cur
->arg
);
237 if (is_authenticated (userlist
))
239 punishment_delay
= 1;
240 return GRUB_ERR_NONE
;
244 grub_sleep (punishment_delay
);
246 if (punishment_delay
< GRUB_ULONG_MAX
/ 2)
247 punishment_delay
*= 2;
249 return GRUB_ACCESS_DENIED
;
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
;
262 grub_normal_auth_init (void)
264 cmd
= grub_register_command ("authenticate",
265 grub_cmd_authenticate
,
267 N_("Check whether user is in USERLIST."));
272 grub_normal_auth_fini (void)
274 grub_unregister_command (cmd
);