1ae115bc7Smrj /* 2ae115bc7Smrj * Open Boot Prom eeprom utility 3*3b133becSGangadhar Mylapuram * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 4ae115bc7Smrj * Use is subject to license terms. 5ae115bc7Smrj */ 6ae115bc7Smrj 7ae115bc7Smrj /* 8ae115bc7Smrj * Copyright (c) 1983 Regents of the University of California. 9ae115bc7Smrj * All rights reserved. The Berkeley software License Agreement 10ae115bc7Smrj * specifies the terms and conditions for redistribution. 11ae115bc7Smrj */ 12ae115bc7Smrj 13ae115bc7Smrj #include <sys/types.h> 14ae115bc7Smrj #include <sys/param.h> 15ae115bc7Smrj #include <sys/openpromio.h> 16ae115bc7Smrj #include <stdio.h> 17ae115bc7Smrj #include <fcntl.h> 18ae115bc7Smrj #include <string.h> 19ae115bc7Smrj #include <errno.h> 20ae115bc7Smrj #include <stdlib.h> 21ae115bc7Smrj #include <unistd.h> 22ae115bc7Smrj 23ae115bc7Smrj /* 24ae115bc7Smrj * Usage: % eeprom [-v] [-f promdev] [-] 25ae115bc7Smrj * % eeprom [-v] [-f promdev] field[=value] ... 26ae115bc7Smrj */ 27ae115bc7Smrj 28ae115bc7Smrj /* 29ae115bc7Smrj * 128 is the size of the largest (currently) property name buffer 30ae115bc7Smrj * 8192 - MAXPROPSIZE - sizeof (int) is the size of the largest 31ae115bc7Smrj * (currently) property value, viz. nvramrc. 32ae115bc7Smrj * the sizeof(u_int) is from struct openpromio 33ae115bc7Smrj */ 34ae115bc7Smrj 35ae115bc7Smrj #define MAXPROPSIZE 128 36ae115bc7Smrj #define MAXNAMESIZE MAXPROPSIZE 37ae115bc7Smrj #define MAXVALSIZE (8192 - MAXPROPSIZE - sizeof (uint_t)) 38ae115bc7Smrj #define BUFSIZE (MAXPROPSIZE + MAXVALSIZE + sizeof (uint_t)) 39ae115bc7Smrj typedef union { 40ae115bc7Smrj char buf[BUFSIZE]; 41ae115bc7Smrj struct openpromio opp; 42ae115bc7Smrj } Oppbuf; 43ae115bc7Smrj 44ae115bc7Smrj extern int _error(int do_perror, char *fmt, ...); 45ae115bc7Smrj extern void setprogname(char *); 46ae115bc7Smrj static int get_password(char *, int); 47ae115bc7Smrj extern int loadlogo(char *, int, int, char *); 48ae115bc7Smrj 49ae115bc7Smrj #define NO_PERROR 0 50ae115bc7Smrj #define PERROR 1 51ae115bc7Smrj 52ae115bc7Smrj static int prom_fd; 53ae115bc7Smrj static char *promdev; 54ae115bc7Smrj static int verbose; 55ae115bc7Smrj 56ae115bc7Smrj static void do_var(char *); 57ae115bc7Smrj static void dump_all(); 58ae115bc7Smrj static void print_one(char *); 59ae115bc7Smrj static void set_one(char *, char *); 60ae115bc7Smrj static void promclose(); 61ae115bc7Smrj static int promopen(int); 62ae115bc7Smrj 63ae115bc7Smrj static int getpropval(struct openpromio *); 64ae115bc7Smrj static int setpropval(struct openpromio *); 65ae115bc7Smrj 66ae115bc7Smrj static char *badarchmsg = "Architecture does not support this command.\n"; 67ae115bc7Smrj 68ae115bc7Smrj typedef void (*func)(); 69ae115bc7Smrj 70ae115bc7Smrj 71ae115bc7Smrj /* We have to special-case two properties related to security */ 72ae115bc7Smrj static void i_secure(); 73ae115bc7Smrj static void i_passwd(), o_passwd(); 74ae115bc7Smrj static void i_oemlogo(); 75ae115bc7Smrj 76ae115bc7Smrj /* 77ae115bc7Smrj * It's unfortunate that we have to know the names of certain properties 78ae115bc7Smrj * in this program (the whole idea of openprom was to avoid it), but at 79ae115bc7Smrj * least we can isolate them to these defines here. 80ae115bc7Smrj */ 81ae115bc7Smrj #define PASSWORD_PROPERTY "security-password" 82ae115bc7Smrj #define MODE_PROPERTY "security-mode" 83ae115bc7Smrj #define LOGO_PROPERTY "oem-logo" 84ae115bc7Smrj #define PW_SIZE 8 85ae115bc7Smrj 86ae115bc7Smrj /* 87ae115bc7Smrj * Unlike the old-style eeprom command, where every property needed an 88ae115bc7Smrj * i_foo and an o_foo function, we only need them when the default case 89ae115bc7Smrj * isn't sufficient. 90ae115bc7Smrj */ 91ae115bc7Smrj static struct opvar { 92ae115bc7Smrj char *name; 93ae115bc7Smrj func in; 94ae115bc7Smrj func out; 95ae115bc7Smrj } opvar[] = { 96ae115bc7Smrj #define e(n, i, o) {n, i, o} 97ae115bc7Smrj e(MODE_PROPERTY, i_secure, (func)NULL), 98ae115bc7Smrj e(PASSWORD_PROPERTY, i_passwd, o_passwd), 99ae115bc7Smrj e(LOGO_PROPERTY, i_oemlogo, (func)NULL), 100ae115bc7Smrj { (char *)NULL, (func)NULL, (func)NULL} 101ae115bc7Smrj #undef e 102ae115bc7Smrj }; 103ae115bc7Smrj 104ae115bc7Smrj 105ae115bc7Smrj /* 106ae115bc7Smrj * sun4c openprom 107ae115bc7Smrj */ 108ae115bc7Smrj 109ae115bc7Smrj int 110ae115bc7Smrj main(int argc, char **argv) 111ae115bc7Smrj { 112ae115bc7Smrj int c; 113ae115bc7Smrj extern char *optarg; 114ae115bc7Smrj extern int optind; 115ae115bc7Smrj 116ae115bc7Smrj promdev = "/dev/openprom"; 117ae115bc7Smrj 118ae115bc7Smrj while ((c = getopt(argc, argv, "cif:v")) != -1) 119ae115bc7Smrj switch (c) { 120ae115bc7Smrj case 'c': 121ae115bc7Smrj case 'i': 122ae115bc7Smrj /* ignore for openprom */ 123ae115bc7Smrj break; 124ae115bc7Smrj case 'v': 125ae115bc7Smrj verbose++; 126ae115bc7Smrj break; 127ae115bc7Smrj case 'f': 128ae115bc7Smrj promdev = optarg; 129ae115bc7Smrj break; 130ae115bc7Smrj default: 131ae115bc7Smrj exit(_error(NO_PERROR, 132ae115bc7Smrj "Usage: %s [-v] [-f prom-device] " 133ae115bc7Smrj "[variable[=value] ...]", argv[0])); 134ae115bc7Smrj } 135ae115bc7Smrj 136ae115bc7Smrj setprogname(argv[0]); 137ae115bc7Smrj 138ae115bc7Smrj /* 139ae115bc7Smrj * If no arguments, dump all fields. 140ae115bc7Smrj */ 141ae115bc7Smrj if (optind >= argc) { 142ae115bc7Smrj dump_all(); 143ae115bc7Smrj exit(0); 144ae115bc7Smrj } 145ae115bc7Smrj 146ae115bc7Smrj while (optind < argc) { 147ae115bc7Smrj /* 148ae115bc7Smrj * If "-" specified, read variables from stdin. 149ae115bc7Smrj */ 150ae115bc7Smrj if (strcmp(argv[optind], "-") == 0) { 151ae115bc7Smrj int c; 152ae115bc7Smrj char *nl, line[BUFSIZE]; 153ae115bc7Smrj 154ae115bc7Smrj while (fgets(line, sizeof (line), stdin) != NULL) { 155ae115bc7Smrj /* zap newline if present */ 156ae115bc7Smrj if (nl = strchr(line, '\n')) 157ae115bc7Smrj *nl = 0; 158ae115bc7Smrj /* otherwise discard rest of line */ 159ae115bc7Smrj else 160ae115bc7Smrj while ((c = getchar()) != '\n' && 161ae115bc7Smrj c != EOF) 162ae115bc7Smrj /* nothing */; 163ae115bc7Smrj 164ae115bc7Smrj do_var(line); 165ae115bc7Smrj } 166ae115bc7Smrj clearerr(stdin); 167ae115bc7Smrj } 168ae115bc7Smrj /* 169ae115bc7Smrj * Process each argument as a variable print or set request. 170ae115bc7Smrj */ 171ae115bc7Smrj else 172ae115bc7Smrj do_var(argv[optind]); 173ae115bc7Smrj 174ae115bc7Smrj optind++; 175ae115bc7Smrj } 176ae115bc7Smrj return (0); 177ae115bc7Smrj } 178ae115bc7Smrj 179ae115bc7Smrj /* 180ae115bc7Smrj * Print or set an EEPROM field. 181ae115bc7Smrj */ 182ae115bc7Smrj static void 183ae115bc7Smrj do_var(char *var) 184ae115bc7Smrj { 185ae115bc7Smrj char *val; 186ae115bc7Smrj 187ae115bc7Smrj val = strchr(var, '='); 188ae115bc7Smrj 189ae115bc7Smrj if (val == NULL) { 190ae115bc7Smrj /* 191ae115bc7Smrj * print specific property 192ae115bc7Smrj */ 193ae115bc7Smrj if (promopen(O_RDONLY)) { 194ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 195ae115bc7Smrj exit(1); 196ae115bc7Smrj } 197ae115bc7Smrj print_one(var); 198ae115bc7Smrj } else { 199ae115bc7Smrj /* 200ae115bc7Smrj * set specific property to value 201ae115bc7Smrj */ 202ae115bc7Smrj *val++ = '\0'; 203ae115bc7Smrj 204ae115bc7Smrj if (promopen(O_RDWR)) { 205ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 206ae115bc7Smrj exit(1); 207ae115bc7Smrj } 208ae115bc7Smrj set_one(var, val); 209ae115bc7Smrj } 210ae115bc7Smrj promclose(); 211ae115bc7Smrj } 212ae115bc7Smrj 213ae115bc7Smrj /* 214ae115bc7Smrj * Print all properties and values 215ae115bc7Smrj */ 216ae115bc7Smrj static void 217ae115bc7Smrj dump_all() 218ae115bc7Smrj { 219ae115bc7Smrj Oppbuf oppbuf; 220ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 221ae115bc7Smrj 222ae115bc7Smrj if (promopen(O_RDONLY)) { 223ae115bc7Smrj (void) fprintf(stderr, badarchmsg); 224ae115bc7Smrj exit(1); 225ae115bc7Smrj } 226ae115bc7Smrj /* get first prop by asking for null string */ 227ae115bc7Smrj (void) memset(oppbuf.buf, '\0', BUFSIZE); 228ae115bc7Smrj /* CONSTCOND */ 229ae115bc7Smrj while (1) { 230ae115bc7Smrj /* 231ae115bc7Smrj * get property 232ae115bc7Smrj */ 233ae115bc7Smrj opp->oprom_size = MAXPROPSIZE; 234ae115bc7Smrj 235ae115bc7Smrj if (ioctl(prom_fd, OPROMNXTOPT, opp) < 0) 236ae115bc7Smrj exit(_error(PERROR, "OPROMNXTOPT")); 237ae115bc7Smrj 238ae115bc7Smrj if (opp->oprom_size == 0) { 239ae115bc7Smrj promclose(); 240ae115bc7Smrj return; 241ae115bc7Smrj } 242ae115bc7Smrj print_one(opp->oprom_array); 243ae115bc7Smrj } 244ae115bc7Smrj } 245ae115bc7Smrj 246ae115bc7Smrj /* 247ae115bc7Smrj * Print one property and its value. 248ae115bc7Smrj */ 249ae115bc7Smrj static void 250ae115bc7Smrj print_one(char *var) 251ae115bc7Smrj { 252ae115bc7Smrj Oppbuf oppbuf; 253ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 254*3b133becSGangadhar Mylapuram char bootargs[MAXVALSIZE]; 255*3b133becSGangadhar Mylapuram 256*3b133becSGangadhar Mylapuram if (strcmp(var, "bootcmd") == 0) { 257*3b133becSGangadhar Mylapuram opp->oprom_size = MAXVALSIZE; 258*3b133becSGangadhar Mylapuram if (ioctl(prom_fd, OPROMGETBOOTARGS, opp) < 0) { 259*3b133becSGangadhar Mylapuram (void) _error(PERROR, "OPROMGETBOOTARGS"); 260*3b133becSGangadhar Mylapuram return; 261*3b133becSGangadhar Mylapuram } 262*3b133becSGangadhar Mylapuram (void) strlcpy(bootargs, opp->oprom_array, MAXVALSIZE); 263*3b133becSGangadhar Mylapuram 264*3b133becSGangadhar Mylapuram opp->oprom_size = MAXVALSIZE; 265*3b133becSGangadhar Mylapuram if (ioctl(prom_fd, OPROMGETBOOTPATH, opp) < 0) { 266*3b133becSGangadhar Mylapuram (void) _error(PERROR, "OPROMGETBOOTPATH"); 267*3b133becSGangadhar Mylapuram return; 268*3b133becSGangadhar Mylapuram } 269*3b133becSGangadhar Mylapuram (void) printf("%s=%s %s\n", var, opp->oprom_array, bootargs); 270*3b133becSGangadhar Mylapuram return; 271*3b133becSGangadhar Mylapuram } 272ae115bc7Smrj 273ae115bc7Smrj (void) strlcpy(opp->oprom_array, var, MAXNAMESIZE); 274ae115bc7Smrj if (getpropval(opp) || opp->oprom_size <= 0) 275ae115bc7Smrj (void) printf("%s: data not available.\n", var); 276ae115bc7Smrj else { 277ae115bc7Smrj /* If necessary, massage the output */ 278ae115bc7Smrj struct opvar *v; 279ae115bc7Smrj 280ae115bc7Smrj for (v = opvar; v->name; v++) 281ae115bc7Smrj if (strcmp(var, v->name) == 0) 282ae115bc7Smrj break; 283ae115bc7Smrj 284ae115bc7Smrj if (v->name && v->out) 285ae115bc7Smrj (*v->out)(v->name, opp->oprom_array); 286ae115bc7Smrj else 287ae115bc7Smrj (void) printf("%s=%s\n", var, opp->oprom_array); 288ae115bc7Smrj } 289ae115bc7Smrj } 290ae115bc7Smrj 291ae115bc7Smrj /* 292ae115bc7Smrj * Set one property to the given value. 293ae115bc7Smrj */ 294ae115bc7Smrj static void 295ae115bc7Smrj set_one(char *var, char *val) 296ae115bc7Smrj { 297ae115bc7Smrj Oppbuf oppbuf; 298ae115bc7Smrj struct openpromio *opp = &(oppbuf.opp); 299ae115bc7Smrj struct opvar *v; 300ae115bc7Smrj 301ae115bc7Smrj if (verbose) { 302ae115bc7Smrj (void) printf("old:"); 303ae115bc7Smrj print_one(var); 304ae115bc7Smrj } 305ae115bc7Smrj 306ae115bc7Smrj /* If necessary, massage the input */ 307ae115bc7Smrj 308ae115bc7Smrj for (v = opvar; v->name; v++) 309ae115bc7Smrj if (strcmp(var, v->name) == 0) 310ae115bc7Smrj break; 311ae115bc7Smrj 312ae115bc7Smrj if (v->name && v->in) 313ae115bc7Smrj (*v->in)(v->name, val, opp); 314ae115bc7Smrj else { 315ae115bc7Smrj int varlen = strlen(var) + 1; 316ae115bc7Smrj int vallen = strlen(val); 317ae115bc7Smrj 318ae115bc7Smrj if (varlen > MAXNAMESIZE) { 319ae115bc7Smrj (void) printf("%s: invalid property.\n", var); 320ae115bc7Smrj return; 321ae115bc7Smrj } 322ae115bc7Smrj if (vallen >= MAXVALSIZE) { 323ae115bc7Smrj (void) printf("%s: invalid property value.\n", var); 324ae115bc7Smrj return; 325ae115bc7Smrj } 326ae115bc7Smrj (void) strcpy(opp->oprom_array, var); 327ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen, val); 328ae115bc7Smrj opp->oprom_size = varlen + vallen; 329ae115bc7Smrj if (setpropval(opp)) 330ae115bc7Smrj (void) printf("%s: invalid property.\n", var); 331ae115bc7Smrj } 332ae115bc7Smrj 333ae115bc7Smrj if (verbose) { 334ae115bc7Smrj (void) printf("new:"); 335ae115bc7Smrj print_one(var); 336ae115bc7Smrj } 337ae115bc7Smrj } 338ae115bc7Smrj 339ae115bc7Smrj static int 340ae115bc7Smrj promopen(int oflag) 341ae115bc7Smrj { 342ae115bc7Smrj /* CONSTCOND */ 343ae115bc7Smrj while (1) { 344ae115bc7Smrj if ((prom_fd = open(promdev, oflag)) < 0) { 345ae115bc7Smrj if (errno == EAGAIN) 346ae115bc7Smrj continue; 347ae115bc7Smrj else if (errno == ENXIO) 348ae115bc7Smrj return (-1); 349ae115bc7Smrj else 350ae115bc7Smrj exit(_error(PERROR, "cannot open %s", promdev)); 351ae115bc7Smrj } else 352ae115bc7Smrj break; 353ae115bc7Smrj } 354ae115bc7Smrj return (0); 355ae115bc7Smrj } 356ae115bc7Smrj 357ae115bc7Smrj static void 358ae115bc7Smrj promclose() 359ae115bc7Smrj { 360ae115bc7Smrj if (close(prom_fd) < 0) 361ae115bc7Smrj exit(_error(PERROR, "close error on %s", promdev)); 362ae115bc7Smrj } 363ae115bc7Smrj 364ae115bc7Smrj static int 365ae115bc7Smrj getpropval(struct openpromio *opp) 366ae115bc7Smrj { 367ae115bc7Smrj opp->oprom_size = MAXVALSIZE; 368ae115bc7Smrj 369ae115bc7Smrj if (ioctl(prom_fd, OPROMGETOPT, opp) < 0) 370ae115bc7Smrj return (_error(PERROR, "OPROMGETOPT")); 371ae115bc7Smrj 372ae115bc7Smrj return (0); 373ae115bc7Smrj } 374ae115bc7Smrj 375ae115bc7Smrj static int 376ae115bc7Smrj setpropval(struct openpromio *opp) 377ae115bc7Smrj { 378ae115bc7Smrj /* Caller must set opp->oprom_size */ 379ae115bc7Smrj 380ae115bc7Smrj if (ioctl(prom_fd, OPROMSETOPT, opp) < 0) 381ae115bc7Smrj return (_error(PERROR, "OPROMSETOPT")); 382ae115bc7Smrj return (0); 383ae115bc7Smrj } 384ae115bc7Smrj 385ae115bc7Smrj 386ae115bc7Smrj /* 387ae115bc7Smrj * The next set of functions handle the special cases. 388ae115bc7Smrj */ 389ae115bc7Smrj 390ae115bc7Smrj static void 391ae115bc7Smrj i_oemlogo(char *var, char *val, struct openpromio *opp) 392ae115bc7Smrj { 393ae115bc7Smrj int varlen = strlen(var) + 1; 394ae115bc7Smrj 395ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* safe - we know the name */ 396ae115bc7Smrj 397ae115bc7Smrj if (loadlogo(val, 64, 64, opp->oprom_array + varlen)) 398ae115bc7Smrj exit(1); 399ae115bc7Smrj opp->oprom_size = varlen + 512; 400ae115bc7Smrj if (ioctl(prom_fd, OPROMSETOPT2, opp) < 0) 401ae115bc7Smrj exit(_error(PERROR, "OPROMSETOPT2")); 402ae115bc7Smrj } 403ae115bc7Smrj 404ae115bc7Smrj /* 405ae115bc7Smrj * Set security mode. 406ae115bc7Smrj * If oldmode was none, and new mode is not none, get and set password, 407ae115bc7Smrj * too. 408ae115bc7Smrj * If old mode was not none, and new mode is none, wipe out old 409ae115bc7Smrj * password. 410ae115bc7Smrj */ 411ae115bc7Smrj static void 412ae115bc7Smrj i_secure(char *var, char *val, struct openpromio *opp) 413ae115bc7Smrj { 414ae115bc7Smrj int secure; 415ae115bc7Smrj Oppbuf oppbuf; 416ae115bc7Smrj struct openpromio *opp2 = &(oppbuf.opp); 417ae115bc7Smrj char pwbuf[PW_SIZE + 2]; 418ae115bc7Smrj int varlen1, varlen2; 419ae115bc7Smrj 420ae115bc7Smrj (void) strcpy(opp2->oprom_array, var); /* safe; we know the name */ 421ae115bc7Smrj if (getpropval(opp2) || opp2->oprom_size <= 0) { 422ae115bc7Smrj (void) printf("%s: data not available.\n", var); 423ae115bc7Smrj exit(1); 424ae115bc7Smrj } 425ae115bc7Smrj secure = strcmp(opp2->oprom_array, "none"); 426ae115bc7Smrj 427ae115bc7Smrj /* Set up opp for mode */ 428ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* safe; we know the name */ 429ae115bc7Smrj varlen1 = strlen(opp->oprom_array) + 1; 430ae115bc7Smrj if (strlen(val) > 32) { /* 32 > [ "full", "command", "none" ] */ 431ae115bc7Smrj (void) printf("Invalid security mode, mode unchanged.\n"); 432ae115bc7Smrj exit(1); 433ae115bc7Smrj } 434ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen1, val); 435ae115bc7Smrj opp->oprom_size = varlen1 + strlen(val); 436ae115bc7Smrj 437ae115bc7Smrj /* Set up opp2 for password */ 438ae115bc7Smrj (void) strcpy(opp2->oprom_array, PASSWORD_PROPERTY); 439ae115bc7Smrj varlen2 = strlen(opp2->oprom_array) + 1; 440ae115bc7Smrj 441ae115bc7Smrj if ((strcmp(val, "full") == 0) || (strcmp(val, "command") == 0)) { 442ae115bc7Smrj if (! secure) { 443ae115bc7Smrj /* no password yet, get one */ 444ae115bc7Smrj if (get_password(pwbuf, PW_SIZE)) { 445ae115bc7Smrj (void) strcpy(opp2->oprom_array + varlen2, 446ae115bc7Smrj pwbuf); 447ae115bc7Smrj opp2->oprom_size = varlen2 + strlen(pwbuf); 448ae115bc7Smrj /* set password first */ 449ae115bc7Smrj if (setpropval(opp2) || setpropval(opp)) 450ae115bc7Smrj exit(1); 451ae115bc7Smrj } else 452ae115bc7Smrj exit(1); 453ae115bc7Smrj } else { 454ae115bc7Smrj if (setpropval(opp)) 455ae115bc7Smrj exit(1); 456ae115bc7Smrj } 457ae115bc7Smrj } else if (strcmp(val, "none") == 0) { 458ae115bc7Smrj if (secure) { 459ae115bc7Smrj (void) memset(opp2->oprom_array + varlen2, '\0', 460ae115bc7Smrj PW_SIZE); 461ae115bc7Smrj opp2->oprom_size = varlen2 + PW_SIZE; 462ae115bc7Smrj /* set mode first */ 463ae115bc7Smrj if (setpropval(opp) || setpropval(opp2)) 464ae115bc7Smrj exit(1); 465ae115bc7Smrj } else { 466ae115bc7Smrj if (setpropval(opp)) 467ae115bc7Smrj exit(1); 468ae115bc7Smrj } 469ae115bc7Smrj } else { 470ae115bc7Smrj (void) printf("Invalid security mode, mode unchanged.\n"); 471ae115bc7Smrj exit(1); 472ae115bc7Smrj } 473ae115bc7Smrj } 474ae115bc7Smrj 475ae115bc7Smrj /* 476ae115bc7Smrj * Set password. 477ae115bc7Smrj * We must be in a secure mode in order to do this. 478ae115bc7Smrj */ 479ae115bc7Smrj /* ARGSUSED */ 480ae115bc7Smrj static void 481ae115bc7Smrj i_passwd(char *var, char *val, struct openpromio *opp) 482ae115bc7Smrj { 483ae115bc7Smrj int secure; 484ae115bc7Smrj Oppbuf oppbuf; 485ae115bc7Smrj struct openpromio *opp2 = &(oppbuf.opp); 486ae115bc7Smrj char pwbuf[PW_SIZE + 2]; 487ae115bc7Smrj int varlen; 488ae115bc7Smrj 489ae115bc7Smrj (void) strcpy(opp2->oprom_array, MODE_PROPERTY); 490ae115bc7Smrj if (getpropval(opp2) || opp2->oprom_size <= 0) { 491ae115bc7Smrj (void) printf("%s: data not available.\n", opp2->oprom_array); 492ae115bc7Smrj exit(1); 493ae115bc7Smrj } 494ae115bc7Smrj secure = strcmp(opp2->oprom_array, "none"); 495ae115bc7Smrj 496ae115bc7Smrj if (!secure) { 497ae115bc7Smrj (void) printf("Not in secure mode\n"); 498ae115bc7Smrj exit(1); 499ae115bc7Smrj } 500ae115bc7Smrj 501ae115bc7Smrj /* Set up opp for password */ 502ae115bc7Smrj (void) strcpy(opp->oprom_array, var); /* Safe; We know the name */ 503ae115bc7Smrj varlen = strlen(opp->oprom_array) + 1; 504ae115bc7Smrj 505ae115bc7Smrj if (get_password(pwbuf, PW_SIZE)) { 506ae115bc7Smrj (void) strcpy(opp->oprom_array + varlen, pwbuf); /* Bounded */ 507ae115bc7Smrj opp->oprom_size = varlen + strlen(pwbuf); 508ae115bc7Smrj if (setpropval(opp)) 509ae115bc7Smrj exit(1); 510ae115bc7Smrj } else 511ae115bc7Smrj exit(1); 512ae115bc7Smrj } 513ae115bc7Smrj 514ae115bc7Smrj /* ARGSUSED */ 515ae115bc7Smrj static void 516ae115bc7Smrj o_passwd(char *var, char *val) 517ae115bc7Smrj { 518ae115bc7Smrj /* Don't print the password */ 519ae115bc7Smrj } 520ae115bc7Smrj 521ae115bc7Smrj static int 522ae115bc7Smrj get_password(char *pw_dest, int pwsize) 523ae115bc7Smrj { 524ae115bc7Smrj int insist = 0, ok, flags; 525ae115bc7Smrj int c, pwlen; 526ae115bc7Smrj char *p; 527ae115bc7Smrj static char pwbuf[256]; 528ae115bc7Smrj char *pasword = NULL; 529ae115bc7Smrj 530ae115bc7Smrj tryagain: 531ae115bc7Smrj (void) printf("Changing PROM password:\n"); 532ae115bc7Smrj if ((pasword = getpass("New password:")) == NULL) { 533ae115bc7Smrj exit(_error(NO_PERROR, "failed to get password")); 534ae115bc7Smrj } 535ae115bc7Smrj (void) strcpy(pwbuf, pasword); 536ae115bc7Smrj pwlen = strlen(pwbuf); 537ae115bc7Smrj if (pwlen == 0) { 538ae115bc7Smrj (void) printf("Password unchanged.\n"); 539ae115bc7Smrj return (0); 540ae115bc7Smrj } 541ae115bc7Smrj /* 542ae115bc7Smrj * Insure password is of reasonable length and 543ae115bc7Smrj * composition. If we really wanted to make things 544ae115bc7Smrj * sticky, we could check the dictionary for common 545ae115bc7Smrj * words, but then things would really be slow. 546ae115bc7Smrj */ 547ae115bc7Smrj ok = 0; 548ae115bc7Smrj flags = 0; 549ae115bc7Smrj p = pwbuf; 550ae115bc7Smrj while ((c = *p++) != 0) { 551ae115bc7Smrj if (c >= 'a' && c <= 'z') 552ae115bc7Smrj flags |= 2; 553ae115bc7Smrj else if (c >= 'A' && c <= 'Z') 554ae115bc7Smrj flags |= 4; 555ae115bc7Smrj else if (c >= '0' && c <= '9') 556ae115bc7Smrj flags |= 1; 557ae115bc7Smrj else 558ae115bc7Smrj flags |= 8; 559ae115bc7Smrj } 560ae115bc7Smrj if (flags >= 7 && pwlen >= 4) 561ae115bc7Smrj ok = 1; 562ae115bc7Smrj if ((flags == 2 || flags == 4) && pwlen >= 6) 563ae115bc7Smrj ok = 1; 564ae115bc7Smrj if ((flags == 3 || flags == 5 || flags == 6) && pwlen >= 5) 565ae115bc7Smrj ok = 1; 566ae115bc7Smrj if (!ok && insist < 2) { 567ae115bc7Smrj (void) printf("Please use %s.\n", flags == 1 ? 568ae115bc7Smrj "at least one non-numeric character" : "a longer password"); 569ae115bc7Smrj insist++; 570ae115bc7Smrj goto tryagain; 571ae115bc7Smrj } 572ae115bc7Smrj if (strcmp(pwbuf, getpass("Retype new password:")) != 0) { 573ae115bc7Smrj (void) printf("Mismatch - password unchanged.\n"); 574ae115bc7Smrj return (0); 575ae115bc7Smrj } 576ae115bc7Smrj (void) strncpy(pw_dest, pwbuf, pwsize); 577ae115bc7Smrj return (1); 578ae115bc7Smrj } 579