Ejemplo n.º 1
0
int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
{
	char *file;
	u_int i, allowed = 0;
 
	temporarily_use_uid(pw);

#ifdef WITH_LDAP_PUBKEY
	if (options.lpk.on) {
	    u_int bits;
	    int sbits;
	    ldap_key_t *k;
	    /* here is the job */
	    Key *key = key_new(KEY_RSA1);

	    debug("[LDAP] trying LDAP first uid=%s", pw->pw_name);
	    if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) {
		if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
		    for (i = 0 ; i < k->num ; i++) {
			char *cp, *xoptions = NULL;

			for (cp = k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
			    ;
			if (!*cp || *cp == '\n' || *cp == '#')
			    continue;

			/*
			* Check if there are options for this key, and if so,
			* save their starting address and skip the option part
			* for now.  If there are no options, set the starting
			* address to NULL.
			 */
			if (*cp < '0' || *cp > '9') {
			    int quoted = 0;
			    xoptions = cp;
			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
				    cp++;	/* Skip both */
				else if (*cp == '"')
				    quoted = !quoted;
			    }
			} else
			    xoptions = NULL;

			/* Parse the key from the line. */
			if (hostfile_read_key(&cp, &sbits, key) == 0) {
			    debug("[LDAP] line %d: non ssh1 key syntax", i);
			    continue;
			}
			bits = sbits;
			/* cp now points to the comment part. */

			/* Check if the we have found the desired key (identified by its modulus). */
			if (BN_cmp(key->rsa->n, client_n) != 0)
			    continue;

			/* check the real bits  */
			if (bits != (unsigned int)BN_num_bits(key->rsa->n))
			    logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: "
				    "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits);

			/* We have found the desired key. */
			/*
			* If our options do not allow this key to be used,
			* do not send challenge.
			 */
			if (!auth_parse_options(pw, xoptions, "[LDAP]", (unsigned long) i))
			    continue;

			/* break out, this key is allowed */
			allowed = 1;

			/* add the return stuff etc... */
			/* Restore the privileged uid. */
			restore_uid();

			/* return key if allowed */
			if (allowed && rkey != NULL)
			    *rkey = key;
			else
			    key_free(key);

			ldap_keys_free(k);
			return (allowed);
		    }
		} else {
		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
		}
	    } else {
		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
	    }
	}
#endif

	for (i = 0; !allowed && i < options.num_authkeys_files; i++) {
		if (strcasecmp(options.authorized_keys_files[i], "none") == 0)
			continue;
		file = expand_authorized_keys(
		    options.authorized_keys_files[i], pw);
		allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey);
		free(file);
	}

	restore_uid();

	return allowed;
}
Ejemplo n.º 2
0
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
	char line[SSH_MAX_PUBKEY_BYTES];
	const char *reason;
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	Key *found;
	char *fp;
#ifdef WITH_LDAP_PUBKEY
	ldap_key_t * k;
	unsigned int i = 0;
#endif

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

#ifdef WITH_LDAP_PUBKEY
	found_key = 0;
	/* allocate a new key type */
	found = key_new(key->type);
 
	/* first check if the options is enabled, then try.. */
	if (options.lpk.on) {
	    debug("[LDAP] trying LDAP first uid=%s",pw->pw_name);
	    if (ldap_ismember(&options.lpk, pw->pw_name) > 0) {
		if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
		    /* Skip leading whitespace, empty and comment lines. */
		    for (i = 0 ; i < k->num ; i++) {
			/* dont forget if multiple keys to reset options */
			char *cp, *xoptions = NULL;

			for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
			    ;
			if (!*cp || *cp == '\n' || *cp == '#')
			    continue;

			if (key_read(found, &cp) != 1) {
			    /* no key?  check if there are options for this key */
			    int quoted = 0;
			    debug2("[LDAP] user_key_allowed: check options: '%s'", cp);
			    xoptions = cp;
			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
				    cp++;	/* Skip both */
				else if (*cp == '"')
				    quoted = !quoted;
			    }
			    /* Skip remaining whitespace. */
			    for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			    if (key_read(found, &cp) != 1) {
				debug2("[LDAP] user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			    }
			}

			if (key_equal(found, key) &&
				auth_parse_options(pw, xoptions, file, linenum) == 1) {
			    found_key = 1;
			    debug("[LDAP] matching key found");
			    fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			    verbose("[LDAP] Found matching %s key: %s", key_type(found), fp);

			    /* restoring memory */
			    ldap_keys_free(k);
			    xfree(fp);
			    restore_uid();
			    key_free(found);
			    return found_key;
			    break;
			}
		    }/* end of LDAP for() */
		} else {
		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
		}
	    } else {
		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
	    }
	}
#endif
	debug("trying public key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);

	if (!f) {
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);

	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp, *key_options = NULL;

		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_is_cert(key)) {
			if (!key_equal(found, key->cert->signature_key))
				continue;
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (!key_is_cert_authority)
				continue;
			fp = key_fingerprint(found, SSH_FP_MD5,
			    SSH_FP_HEX);
			debug("matching CA found: file %s, line %lu, %s %s",
			    file, linenum, key_type(found), fp);
			/*
			 * If the user has specified a list of principals as
			 * a key option, then prefer that list to matching
			 * their username in the certificate principals list.
			 */
			if (authorized_principals != NULL &&
			    !match_principals_option(authorized_principals,
			    key->cert)) {
				reason = "Certificate does not contain an "
				    "authorized principal";
 fail_reason:
				xfree(fp);
				error("%s", reason);
				auth_debug_add("%s", reason);
				continue;
			}
			if (key_cert_check_authority(key, 0, 0,
			    authorized_principals == NULL ? pw->pw_name : NULL,
			    &reason) != 0)
				goto fail_reason;
			if (auth_cert_options(key, pw) != 0) {
				xfree(fp);
				continue;
			}
			verbose("Accepted certificate ID \"%s\" "
			    "signed by %s CA %s via %s", key->cert->key_id,
			    key_type(found), fp, file);
			xfree(fp);
			found_key = 1;
			break;
		} else if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (key_is_cert_authority)
				continue;
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}