#include <u.h>
#include <libc.h>
#include <authsrv.h>

static long	finddosfile(int, char*);

static int
check(void *x, int len, uchar sum, char *msg)
{
	if(nvcsum(x, len) == sum)
		return 0;
	memset(x, 0, len);
	fprint(2, "%s\n", msg);
	return 1;
}

/*
 *  get key info out of nvram.  since there isn't room in the PC's nvram use
 *  a disk partition there.
 */
static struct {
	char *cputype;
	char *file;
	int off;
	int len;
} nvtab[] = {
	"sparc", "#r/nvram", 1024+850, sizeof(Nvrsafe),
	"pc", "#S/sdC0/nvram", 0, sizeof(Nvrsafe),
	"pc", "#S/sdC0/9fat", -1, sizeof(Nvrsafe),
	"pc", "#S/sdC1/nvram", 0, sizeof(Nvrsafe),
	"pc", "#S/sdC1/9fat", -1, sizeof(Nvrsafe),
	"pc", "#S/sd00/nvram", 0, sizeof(Nvrsafe),
	"pc", "#S/sd00/9fat", -1, sizeof(Nvrsafe),
	"pc", "#S/sd01/nvram", 0, sizeof(Nvrsafe),
	"pc", "#S/sd01/9fat", -1, sizeof(Nvrsafe),
	"pc", "#f/fd0disk", -1, 512,	/* 512: #f requires whole sector reads */
	"pc", "#f/fd1disk", -1, 512,
	"mips", "#r/nvram", 1024+900, sizeof(Nvrsafe),
	"power", "#F/flash/flash0", 0x440000, sizeof(Nvrsafe),
	"power", "#r/nvram", 4352, sizeof(Nvrsafe),	/* OK for MTX-604e */
	"debug", "/tmp/nvram", 0, sizeof(Nvrsafe),
};

char*
xreadcons(char *prompt, char *def, int secret, char *buf, int nbuf)
{
	char *p;
	
	p = readcons(prompt, def, secret);
	if(p == nil)
		return nil;
	strecpy(buf, buf+nbuf, p);
	memset(p, 0, strlen(p));
	free(p);
	return buf;
}

/*
 *  get key info out of nvram.  since there isn't room in the PC's nvram use
 *  a disk partition there.
 */
int
readnvram(Nvrsafe *safep, int flag)
{
	char buf[1024], in[128], *cputype, *nvrfile, *nvrlen, *nvroff, *v[2];
	int fd, err, i, safeoff, safelen;
	Nvrsafe *safe;

	err = 0;
	memset(safep, 0, sizeof(*safep));

	nvrfile = getenv("nvram");
	cputype = getenv("cputype");
	if(cputype == nil)
		cputype = "mips";
	if(strcmp(cputype, "386")==0 || strcmp(cputype, "alpha")==0)
		cputype = "pc";

	safe = (Nvrsafe*)buf;

	fd = -1;
	safeoff = -1;
	safelen = -1;
	if(nvrfile != nil){
		/* accept device and device!file */
		i = gettokens(nvrfile, v, nelem(v), "!");
		fd = open(v[0], ORDWR);
		safelen = sizeof(Nvrsafe);
		if(strstr(v[0], "/9fat") == nil)
			safeoff = 0;
		nvrlen = getenv("nvrlen");
		if(nvrlen != nil)
			safelen = atoi(nvrlen);
		nvroff = getenv("nvroff");
		if(nvroff != nil){
			if(strcmp(nvroff, "dos") == 0)
				safeoff = -1;
			else
				safeoff = atoi(nvroff);
		}
		if(safeoff < 0 && fd >= 0){
			safelen = 512;
			safeoff = finddosfile(fd, i == 2 ? v[1] : "plan9.nvr");
			if(safeoff < 0){
				close(fd);
				fd = -1;
			}
		}
		free(nvrfile);
		if(nvrlen != nil)
			free(nvrlen);
		if(nvroff != nil)
			free(nvroff);
	}else{
		for(i=0; i<nelem(nvtab); i++){
			if(strcmp(cputype, nvtab[i].cputype) != 0)
				continue;
			if((fd = open(nvtab[i].file, ORDWR)) < 0)
				continue;
			safeoff = nvtab[i].off;
			safelen = nvtab[i].len;
			if(safeoff == -1){
				safeoff = finddosfile(fd, "plan9.nvr");
				if(safeoff < 0){
					close(fd);
					fd = -1;
					continue;
				}
			}
			break;
		}
	}

	if(fd < 0
	|| seek(fd, safeoff, 0) < 0
	|| read(fd, buf, safelen) != safelen){
		err = 1;
		if(flag&(NVwrite|NVwriteonerr))
			fprint(2, "can't read nvram: %r\n");
		memset(safep, 0, sizeof(*safep));
		safe = safep;
	}else{
		*safep = *safe;
		safe = safep;

		err |= check(safe->machkey, DESKEYLEN, safe->machsum, "bad nvram key");
//		err |= check(safe->config, CONFIGLEN, safe->configsum, "bad secstore key");
		err |= check(safe->authid, ANAMELEN, safe->authidsum, "bad authentication id");
		err |= check(safe->authdom, DOMLEN, safe->authdomsum, "bad authentication domain");
	}

	if((flag&NVwrite) || (err && (flag&NVwriteonerr))){
		xreadcons("authid", nil, 0, safe->authid, sizeof(safe->authid));
		xreadcons("authdom", nil, 0, safe->authdom, sizeof(safe->authdom));
		xreadcons("secstore key", nil, 1, safe->config, sizeof(safe->config));
		for(;;){
			if(xreadcons("password", nil, 1, in, sizeof in) == nil)
				goto Out;
			if(passtokey(safe->machkey, in))
				break;
		}
		safe->machsum = nvcsum(safe->machkey, DESKEYLEN);
		safe->configsum = nvcsum(safe->config, CONFIGLEN);
		safe->authidsum = nvcsum(safe->authid, sizeof(safe->authid));
		safe->authdomsum = nvcsum(safe->authdom, sizeof(safe->authdom));
		*(Nvrsafe*)buf = *safe;
		if(seek(fd, safeoff, 0) < 0
		|| write(fd, buf, safelen) != safelen){
			fprint(2, "can't write key to nvram: %r\n");
			err = 1;
		}else
			err = 0;
	}
Out:
	close(fd);
	return err ? -1 : 0;
}

typedef struct Dosboot	Dosboot;
struct Dosboot{
	uchar	magic[3];	/* really an xx86 JMP instruction */
	uchar	version[8];
	uchar	sectsize[2];
	uchar	clustsize;
	uchar	nresrv[2];
	uchar	nfats;
	uchar	rootsize[2];
	uchar	volsize[2];
	uchar	mediadesc;
	uchar	fatsize[2];
	uchar	trksize[2];
	uchar	nheads[2];
	uchar	nhidden[4];
	uchar	bigvolsize[4];
	uchar	driveno;
	uchar	reserved0;
	uchar	bootsig;
	uchar	volid[4];
	uchar	label[11];
	uchar	type[8];
};
#define	GETSHORT(p) (((p)[1]<<8) | (p)[0])
#define	GETLONG(p) ((GETSHORT((p)+2) << 16) | GETSHORT((p)))

typedef struct Dosdir	Dosdir;
struct Dosdir
{
	char	name[8];
	char	ext[3];
	uchar	attr;
	uchar	reserved[10];
	uchar	time[2];
	uchar	date[2];
	uchar	start[2];
	uchar	length[4];
};

static char*
dosparse(char *from, char *to, int len)
{
	char c;

	memset(to, ' ', len);
	if(from == 0)
		return 0;
	while(len-- > 0){
		c = *from++;
		if(c == '.')
			return from;
		if(c == 0)
			break;
		if(c >= 'a' && c <= 'z')
			*to++ = c + 'A' - 'a';
		else
			*to++ = c;
	}
	return 0;
}

/*
 *  return offset of first file block
 *
 *  This is a very simplistic dos file system.  It only
 *  works on floppies, only looks in the root, and only
 *  returns a pointer to the first block of a file.
 *
 *  This exists for cpu servers that have no hard disk
 *  or nvram to store the key on.
 *
 *  Please don't make this any smarter: it stays resident
 *  and I'ld prefer not to waste the space on something that
 *  runs only at boottime -- presotto.
 */
static long
finddosfile(int fd, char *file)
{
	uchar secbuf[512];
	char name[8];
	char ext[3];
	Dosboot	*b;
	Dosdir *root, *dp;
	int nroot, sectsize, rootoff, rootsects, n;

	/* dos'ize file name */
	file = dosparse(file, name, 8);
	dosparse(file, ext, 3);

	/* read boot block, check for sanity */
	b = (Dosboot*)secbuf;
	if(read(fd, secbuf, sizeof(secbuf)) != sizeof(secbuf))
		return -1;
	if(b->magic[0] != 0xEB || b->magic[1] != 0x3C || b->magic[2] != 0x90)
		return -1;
	sectsize = GETSHORT(b->sectsize);
	if(sectsize != 512)
		return -1;
	rootoff = (GETSHORT(b->nresrv) + b->nfats*GETSHORT(b->fatsize)) * sectsize;
	if(seek(fd, rootoff, 0) < 0)
		return -1;
	nroot = GETSHORT(b->rootsize);
	rootsects = (nroot*sizeof(Dosdir)+sectsize-1)/sectsize;
	if(rootsects <= 0 || rootsects > 64)
		return -1;

	/* 
	 *  read root. it is contiguous to make stuff like
	 *  this easier
	 */
	root = malloc(rootsects*sectsize);
	if(read(fd, root, rootsects*sectsize) != rootsects*sectsize)
		return -1;
	n = -1;
	for(dp = root; dp < &root[nroot]; dp++)
		if(memcmp(name, dp->name, 8) == 0 && memcmp(ext, dp->ext, 3) == 0){
			n = GETSHORT(dp->start);
			break;
		}
	free(root);

	if(n < 0)
		return -1;

	/*
	 *  dp->start is in cluster units, not sectors.  The first
	 *  cluster is cluster 2 which starts immediately after the
	 *  root directory
	 */
	return rootoff + rootsects*sectsize + (n-2)*sectsize*b->clustsize;
}

