Esempio n. 1
0
Key *
key_load_private(const char *filename, const char *passphrase,
                 char **commentp)
{
    Key *pub, *prv;
    int fd;

    fd = open(filename, O_RDONLY);
    if (fd < 0)
        return NULL;
    if (!key_perm_ok(fd, filename)) {
        error("bad permissions: ignore key: %s", filename);
        close(fd);
        return NULL;
    }
    pub = key_load_public_rsa1(fd, filename, commentp);
    lseek(fd, (off_t) 0, SEEK_SET);		/* rewind */
    if (pub == NULL) {
        /* closes fd */
        prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL);
        /* use the filename as a comment for PEM */
        if (commentp && prv)
            *commentp = xstrdup(filename);
    } else {
        /* it's a SSH v1 key if the public key part is readable */
        key_free(pub);
        /* closes fd */
        prv = key_load_private_rsa1(fd, filename, passphrase, NULL);
    }
    return prv;
}
Esempio n. 2
0
Key *
key_load_private_type(int type, const char *filename, const char *passphrase,
                      char **commentp)
{
    int fd;

    fd = open(filename, O_RDONLY);
    if (fd < 0)
        return NULL;
    if (!key_perm_ok(fd, filename)) {
        error("bad permissions: ignore key: %s", filename);
        close(fd);
        return NULL;
    }
    switch (type) {
    case KEY_RSA1:
        return key_load_private_rsa1(fd, filename, passphrase,
                                     commentp);
        /* closes fd */
        break;
    case KEY_DSA:
    case KEY_RSA:
    case KEY_UNSPEC:
        return key_load_private_pem(fd, type, passphrase, commentp);
        /* closes fd */
        break;
    default:
        close(fd);
        break;
    }
    return NULL;
}
Esempio n. 3
0
int
main(int argc, char **argv)
{
	Buffer b;
	Options options;
#define NUM_KEYTYPES 3
	Key *keys[NUM_KEYTYPES], *key = NULL;
	struct passwd *pw;
	int key_fd[NUM_KEYTYPES], i, found, version = 2, fd;
	u_char *signature, *data;
	char *host;
	u_int slen, dlen;
	u_int32_t rnd[256];

	/* Ensure that stdin and stdout are connected */
	if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2)
		exit(1);
	/* Leave /dev/null fd iff it is attached to stderr */
	if (fd > 2)
		close(fd);

	i = 0;
	key_fd[i++] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
	key_fd[i++] = open(_PATH_HOST_ECDSA_KEY_FILE, O_RDONLY);
	key_fd[i++] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);

	original_real_uid = getuid();	/* XXX readconf.c needs this */
	if ((pw = getpwuid(original_real_uid)) == NULL)
		fatal("getpwuid failed");
	pw = pwcopy(pw);

	permanently_set_uid(pw);

#ifdef DEBUG_SSH_KEYSIGN
	log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
#endif

	/* verify that ssh-keysign is enabled by the admin */
	initialize_options(&options);
	(void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0);
	fill_default_options(&options);
	if (options.enable_ssh_keysign != 1)
		fatal("ssh-keysign not enabled in %s",
		    _PATH_HOST_CONFIG_FILE);

	for (i = found = 0; i < NUM_KEYTYPES; i++) {
		if (key_fd[i] != -1)
			found = 1;
	}
	if (found == 0)
		fatal("could not open any host key");

	OpenSSL_add_all_algorithms();
	for (i = 0; i < 256; i++)
		rnd[i] = arc4random();
	RAND_seed(rnd, sizeof(rnd));

	found = 0;
	for (i = 0; i < NUM_KEYTYPES; i++) {
		keys[i] = NULL;
		if (key_fd[i] == -1)
			continue;
		keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
		    NULL, NULL);
		close(key_fd[i]);
		if (keys[i] != NULL)
			found = 1;
	}
	if (!found)
		fatal("no hostkey found");

	buffer_init(&b);
	if (ssh_msg_recv(STDIN_FILENO, &b) < 0)
		fatal("ssh_msg_recv failed");
	if (buffer_get_char(&b) != version)
		fatal("bad version");
	fd = buffer_get_int(&b);
	if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
		fatal("bad fd");
	if ((host = get_local_name(fd)) == NULL)
		fatal("cannot get local name for fd");

	data = buffer_get_string(&b, &dlen);
	if (valid_request(pw, host, &key, data, dlen) < 0)
		fatal("not a valid request");
	xfree(host);

	found = 0;
	for (i = 0; i < NUM_KEYTYPES; i++) {
		if (keys[i] != NULL &&
		    key_equal_public(key, keys[i])) {
			found = 1;
			break;
		}
	}
	if (!found)
		fatal("no matching hostkey found");

	if (key_sign(keys[i], &signature, &slen, data, dlen) != 0)
		fatal("key_sign failed");
	xfree(data);

	/* send reply */
	buffer_clear(&b);
	buffer_put_string(&b, signature, slen);
	if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1)
		fatal("ssh_msg_send failed");

	return (0);
}