Пример #1
0
int
pefs_keyparam_setfile(struct pefs_keyparam *kp, const char **files,
                      const char *arg)
{
    int *countp;

    if (files == kp->kp_keyfile)
        countp = &kp->kp_keyfile_count;
    else if (files == kp->kp_passfile)
        countp = &kp->kp_passfile_count;
    else {
        pefs_warn("internal error. invalid key parameters file type");
        return (PEFS_ERR_INVALID);
    }
    if (arg == NULL || arg[0] == '\0') {
        pefs_warn("invalid key file");
        return (PEFS_ERR_INVALID);
    }
    if (*countp == PEFS_KEYPARAM_FILES_MAX) {
        pefs_warn("key file limit exceed, %d max",
                  PEFS_KEYPARAM_FILES_MAX);
        return (PEFS_ERR_INVALID);
    }
    files[(*countp)++] = arg;

    return (0);
}
Пример #2
0
static int
pam_pefs_delkeys(const char *homedir)
{
	struct pefs_xkey k;
	int fd;

	fd = open(homedir, O_RDONLY);
	if (fd == -1) {
		pefs_warn("cannot open homedir %s: %s",
		    homedir, strerror(errno));
		return (PAM_USER_UNKNOWN);
	}

	bzero(&k, sizeof(k));
	while (1) {
		if (ioctl(fd, PEFS_GETKEY, &k) == -1)
			break;

		if (ioctl(fd, PEFS_DELKEY, &k) == -1) {
			pefs_warn("cannot del key: %s: %s",
			    homedir, strerror(errno));
			k.pxk_index++;
		}
	}
	close(fd);

	return (PAM_SUCCESS);
}
Пример #3
0
int
pefs_keyparam_setiterations(struct pefs_keyparam *kp, const char *arg)
{
    kp->kp_iterations = atoi(arg);
    if (kp->kp_iterations < 0) {
        pefs_warn("invalid iterations number: %s", arg);
        return (PEFS_ERR_INVALID);
    }

    return (0);
}
Пример #4
0
static int
pam_pefs_addkeys(const char *homedir, struct pefs_keychain_head *kch)
{
	struct pefs_keychain *kc;
	int fd;

	fd = open(homedir, O_RDONLY);
	if (fd == -1) {
		pefs_warn("cannot open homedir %s: %s",
		    homedir, strerror(errno));
		return (PAM_USER_UNKNOWN);
	}

	TAILQ_FOREACH(kc, kch, kc_entry) {
		if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) {
			pefs_warn("cannot add key: %s: %s",
			    homedir, strerror(errno));
			break;
		}
	}
	close(fd);

	return (PAM_SUCCESS);
}
Пример #5
0
int
pefs_keyparam_setalg(struct pefs_keyparam *kp, const char *algname)
{
    struct algorithm *alg;

    for (alg = algs; alg->name != NULL; alg++) {
        if (strcmp(algname, alg->name) == 0) {
            kp->kp_alg = alg->id;
            kp->kp_keybits = alg->keybits;
            return (0);
        }
    }

    pefs_warn("invalid algorithm %s", algname);
    return (PEFS_ERR_INVALID);
}
Пример #6
0
static int
pefs_keyparam_handle(struct pefs_keyparam *kp, int ind, const char *param)
{
    int err;

    if (*param == '\0')
        return (0);

    switch (ind) {
    case PEFS_KEYCONF_ALG_IND:
        err = pefs_keyparam_setalg(kp, param);
        break;
    case PEFS_KEYCONF_ITERATIONS_IND:
        err = pefs_keyparam_setiterations(kp, param);
        break;
    default:
        pefs_warn("invalid configuration option at position %d: %s",
                  ind + 1, param);
        err = PEFS_ERR_USAGE;
    }

    return (err);
}
Пример #7
0
static int
flopen_retry(const char *filename)
{
	int fd, try;

	for (try = 1; try <= 1024; try *= 2) {
		fd = flopen(filename, PEFS_SESSION_FILE_FLAGS,
		    PEFS_SESSION_FILE_MODE);
		if (fd != -1)
			return (fd);
		else if (errno != EWOULDBLOCK)
			return (-1);
		// Exponential back-off up to 1 second
		usleep(try * 1000000 / 1024);
	}
	errno = ETIMEDOUT;
	return (-1);
}

static int
pefs_session_count_incr(const char *user, bool incr)
{
	struct stat sb;
	struct timespec tp_uptime, tp_now;
	ssize_t offset;
	int fd, total = 0;
	char filename[MAXPATHLEN], buf[16];
	const char *errstr;

	snprintf(filename, sizeof(filename), "%s/%s", PEFS_SESSION_DIR, user);

	if (lstat(PEFS_SESSION_DIR, &sb) == -1) {
		if (errno != ENOENT) {
			pefs_warn("unable to access session directory %s: %s",
			    PEFS_SESSION_DIR, strerror(errno));
			return (-1);
		}
		if (mkdir(PEFS_SESSION_DIR, PEFS_SESSION_DIR_MODE) == -1) {
			pefs_warn("unable to create session directory %s: %s",
			    PEFS_SESSION_DIR, strerror(errno));
			return (-1);
		}
	} else if (!S_ISDIR(sb.st_mode)) {
		pefs_warn("%s is not a directory", PEFS_SESSION_DIR);
		return (-1);
	}

	if ((fd = flopen_retry(filename)) == -1) {
		pefs_warn("unable to create session counter file %s: %s",
		    filename, strerror(errno));
		return (-1);
	}

	if ((offset = pread(fd, buf, sizeof(buf) - 1, 0)) == -1) {
		pefs_warn("unable to read from the session counter file %s: %s",
		    filename, strerror(errno));
		close(fd);
		return (-1);
	}
	buf[offset] = '\0';
	if (offset != 0) {
		total = strtonum(buf, 0, INT_MAX, &errstr);
		if (errstr != NULL)
			pefs_warn("corrupted session counter file: %s: %s",
			    filename, errstr);
	}

	/*
	 * Determine if this is the first increment of the session file.
	 *
	 * It is considered the first increment if the session file has not
	 * been modified since the last boot time.
	 */
	if (incr && total > 0) {
		if (fstat(fd, &sb) == -1) {
			pefs_warn("unable to access session counter file %s: %s",
			    filename, strerror(errno));
			close(fd);
			return (-1);
		}
		/*
		 * Check is messy and will fail if wall clock isn't monotonical
		 * (e.g. because of ntp, DST, leap seconds)
		 */
		clock_gettime(CLOCK_REALTIME_FAST, &tp_now);
		clock_gettime(CLOCK_UPTIME_FAST, &tp_uptime);
		if (sb.st_mtime < tp_now.tv_sec - tp_uptime.tv_sec) {
			pefs_warn("stale session counter file: %s",
			    filename);
			total = 0;
		}
	}

	lseek(fd, 0L, SEEK_SET);
	ftruncate(fd, 0L);

	total += incr ? 1 : -1;
	if (total < 0) {
		pefs_warn("corrupted session counter file: %s",
		    filename);
		total = 0;
	} else
		pefs_warn("%s: session count %d", user, total);

	buf[0] = '\0';
	snprintf(buf, sizeof(buf), "%d", total);
	pwrite(fd, buf, strlen(buf), 0);
	close(fd);

	return (total);
}

static int
pam_pefs_checkfs(const char *homedir)
{
	char fsroot[MAXPATHLEN];
	int error;

	error = pefs_getfsroot(homedir, 0, fsroot, sizeof(fsroot));
	if (error != 0) {
		pefs_warn("file system is not mounted: %s", homedir);
		return (PAM_USER_UNKNOWN);
	} if (strcmp(fsroot, homedir) != 0) {
		pefs_warn("file system is not mounted on home dir: %s", fsroot);
		return (PAM_USER_UNKNOWN);
	}

	return (PAM_SUCCESS);
}