]> git.proxmox.com Git - grub2.git/blame - grub-core/commands/legacycfg.c
Clarify and unify messages.
[grub2.git] / grub-core / commands / legacycfg.c
CommitLineData
092fd48a
VS
1/*
2 * GRUB -- GRand Unified Bootloader
a37376e7 3 * Copyright (C) 2000, 2001, 2010 Free Software Foundation, Inc.
092fd48a
VS
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/types.h>
20#include <grub/misc.h>
21#include <grub/command.h>
22#include <grub/mm.h>
23#include <grub/err.h>
24#include <grub/dl.h>
25#include <grub/file.h>
092fd48a
VS
26#include <grub/normal.h>
27#include <grub/script_sh.h>
28#include <grub/i18n.h>
68cc4355 29#include <grub/term.h>
fff175c7 30#include <grub/legacy_parse.h>
a37376e7
VS
31#include <grub/crypto.h>
32#include <grub/auth.h>
64ad6157
VS
33#include <grub/disk.h>
34#include <grub/partition.h>
092fd48a 35
e745cf0c
VS
36GRUB_MOD_LICENSE ("GPLv3+");
37
092fd48a
VS
38static grub_err_t
39legacy_file (const char *filename)
40{
41 grub_file_t file;
42 char *entryname = NULL, *entrysrc = NULL;
43 grub_menu_t menu;
6c6850ae
VS
44 char *suffix = grub_strdup ("");
45
46 auto grub_err_t getline (char **line, int cont);
47 grub_err_t getline (char **line,
48 int cont __attribute__ ((unused)))
49 {
50 *line = 0;
51 return GRUB_ERR_NONE;
52 }
53
54 if (!suffix)
55 return grub_errno;
092fd48a 56
bd960307 57 file = grub_file_open (filename);
092fd48a
VS
58 if (! file)
59 return grub_errno;
60
61 menu = grub_env_get_menu ();
62 if (! menu)
63 {
64 menu = grub_zalloc (sizeof (*menu));
65 if (! menu)
66 return grub_errno;
67
68 grub_env_set_menu (menu);
69 }
70
71 while (1)
72 {
73 char *buf = grub_file_getline (file);
64ad6157 74 char *parsed = NULL;
092fd48a
VS
75
76 if (!buf && grub_errno)
77 {
78 grub_file_close (file);
79 return grub_errno;
80 }
81
82 if (!buf)
83 break;
84
85 {
86 char *oldname = NULL;
e64334df 87 char *newsuffix;
47a77af5
VS
88 char *ptr;
89
90 for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
092fd48a
VS
91
92 oldname = entryname;
47a77af5
VS
93 parsed = grub_legacy_parse (ptr, &entryname, &newsuffix);
94 grub_free (buf);
64ad6157 95 buf = NULL;
e64334df 96 if (newsuffix)
6c6850ae
VS
97 {
98 char *t;
99
100 t = suffix;
101 suffix = grub_realloc (suffix, grub_strlen (suffix)
e64334df 102 + grub_strlen (newsuffix) + 1);
6c6850ae
VS
103 if (!suffix)
104 {
105 grub_free (t);
106 grub_free (entrysrc);
107 grub_free (parsed);
e64334df 108 grub_free (newsuffix);
6c6850ae
VS
109 grub_free (suffix);
110 return grub_errno;
111 }
e64334df
VS
112 grub_memcpy (suffix + grub_strlen (suffix), newsuffix,
113 grub_strlen (newsuffix) + 1);
114 grub_free (newsuffix);
115 newsuffix = NULL;
6c6850ae 116 }
092fd48a
VS
117 if (oldname != entryname && oldname)
118 {
119 const char **args = grub_malloc (sizeof (args[0]));
120 if (!args)
121 {
122 grub_file_close (file);
123 return grub_errno;
124 }
125 args[0] = oldname;
bd960307 126 grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
fc55cc4c 127 entrysrc, 0);
64ad6157
VS
128 grub_free (args);
129 entrysrc[0] = 0;
130 grub_free (oldname);
092fd48a
VS
131 }
132 }
133
134 if (parsed && !entryname)
135 {
092fd48a 136 grub_normal_parse_line (parsed, getline);
67cb07a3 137 grub_print_error ();
092fd48a 138 grub_free (parsed);
64ad6157 139 parsed = NULL;
092fd48a
VS
140 }
141 else if (parsed)
142 {
143 if (!entrysrc)
144 entrysrc = parsed;
145 else
146 {
147 char *t;
148
149 t = entrysrc;
150 entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
151 + grub_strlen (parsed) + 1);
152 if (!entrysrc)
153 {
154 grub_free (t);
155 grub_free (parsed);
6c6850ae 156 grub_free (suffix);
092fd48a
VS
157 return grub_errno;
158 }
68cc4355 159 grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed,
092fd48a
VS
160 grub_strlen (parsed) + 1);
161 grub_free (parsed);
162 parsed = NULL;
163 }
164 }
165 }
166 grub_file_close (file);
167
168 if (entryname)
169 {
170 const char **args = grub_malloc (sizeof (args[0]));
171 if (!args)
172 {
173 grub_file_close (file);
174 return grub_errno;
175 }
176 args[0] = entryname;
fc55cc4c 177 grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0);
64ad6157 178 grub_free (args);
092fd48a
VS
179 }
180
6c6850ae
VS
181 grub_normal_parse_line (suffix, getline);
182 grub_print_error ();
183 grub_free (suffix);
64ad6157 184 grub_free (entrysrc);
6c6850ae 185
092fd48a
VS
186 return GRUB_ERR_NONE;
187}
188
189static grub_err_t
57f20e67 190grub_cmd_legacy_source (struct grub_command *cmd,
092fd48a
VS
191 int argc, char **args)
192{
57f20e67 193 int new_env, extractor;
092fd48a 194 grub_err_t ret;
57f20e67 195
092fd48a
VS
196 if (argc != 1)
197 return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
198
57f20e67 199 extractor = (cmd->name[0] == 'e');
f1808884
VS
200 new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1)
201 : (sizeof ("legacy_") - 1)] == 'c');
57f20e67
VS
202
203 if (new_env)
204 grub_cls ();
205
206 if (new_env && !extractor)
207 grub_env_context_open ();
208 if (extractor)
209 grub_env_extractor_open (!new_env);
092fd48a
VS
210
211 ret = legacy_file (args[0]);
57f20e67 212
f1808884
VS
213 if (new_env)
214 {
215 grub_menu_t menu;
216 menu = grub_env_get_menu ();
217 if (menu && menu->size)
dcb883b1 218 grub_show_menu (menu, 1, 0);
f1808884
VS
219 if (!extractor)
220 grub_env_context_close ();
221 }
57f20e67
VS
222 if (extractor)
223 grub_env_extractor_close (!new_env);
092fd48a
VS
224
225 return ret;
226}
227
8fc6a271
VS
228static enum
229 {
230 GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD
231 } kernel_type;
232
233static grub_err_t
234grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
235 int argc, char **args)
236{
237 int i;
6bdda8f8 238#ifdef TODO
8fc6a271 239 int no_mem_option = 0;
6bdda8f8 240#endif
8fc6a271 241 struct grub_command *cmd;
9fb175ed
VS
242 char **cutargs;
243 int cutargc;
64ad6157 244
8fc6a271
VS
245 for (i = 0; i < 2; i++)
246 {
247 /* FIXME: really support this. */
248 if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0)
249 {
6bdda8f8 250#ifdef TODO
8fc6a271 251 no_mem_option = 1;
6bdda8f8 252#endif
8fc6a271
VS
253 argc--;
254 args++;
255 continue;
256 }
257
2a87d7d1 258 /* linux16 handles both zImages and bzImages. */
8fc6a271
VS
259 if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0
260 || grub_strcmp (args[0], "--type=biglinux") == 0))
261 {
262 kernel_type = LINUX;
263 argc--;
264 args++;
265 continue;
266 }
267
268 if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0)
269 {
270 kernel_type = MULTIBOOT;
271 argc--;
272 args++;
273 continue;
274 }
275
276 if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0)
277 {
278 kernel_type = KFREEBSD;
279 argc--;
280 args++;
281 continue;
282 }
283
284 if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0)
285 {
286 kernel_type = KOPENBSD;
287 argc--;
288 args++;
289 continue;
290 }
291
292 if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0)
293 {
294 kernel_type = KNETBSD;
295 argc--;
296 args++;
297 continue;
298 }
299 }
300
9fb175ed 301 if (argc < 2)
8fc6a271
VS
302 return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
303
bd960307 304 cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
9fb175ed 305 cutargc = argc - 1;
bd960307 306 grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
9fb175ed
VS
307 cutargs[0] = args[0];
308
8fc6a271
VS
309 do
310 {
311 /* First try Linux. */
312 if (kernel_type == GUESS_IT || kernel_type == LINUX)
313 {
314 cmd = grub_command_find ("linux16");
315 if (cmd)
316 {
9fb175ed 317 if (!(cmd->func) (cmd, cutargc, cutargs))
8fc6a271
VS
318 {
319 kernel_type = LINUX;
320 return GRUB_ERR_NONE;
321 }
322 }
323 grub_errno = GRUB_ERR_NONE;
324 }
325
326 /* Then multiboot. */
8fc6a271
VS
327 if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT)
328 {
329 cmd = grub_command_find ("multiboot");
330 if (cmd)
331 {
332 if (!(cmd->func) (cmd, argc, args))
333 {
334 kernel_type = MULTIBOOT;
335 return GRUB_ERR_NONE;
336 }
337 }
338 grub_errno = GRUB_ERR_NONE;
339 }
340
64ad6157
VS
341 {
342 int bsd_device = -1;
343 int bsd_slice = -1;
344 int bsd_part = -1;
8fc6a271 345 {
64ad6157 346 grub_device_t dev;
d35d0d37 347 const char *hdbiasstr;
64ad6157
VS
348 int hdbias = 0;
349 hdbiasstr = grub_env_get ("legacy_hdbias");
350 if (hdbiasstr)
8fc6a271 351 {
64ad6157
VS
352 hdbias = grub_strtoul (hdbiasstr, 0, 0);
353 grub_errno = GRUB_ERR_NONE;
354 }
355 dev = grub_device_open (0);
356 if (dev && dev->disk
357 && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID
358 && dev->disk->dev->id >= 0x80 && dev->disk->dev->id <= 0x90)
359 {
360 struct grub_partition *part = dev->disk->partition;
361 bsd_device = dev->disk->id - 0x80 - hdbias;
362 if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0
363 || grub_strcmp (part->partmap->name, "openbsd") == 0
364 || grub_strcmp (part->partmap->name, "bsd") == 0))
8fc6a271 365 {
64ad6157
VS
366 bsd_part = part->number;
367 part = part->parent;
8fc6a271 368 }
64ad6157
VS
369 if (part && grub_strcmp (part->partmap->name, "msdos") == 0)
370 bsd_slice = part->number;
8fc6a271 371 }
8fc6a271 372 }
64ad6157
VS
373
374 /* k*BSD didn't really work well with grub-legacy. */
375 if (kernel_type == GUESS_IT || kernel_type == KFREEBSD)
376 {
377 char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")];
378 if (bsd_device != -1)
379 {
380 if (bsd_slice != -1 && bsd_part != -1)
381 grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device,
382 bsd_slice, 'a' + bsd_part);
383 else if (bsd_slice != -1)
384 grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device,
385 bsd_slice);
386 else
387 grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device);
388 grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf);
389 }
390 else
391 grub_env_unset ("kFreeBSD.vfs.root.mountfrom");
392 cmd = grub_command_find ("kfreebsd");
393 if (cmd)
394 {
395 if (!(cmd->func) (cmd, cutargc, cutargs))
396 {
397 kernel_type = KFREEBSD;
398 return GRUB_ERR_NONE;
399 }
400 }
401 grub_errno = GRUB_ERR_NONE;
402 }
8fc6a271 403 {
64ad6157
VS
404 char **bsdargs;
405 int bsdargc;
406 char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
407 if (bsd_device == -1)
8fc6a271 408 {
64ad6157
VS
409 bsdargs = cutargs;
410 bsdargc = cutargc;
411 }
412 else
413 {
414 bsdargc = cutargc + 2;
415 bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
416 grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
417 bsdargs[argc] = "-r";
418 bsdargs[argc + 1] = bsddevname;
419 grub_snprintf (bsddevname, sizeof (bsddevname),
420 "wd%d%c", bsd_device,
421 bsd_part != -1 ? bsd_part + 'a' : 'c');
422 }
423 if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
424 {
425 cmd = grub_command_find ("knetbsd");
426 if (cmd)
8fc6a271 427 {
64ad6157
VS
428 if (!(cmd->func) (cmd, bsdargc, bsdargs))
429 {
430 kernel_type = KNETBSD;
431 return GRUB_ERR_NONE;
432 }
8fc6a271 433 }
64ad6157 434 grub_errno = GRUB_ERR_NONE;
8fc6a271 435 }
64ad6157 436 if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
8fc6a271 437 {
64ad6157
VS
438 cmd = grub_command_find ("kopenbsd");
439 if (cmd)
8fc6a271 440 {
64ad6157
VS
441 if (!(cmd->func) (cmd, bsdargc, bsdargs))
442 {
443 kernel_type = KOPENBSD;
444 return GRUB_ERR_NONE;
445 }
8fc6a271 446 }
64ad6157 447 grub_errno = GRUB_ERR_NONE;
8fc6a271 448 }
64ad6157
VS
449 if (bsdargs != cutargs)
450 grub_free (bsdargs);
8fc6a271 451 }
64ad6157 452 }
8fc6a271
VS
453 }
454 while (0);
455
456 return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s\n",
457 args[0]);
458}
459
460static grub_err_t
461grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)),
462 int argc, char **args)
463{
464 struct grub_command *cmd;
465
466 if (kernel_type == LINUX)
467 {
468 cmd = grub_command_find ("initrd16");
469 if (!cmd)
470 return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found");
471
472 return cmd->func (cmd, argc, args);
473 }
474 if (kernel_type == MULTIBOOT)
475 {
8fc6a271
VS
476 cmd = grub_command_find ("module");
477 if (!cmd)
478 return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found");
479
480 return cmd->func (cmd, argc, args);
481 }
482
483 return grub_error (GRUB_ERR_BAD_ARGUMENT,
484 "no kernel with module support is loaded in legacy way");
485}
486
237a43b1
VS
487static grub_err_t
488grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)),
489 int argc, char **args)
490{
491 struct grub_command *cmd;
492
493 if (kernel_type == LINUX)
494 {
495 cmd = grub_command_find ("initrd16");
496 if (!cmd)
497 return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found");
498
499 return cmd->func (cmd, argc, args);
500 }
501 if (kernel_type == MULTIBOOT)
502 {
503 char **newargs;
504 grub_err_t err;
505 newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
506 if (!newargs)
507 return grub_errno;
508 grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
509 newargs[0] = "--nounzip";
510 cmd = grub_command_find ("module");
511 if (!cmd)
512 return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found");
513
514 err = cmd->func (cmd, argc + 1, newargs);
515 grub_free (newargs);
516 return err;
517 }
518
519 return grub_error (GRUB_ERR_BAD_ARGUMENT,
520 "no kernel with module support is loaded in legacy way");
521}
522
a37376e7
VS
523static grub_err_t
524check_password_deny (const char *user __attribute__ ((unused)),
525 const char *entered __attribute__ ((unused)),
526 void *password __attribute__ ((unused)))
527{
528 return GRUB_ACCESS_DENIED;
529}
530
531#define MD5_HASHLEN 16
532
533struct legacy_md5_password
534{
535 grub_uint8_t *salt;
536 int saltlen;
537 grub_uint8_t hash[MD5_HASHLEN];
538};
539
540static int
541check_password_md5_real (const char *entered,
542 struct legacy_md5_password *pw)
543{
544 int enteredlen = grub_strlen (entered);
545 unsigned char alt_result[MD5_HASHLEN];
546 unsigned char *digest;
547 grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
548 int i;
549
550 GRUB_MD_MD5->init (ctx);
551 GRUB_MD_MD5->write (ctx, entered, enteredlen);
552 GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
553 GRUB_MD_MD5->write (ctx, entered, enteredlen);
554 digest = GRUB_MD_MD5->read (ctx);
555 GRUB_MD_MD5->final (ctx);
556 memcpy (alt_result, digest, MD5_HASHLEN);
557
558 GRUB_MD_MD5->init (ctx);
559 GRUB_MD_MD5->write (ctx, entered, enteredlen);
560 GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */
561 for (i = enteredlen; i > 16; i -= 16)
562 GRUB_MD_MD5->write (ctx, alt_result, 16);
563 GRUB_MD_MD5->write (ctx, alt_result, i);
564
565 for (i = enteredlen; i > 0; i >>= 1)
566 GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1);
567 digest = GRUB_MD_MD5->read (ctx);
568 GRUB_MD_MD5->final (ctx);
569
570 for (i = 0; i < 1000; i++)
571 {
572 memcpy (alt_result, digest, 16);
573
574 GRUB_MD_MD5->init (ctx);
575 if ((i & 1) != 0)
576 GRUB_MD_MD5->write (ctx, entered, enteredlen);
577 else
578 GRUB_MD_MD5->write (ctx, alt_result, 16);
579
580 if (i % 3 != 0)
581 GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
582
583 if (i % 7 != 0)
584 GRUB_MD_MD5->write (ctx, entered, enteredlen);
585
586 if ((i & 1) != 0)
587 GRUB_MD_MD5->write (ctx, alt_result, 16);
588 else
589 GRUB_MD_MD5->write (ctx, entered, enteredlen);
590 digest = GRUB_MD_MD5->read (ctx);
591 GRUB_MD_MD5->final (ctx);
592 }
593
594 return (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0);
595}
596
597static grub_err_t
598check_password_md5 (const char *user,
599 const char *entered,
600 void *password)
601{
602 if (!check_password_md5_real (entered, password))
603 return GRUB_ACCESS_DENIED;
604
605 grub_auth_authenticate (user);
606
607 return GRUB_ERR_NONE;
608}
609
610static inline int
611ib64t (char c)
612{
613 if (c == '.')
614 return 0;
615 if (c == '/')
616 return 1;
617 if (c >= '0' && c <= '9')
618 return c - '0' + 2;
619 if (c >= 'A' && c <= 'Z')
620 return c - 'A' + 12;
621 if (c >= 'a' && c <= 'z')
622 return c - 'a' + 38;
623 return -1;
624}
625
e2830452
VS
626static struct legacy_md5_password *
627parse_legacy_md5 (int argc, char **args)
a37376e7
VS
628{
629 const char *salt, *saltend;
a37376e7
VS
630 struct legacy_md5_password *pw = NULL;
631 int i;
e2830452 632 const char *p;
a37376e7 633
a37376e7
VS
634 if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0)
635 goto fail;
636 if (argc == 1)
637 goto fail;
638 if (grub_strlen(args[1]) <= 3)
639 goto fail;
640 salt = args[1];
641 saltend = grub_strchr (salt + 3, '$');
642 if (!saltend)
643 goto fail;
644 pw = grub_malloc (sizeof (*pw));
645 if (!pw)
646 goto fail;
647
648 p = saltend + 1;
649 for (i = 0; i < 5; i++)
650 {
651 int n;
652 grub_uint32_t w = 0;
653
654 for (n = 0; n < 4; n++)
655 {
656 int ww = ib64t(*p++);
657 if (ww == -1)
658 goto fail;
659 w |= ww << (n * 6);
660 }
661 pw->hash[i == 4 ? 5 : 12+i] = w & 0xff;
662 pw->hash[6+i] = (w >> 8) & 0xff;
663 pw->hash[i] = (w >> 16) & 0xff;
664 }
665 {
666 int n;
667 grub_uint32_t w = 0;
668 for (n = 0; n < 2; n++)
669 {
670 int ww = ib64t(*p++);
671 if (ww == -1)
672 goto fail;
673 w |= ww << (6 * n);
674 }
675 if (w >= 0x100)
676 goto fail;
677 pw->hash[11] = w;
678 }
679
680 pw->saltlen = saltend - salt;
681 pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen);
682 if (!pw->salt)
683 goto fail;
684
e2830452 685 return pw;
a37376e7
VS
686
687 fail:
688 grub_free (pw);
e2830452
VS
689 return NULL;
690}
691
692static grub_err_t
693grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)),
694 int argc, char **args)
695{
696 struct legacy_md5_password *pw = NULL;
697
698 if (argc == 0)
699 return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
700 if (args[0][0] != '-' || args[0][1] != '-')
701 return grub_normal_set_password ("legacy", args[0]);
702
703 pw = parse_legacy_md5 (argc, args);
704
705 if (pw)
706 return grub_auth_register_authentication ("legacy", check_password_md5, pw);
707 else
708 /* This is to imitate minor difference between grub-legacy in GRUB2.
709 If 2 password commands are executed in a row and second one fails
710 on GRUB2 the password of first one is used, whereas in grub-legacy
711 authenthication is denied. In case of no password command was executed
712 early both versions deny any access. */
713 return grub_auth_register_authentication ("legacy", check_password_deny,
714 NULL);
715}
716
717static grub_err_t
718grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)),
719 int argc, char **args)
720{
721 struct legacy_md5_password *pw = NULL;
722 char entered[GRUB_AUTH_MAX_PASSLEN];
723
724 if (argc == 0)
725 return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
6e0632e2 726 grub_puts_ (N_("Enter password: "));
e2830452
VS
727 if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
728 return GRUB_ACCESS_DENIED;
729
730 if (args[0][0] != '-' || args[0][1] != '-')
731 {
732 char correct[GRUB_AUTH_MAX_PASSLEN];
733
734 grub_memset (correct, 0, sizeof (correct));
735 grub_strncpy (correct, args[0], sizeof (correct));
736
737 if (grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) != 0)
738 return GRUB_ACCESS_DENIED;
739 return GRUB_ERR_NONE;
740 }
741
742 pw = parse_legacy_md5 (argc, args);
743
744 if (!pw)
745 return GRUB_ACCESS_DENIED;
746
747 if (!check_password_md5_real (entered, pw))
748 return GRUB_ACCESS_DENIED;
749
750 return GRUB_ERR_NONE;
a37376e7
VS
751}
752
57f20e67
VS
753static grub_command_t cmd_source, cmd_configfile;
754static grub_command_t cmd_source_extract, cmd_configfile_extract;
755static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip;
756static grub_command_t cmd_password, cmd_check_password;
092fd48a
VS
757
758GRUB_MOD_INIT(legacycfg)
759{
57f20e67
VS
760 cmd_source
761 = grub_register_command ("legacy_source",
762 grub_cmd_legacy_source,
763 N_("FILE"),
764 N_("Parse legacy config in same context"));
765 cmd_configfile
766 = grub_register_command ("legacy_configfile",
767 grub_cmd_legacy_source,
768 N_("FILE"),
769 N_("Parse legacy config in new context"));
770 cmd_source_extract
771 = grub_register_command ("extract_legacy_entries_source",
772 grub_cmd_legacy_source,
773 N_("FILE"),
5b1bdf12 774 N_("Parse legacy config in same context taking only menu entries"));
57f20e67
VS
775 cmd_configfile_extract
776 = grub_register_command ("extract_legacy_entries_configfile",
777 grub_cmd_legacy_source,
778 N_("FILE"),
5b1bdf12 779 N_("Parse legacy config in new context taking only menu entries"));
281d6905 780
8fc6a271
VS
781 cmd_kernel = grub_register_command ("legacy_kernel",
782 grub_cmd_legacy_kernel,
783 N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"),
b525fd83 784 N_("Simulate grub-legacy `kernel' command"));
8fc6a271
VS
785
786 cmd_initrd = grub_register_command ("legacy_initrd",
787 grub_cmd_legacy_initrd,
788 N_("FILE [ARG ...]"),
b525fd83 789 N_("Simulate grub-legacy `initrd' command"));
237a43b1
VS
790 cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip",
791 grub_cmd_legacy_initrdnounzip,
792 N_("FILE [ARG ...]"),
b525fd83 793 N_("Simulate grub-legacy `modulenounzip' command"));
237a43b1 794
a37376e7
VS
795 cmd_password = grub_register_command ("legacy_password",
796 grub_cmd_legacy_password,
797 N_("[--md5] PASSWD [FILE]"),
b525fd83 798 N_("Simulate grub-legacy `password' command"));
e2830452
VS
799
800 cmd_check_password = grub_register_command ("legacy_check_password",
801 grub_cmd_legacy_check_password,
802 N_("[--md5] PASSWD [FILE]"),
b525fd83 803 N_("Simulate grub-legacy `password' command in menuentry mode"));
e2830452 804
092fd48a
VS
805}
806
807GRUB_MOD_FINI(legacycfg)
808{
809 grub_unregister_command (cmd_source);
810 grub_unregister_command (cmd_configfile);
57f20e67
VS
811 grub_unregister_command (cmd_source_extract);
812 grub_unregister_command (cmd_configfile_extract);
813
8fc6a271
VS
814 grub_unregister_command (cmd_kernel);
815 grub_unregister_command (cmd_initrd);
237a43b1 816 grub_unregister_command (cmd_initrdnounzip);
57f20e67 817
a37376e7 818 grub_unregister_command (cmd_password);
e2830452 819 grub_unregister_command (cmd_check_password);
092fd48a 820}