2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2004 Marius Strobl
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
32 * Handlers for Open Firmware /options node.
35 #include <sys/types.h>
37 #include <dev/ofw/openfirm.h>
41 #include <readpassphrase.h>
48 #include "ofw_options.h"
52 #define OFWO_MAXPROP 31
55 struct ofwo_extabent {
57 int (*ex_handler)(const struct ofwo_extabent *, int,
58 const void *, int, const char *);
61 static int ofwo_oemlogo(const struct ofwo_extabent *, int, const void *,
63 static int ofwo_secmode(const struct ofwo_extabent *, int, const void *,
65 static int ofwo_secpwd(const struct ofwo_extabent *, int, const void *,
68 static const struct ofwo_extabent ofwo_extab[] = {
69 { "oem-logo", ofwo_oemlogo },
70 { "security-mode", ofwo_secmode },
71 { "security-password", ofwo_secpwd },
75 static int ofwo_setpass(int);
76 static int ofwo_setstr(int, const void *, int, const char *, const char *);
79 ofwo_printprop(const char *prop, const char* buf, int buflen)
82 printf("%s: %.*s\n", prop, buflen, buf);
86 ofwo_oemlogo(const struct ofwo_extabent *exent, int fd, const void *buf,
87 int buflen, const char *val)
90 char logo[OFWO_LOGO + 1];
94 ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop, "", 1);
96 if ((lfd = open(val, O_RDONLY)) == -1) {
97 warn("could not open '%s'", val);
100 if (read(lfd, logo, OFWO_LOGO) != OFWO_LOGO ||
101 lseek(lfd, 0, SEEK_END) != OFWO_LOGO) {
103 warnx("logo '%s' has wrong size.", val);
107 logo[OFWO_LOGO] = '\0';
108 if (ofw_setprop(fd, ofw_optnode(fd), exent->ex_prop,
109 logo, OFWO_LOGO + 1) != OFWO_LOGO)
110 errx(EX_IOERR, "writing logo failed.");
114 printf("%s: <logo data>\n", exent->ex_prop);
116 ofwo_printprop(exent->ex_prop, (const char *)buf,
122 ofwo_secmode(const struct ofwo_extabent *exent, int fd, const void *buf,
123 int buflen, const char *val)
128 if (strcmp(val, "full") == 0 || strcmp(val, "command") == 0) {
129 if ((res = ofwo_setpass(fd)) != EX_OK)
131 if ((res = ofwo_setstr(fd, buf, buflen, exent->ex_prop,
133 ofw_setprop(fd, ofw_optnode(fd),
134 "security-password", "", 1);
137 if (strcmp(val, "none") == 0) {
138 ofw_setprop(fd, ofw_optnode(fd), "security-password",
140 return (ofwo_setstr(fd, buf, buflen, exent->ex_prop,
145 ofwo_printprop(exent->ex_prop, (const char *)buf, buflen);
150 ofwo_secpwd(const struct ofwo_extabent *exent, int fd, const void *buf,
151 int buflen, const char *val)
160 len = ofw_getprop_alloc(fd, ofw_optnode(fd), "security-mode",
162 if (len <= 0 || strncmp("none", (char *)pbuf, len) == 0) {
164 warnx("no security mode set.");
165 } else if (strncmp("command", (char *)pbuf, len) == 0 ||
166 strncmp("full", (char *)pbuf, len) == 0) {
167 rv = ofwo_setpass(fd);
170 warnx("invalid security mode.");
173 ofwo_printprop(exent->ex_prop, (const char *)buf, buflen);
182 char pwd1[OFWO_MAXPWD + 1], pwd2[OFWO_MAXPWD + 1];
184 if (readpassphrase("New password:", pwd1, sizeof(pwd1),
185 RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL ||
186 readpassphrase("Retype new password:", pwd2, sizeof(pwd2),
187 RPP_ECHO_OFF | RPP_REQUIRE_TTY) == NULL)
188 errx(EX_USAGE, "failed to get password.");
189 if (strlen(pwd1) == 0) {
190 printf("Password unchanged.\n");
193 if (strcmp(pwd1, pwd2) != 0) {
194 printf("Mismatch - password unchanged.\n");
197 ofw_setprop(fd, ofw_optnode(fd), "security-password", pwd1,
203 ofwo_setstr(int fd, const void *buf, int buflen, const char *prop,
214 optnode = ofw_optnode(fd);
215 ofw_setprop(fd, optnode, prop, val, strlen(val) + 1);
216 len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1);
217 if (len < 0 || strncmp(val, (char *)pbuf, len) != 0) {
219 * The value is too long for this property and the OFW has
220 * truncated it to fit or the value is illegal and a legal
221 * one has been written instead (e.g. attempted to write
222 * "foobar" to a "true"/"false"-property) - try to recover
226 if ((oval = malloc(buflen + 1)) == NULL)
227 err(EX_OSERR, "malloc() failed.");
228 strncpy(oval, buf, buflen);
230 len = ofw_setprop(fd, optnode, prop, oval, buflen + 1);
232 errx(EX_IOERR, "recovery of old value failed.");
236 printf("%s: %.*s%s->%s%.*s\n", prop, buflen, (const char *)buf,
237 buflen > 0 ? " " : "", len > 0 ? " " : "", len, (char *)pbuf);
248 int fd, len, nlen, pblen;
250 char prop[OFWO_MAXPROP + 1];
251 const struct ofwo_extabent *ex;
255 fd = ofw_open(O_RDONLY);
256 optnode = ofw_optnode(fd);
257 for (nlen = ofw_firstprop(fd, optnode, prop, sizeof(prop)); nlen != 0;
258 nlen = ofw_nextprop(fd, optnode, prop, prop, sizeof(prop))) {
259 len = ofw_getprop_alloc(fd, optnode, prop, &pbuf, &pblen, 1);
262 if (strcmp(prop, "name") == 0)
264 for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex)
265 if (strcmp(ex->ex_prop, prop) == 0)
267 if (ex->ex_prop != NULL)
268 (*ex->ex_handler)(ex, fd, pbuf, len, NULL);
270 ofwo_printprop(prop, (char *)pbuf, len);
278 ofwo_action(const char *prop, const char *val)
281 int fd, len, pblen, rv;
282 const struct ofwo_extabent *ex;
287 if (strcmp(prop, "name") == 0)
288 return (EX_UNAVAILABLE);
290 fd = ofw_open(O_RDWR);
292 fd = ofw_open(O_RDONLY);
293 len = ofw_getprop_alloc(fd, ofw_optnode(fd), prop, &pbuf, &pblen, 1);
298 for (ex = ofwo_extab; ex->ex_prop != NULL; ++ex)
299 if (strcmp(ex->ex_prop, prop) == 0)
301 if (ex->ex_prop != NULL)
302 rv = (*ex->ex_handler)(ex, fd, pbuf, len, val);
304 rv = ofwo_setstr(fd, pbuf, len, prop, val);
306 ofwo_printprop(prop, (char *)pbuf, len);