use mkstemp() and arc4random() to generate cookie

This commit is contained in:
Alexandre Ratchov 2011-04-28 00:15:11 +02:00
parent 8d0497a37b
commit d12861225f
2 changed files with 65 additions and 53 deletions

1
configure vendored
View File

@ -51,6 +51,7 @@ case `uname` in
;;
OpenBSD)
sun=yes
defs='-DUSE_ARC4RANDOM'
;;
esac

View File

@ -38,9 +38,11 @@
#include "bsd-compat.h"
#endif
#ifndef USE_ARC4RANDOM
#ifndef DEV_RANDOM
#define DEV_RANDOM "/dev/arandom"
#endif
#endif
/*
* read a message, return 0 if not completed
@ -203,60 +205,20 @@ aucat_wdata(struct aucat *hdl, const void *buf, size_t len, unsigned wbpf, int *
return n;
}
int
aucat_gencookie(unsigned char *cookie)
{
int fd;
ssize_t n, len;
fd = open(DEV_RANDOM, O_RDONLY);
if (fd < 0) {
DPERROR(DEV_RANDOM);
return 0;
}
len = AMSG_COOKIELEN;
while (len > 0) {
n = read(fd, cookie, AMSG_COOKIELEN);
if (n < 0) {
DPERROR(DEV_RANDOM);
close(fd);
return 0;
}
if (n == 0) {
close(fd);
return 0;
}
cookie += n;
len -= n;
}
close(fd);
return 1;
}
void
aucat_savecookie(char *path, unsigned char *cookie)
{
int fd;
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
if (fd < 0) {
DPERROR(path);
return;
}
if (write(fd, cookie, AMSG_COOKIELEN) < 0) {
DPERROR(path);
return;
}
close(fd);
}
int
aucat_loadcookie(unsigned char *cookie)
{
struct stat sb;
char buf[PATH_MAX], *path;
int fd, len, res;
char buf[PATH_MAX], tmp[PATH_MAX], *path;
ssize_t len;
#ifndef USE_ARC4RANDOM
ssize_t n;
#endif
int fd;
/*
* try to load the cookie
*/
path = issetugid() ? NULL : getenv("AUCAT_COOKIE");
if (path == NULL) {
path = issetugid() ? NULL : getenv("HOME");
@ -293,10 +255,59 @@ aucat_loadcookie(unsigned char *cookie)
bad_close:
close(fd);
bad_gen:
res = aucat_gencookie(cookie);
if (path != NULL)
aucat_savecookie(path, cookie);
return res;
/*
* generate a new cookie
*/
#ifdef USE_ARC4RANDOM
arc4random_buf(cookie, AMSG_COOKIELEN);
#else
fd = open(DEV_RANDOM, O_RDONLY);
if (fd < 0) {
DPERROR(DEV_RANDOM);
return 0;
}
len = AMSG_COOKIELEN;
while (len > 0) {
n = read(fd, cookie, AMSG_COOKIELEN);
if (n < 0) {
DPERROR(DEV_RANDOM);
close(fd);
return 0;
}
if (n == 0) {
close(fd);
return 0;
}
cookie += n;
len -= n;
}
close(fd);
#endif
/*
* save the cookie, ignore errors
*/
if (path != NULL) {
if (strlcpy(tmp, path, PATH_MAX) >= PATH_MAX ||
strlcat(tmp, ".XXXXXXXX", PATH_MAX) >= PATH_MAX) {
DPRINTF("%s: too long\n", path);
return 1;
}
fd = mkstemp(tmp);
if (fd < 0) {
DPERROR(tmp);
return 1;
}
if (write(fd, cookie, AMSG_COOKIELEN) < 0) {
DPERROR(tmp);
}
close(fd);
if (rename(tmp, path) < 0) {
DPERROR(tmp);
unlink(tmp);
}
}
return 1;
}
int