~ilya-yanok/ubuntu/precise/grub2/fix-for-948716

« back to all changes in this revision

Viewing changes to normal/auth.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Millan
  • Date: 2009-07-25 19:00:53 UTC
  • mfrom: (1.6.3 upstream)
  • mto: (17.4.13 sid)
  • mto: This revision was merged to the branch mainline in revision 53.
  • Revision ID: james.westby@ubuntu.com-20090725190053-uv3lm6ya3zxs77ep
ImportĀ upstreamĀ versionĀ 1.96+20090725

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  GRUB  --  GRand Unified Bootloader
3
 
 *  Copyright (C) 2009  Free Software Foundation, Inc.
4
 
 *
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.
9
 
 *
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.
14
 
 *
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/>.
17
 
 */
18
 
 
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
 
 
26
 
struct grub_auth_user
27
 
{
28
 
  struct grub_auth_user *next;
29
 
  char *name;
30
 
  grub_auth_callback_t callback;
31
 
  void *arg;
32
 
  int authenticated;
33
 
};
34
 
 
35
 
struct grub_auth_user *users = NULL;
36
 
 
37
 
int
38
 
grub_auth_strcmp (const char *user_input, const char *template)
39
 
{
40
 
  int ok = 1;
41
 
  const char *ptr1, *ptr2;
42
 
  for (ptr1 = user_input, ptr2 = template; *ptr1; ptr1++)
43
 
    if (*ptr1 == (ptr2 ? *ptr2 : ptr1[1]) && ok && ptr2 != NULL)
44
 
      ptr2++;
45
 
    else
46
 
      ok = 0;
47
 
 
48
 
  return !ok;
49
 
}
50
 
 
51
 
static int
52
 
grub_iswordseparator (int c)
53
 
{
54
 
  return (grub_isspace (c) || c == ',' || c == ';' || c == '|' || c == '&');
55
 
}
56
 
 
57
 
int
58
 
grub_auth_strword (const char *haystack, const char *needle)
59
 
{
60
 
  const char *n_pos = needle;
61
 
  int found = 0;
62
 
 
63
 
  while (grub_iswordseparator (*haystack))
64
 
    haystack++;
65
 
 
66
 
  while (*haystack)
67
 
    {
68
 
      int ok = 1;
69
 
      /* Crawl both the needle and the haystack word we're on.  */
70
 
      while(*haystack && !grub_iswordseparator (*haystack))
71
 
        {
72
 
          if (*haystack == *n_pos && ok)
73
 
            n_pos++;
74
 
          else
75
 
            ok = 0;
76
 
 
77
 
          haystack++;
78
 
        }
79
 
 
80
 
      if (ok)
81
 
        found = 1;
82
 
    }
83
 
 
84
 
  return found;
85
 
}
86
 
 
87
 
grub_err_t
88
 
grub_auth_register_authentication (const char *user,
89
 
                                   grub_auth_callback_t callback,
90
 
                                   void *arg)
91
 
{
92
 
  struct grub_auth_user *cur;
93
 
 
94
 
  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
95
 
  if (!cur)
96
 
    cur = grub_zalloc (sizeof (*cur));
97
 
  if (!cur)
98
 
    return grub_errno;
99
 
  cur->callback = callback;
100
 
  cur->arg = arg;
101
 
  if (! cur->name)
102
 
    {
103
 
      cur->name = grub_strdup (user);
104
 
      if (!cur->name)
105
 
        {
106
 
          grub_free (cur);
107
 
          return grub_errno;
108
 
        }
109
 
      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
110
 
    }
111
 
  return GRUB_ERR_NONE;
112
 
}
113
 
 
114
 
grub_err_t
115
 
grub_auth_unregister_authentication (const char *user)
116
 
{
117
 
  struct grub_auth_user *cur;
118
 
  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
119
 
  if (!cur)
120
 
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
121
 
  if (!cur->authenticated)
122
 
    {
123
 
      grub_free (cur->name);
124
 
      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
125
 
      grub_free (cur);
126
 
    }
127
 
  else
128
 
    {
129
 
      cur->callback = NULL;
130
 
      cur->arg = NULL;
131
 
    }
132
 
  return GRUB_ERR_NONE;
133
 
}
134
 
 
135
 
grub_err_t
136
 
grub_auth_authenticate (const char *user)
137
 
{
138
 
  struct grub_auth_user *cur;
139
 
 
140
 
  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
141
 
  if (!cur)
142
 
    cur = grub_zalloc (sizeof (*cur));
143
 
  if (!cur)
144
 
    return grub_errno;
145
 
 
146
 
  cur->authenticated = 1;
147
 
 
148
 
  if (! cur->name)
149
 
    {
150
 
      cur->name = grub_strdup (user);
151
 
      if (!cur->name)
152
 
        {
153
 
          grub_free (cur);
154
 
          return grub_errno;
155
 
        }
156
 
      grub_list_push (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
157
 
    }
158
 
 
159
 
  return GRUB_ERR_NONE;
160
 
}
161
 
 
162
 
grub_err_t
163
 
grub_auth_deauthenticate (const char *user)
164
 
{
165
 
  struct grub_auth_user *cur;
166
 
  cur = grub_named_list_find (GRUB_AS_NAMED_LIST (users), user);
167
 
  if (!cur)
168
 
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "user '%s' not found", user);
169
 
  if (!cur->callback)
170
 
    {
171
 
      grub_free (cur->name);
172
 
      grub_list_remove (GRUB_AS_LIST_P (&users), GRUB_AS_LIST (cur));
173
 
      grub_free (cur);
174
 
    }
175
 
  else
176
 
    cur->authenticated = 0;
177
 
  return GRUB_ERR_NONE;
178
 
}
179
 
 
180
 
static int
181
 
is_authenticated (const char *userlist)
182
 
{
183
 
  const char *superusers;
184
 
 
185
 
  auto int hook (grub_list_t item);
186
 
  int hook (grub_list_t item)
187
 
  {
188
 
    const char *name;
189
 
    if (!((struct grub_auth_user *) item)->authenticated)
190
 
      return 0;
191
 
    name = ((struct grub_auth_user *) item)->name;
192
 
 
193
 
    return (userlist && grub_auth_strword (userlist, name))
194
 
      || grub_auth_strword (superusers, name);
195
 
  }
196
 
 
197
 
  superusers = grub_env_get ("superusers");
198
 
 
199
 
  if (!superusers)
200
 
    return 1;
201
 
 
202
 
  return grub_list_iterate (GRUB_AS_LIST (users), hook);
203
 
}
204
 
 
205
 
grub_err_t
206
 
grub_auth_check_authentication (const char *userlist)
207
 
{
208
 
  char login[1024];
209
 
  struct grub_auth_user *cur = NULL;
210
 
  grub_err_t err;
211
 
 
212
 
  auto int hook (grub_list_t item);
213
 
  int hook (grub_list_t item)
214
 
  {
215
 
    if (grub_auth_strcmp (login, ((struct grub_auth_user *) item)->name) == 0)
216
 
      cur = (struct grub_auth_user *) item;
217
 
    return 0;
218
 
  }
219
 
 
220
 
  auto int hook_any (grub_list_t item);
221
 
  int hook_any (grub_list_t item)
222
 
  {
223
 
    if (((struct grub_auth_user *) item)->callback)
224
 
      cur = (struct grub_auth_user *) item;
225
 
    return 0;
226
 
  }
227
 
 
228
 
  grub_memset (login, 0, sizeof (login));
229
 
 
230
 
  if (is_authenticated (userlist))
231
 
    return GRUB_ERR_NONE;
232
 
 
233
 
  if (!grub_cmdline_get ("Enter username: ", login, sizeof (login) - 1,
234
 
                         0, 0, 0))
235
 
    return GRUB_ACCESS_DENIED;
236
 
 
237
 
  grub_list_iterate (GRUB_AS_LIST (users), hook);
238
 
 
239
 
  if (!cur || ! cur->callback)
240
 
    {
241
 
      grub_list_iterate (GRUB_AS_LIST (users), hook_any);
242
 
 
243
 
      /* No users present at all.  */
244
 
      if (!cur)
245
 
        return GRUB_ACCESS_DENIED;
246
 
 
247
 
      /* Display any of available authentication schemes.  */
248
 
      err = cur->callback (login, 0);
249
 
 
250
 
      return GRUB_ACCESS_DENIED;
251
 
    }
252
 
  err = cur->callback (login, cur->arg);
253
 
  if (is_authenticated (userlist))
254
 
    return GRUB_ERR_NONE;
255
 
  return GRUB_ACCESS_DENIED;
256
 
}