struct sshauthopt *
sshauthopt_from_cert(struct sshkey *k)
{
	struct sshauthopt *ret;

	if (k == NULL || !sshkey_type_is_cert(k->type) || k->cert == NULL ||
	    k->cert->type != SSH2_CERT_TYPE_USER)
		return NULL;

	if ((ret = sshauthopt_new()) == NULL)
		return NULL;

	/* Handle options and critical extensions separately */
	if (cert_option_list(ret, k->cert->critical,
	    OPTIONS_CRITICAL, 1) == -1) {
		sshauthopt_free(ret);
		return NULL;
	}
	if (cert_option_list(ret, k->cert->extensions,
	    OPTIONS_EXTENSIONS, 0) == -1) {
		sshauthopt_free(ret);
		return NULL;
	}
	/* success */
	return ret;
}
Beispiel #2
0
/* Disable forwarding, etc for the session */
void
auth_restrict_session(struct ssh *ssh)
{
	struct sshauthopt *restricted;

	debug("%s: restricting session", __func__);

	/* A blank sshauthopt defaults to permitting nothing */
	restricted = sshauthopt_new();
	restricted->permit_pty_flag = 1;
	restricted->restricted = 1;

	if (auth_activate_options(ssh, restricted) != 0)
		fatal("%s: failed to restrict session", __func__);
	sshauthopt_free(restricted);
}
struct sshauthopt *
sshauthopt_new_with_keys_defaults(void)
{
	struct sshauthopt *ret = NULL;

	if ((ret = sshauthopt_new()) == NULL)
		return NULL;

	/* Defaults for authorized_keys flags */
	ret->permit_port_forwarding_flag = 1;
	ret->permit_agent_forwarding_flag = 1;
	ret->permit_x11_forwarding_flag = 1;
	ret->permit_pty_flag = 1;
	ret->permit_user_rc = 1;
	return ret;
}
/*
 * Copy options
 */
struct sshauthopt *
sshauthopt_copy(const struct sshauthopt *orig)
{
	struct sshauthopt *ret;

	if ((ret = sshauthopt_new()) == NULL)
		return NULL;

#define OPTSCALAR(x) ret->x = orig->x
	OPTSCALAR(permit_port_forwarding_flag);
	OPTSCALAR(permit_agent_forwarding_flag);
	OPTSCALAR(permit_x11_forwarding_flag);
	OPTSCALAR(permit_pty_flag);
	OPTSCALAR(permit_user_rc);
	OPTSCALAR(restricted);
	OPTSCALAR(cert_authority);
	OPTSCALAR(force_tun_device);
	OPTSCALAR(valid_before);
#undef OPTSCALAR
#define OPTSTRING(x) \
	do { \
		if (orig->x != NULL && (ret->x = strdup(orig->x)) == NULL) { \
			sshauthopt_free(ret); \
			return NULL; \
		} \
	} while (0)
	OPTSTRING(cert_principals);
	OPTSTRING(force_command);
	OPTSTRING(required_from_host_cert);
	OPTSTRING(required_from_host_keys);
#undef OPTSTRING

	if (dup_strings(&ret->env, &ret->nenv, orig->env, orig->nenv) != 0 ||
	    dup_strings(&ret->permitopen, &ret->npermitopen,
	    orig->permitopen, orig->npermitopen) != 0) {
		sshauthopt_free(ret);
		return NULL;
	}
	return ret;
}
/*
 * Merges "additional" options to "primary" and returns the result.
 * NB. Some options from primary have primacy.
 */
struct sshauthopt *
sshauthopt_merge(const struct sshauthopt *primary,
    const struct sshauthopt *additional, const char **errstrp)
{
	struct sshauthopt *ret;
	const char *errstr = "internal error";
	const char *tmp;

	if (errstrp != NULL)
		*errstrp = NULL;

	if ((ret = sshauthopt_new()) == NULL)
		goto alloc_fail;

	/* cert_authority and cert_principals are cleared in result */

	/* Prefer access lists from primary. */
	/* XXX err is both set and mismatch? */
	tmp = primary->required_from_host_cert;
	if (tmp == NULL)
		tmp = additional->required_from_host_cert;
	if (tmp != NULL && (ret->required_from_host_cert = strdup(tmp)) == NULL)
		goto alloc_fail;
	tmp = primary->required_from_host_keys;
	if (tmp == NULL)
		tmp = additional->required_from_host_keys;
	if (tmp != NULL && (ret->required_from_host_keys = strdup(tmp)) == NULL)
		goto alloc_fail;

	/* force_tun_device, permitopen and environment prefer the primary. */
	ret->force_tun_device = primary->force_tun_device;
	if (ret->force_tun_device == -1)
		ret->force_tun_device = additional->force_tun_device;
	if (primary->nenv > 0) {
		if (dup_strings(&ret->env, &ret->nenv,
		    primary->env, primary->nenv) != 0)
			goto alloc_fail;
	} else if (additional->nenv) {
		if (dup_strings(&ret->env, &ret->nenv,
		    additional->env, additional->nenv) != 0)
			goto alloc_fail;
	}
	if (primary->npermitopen > 0) {
		if (dup_strings(&ret->permitopen, &ret->npermitopen,
		    primary->permitopen, primary->npermitopen) != 0)
			goto alloc_fail;
	} else if (additional->npermitopen > 0) {
		if (dup_strings(&ret->permitopen, &ret->npermitopen,
		    additional->permitopen, additional->npermitopen) != 0)
			goto alloc_fail;
	}

	/* Flags are logical-AND (i.e. must be set in both for permission) */
#define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1)
	OPTFLAG(permit_port_forwarding_flag);
	OPTFLAG(permit_agent_forwarding_flag);
	OPTFLAG(permit_x11_forwarding_flag);
	OPTFLAG(permit_pty_flag);
	OPTFLAG(permit_user_rc);
#undef OPTFLAG

	/* Earliest expiry time should win */
	if (primary->valid_before != 0)
		ret->valid_before = primary->valid_before;
	if (additional->valid_before != 0 &&
	    additional->valid_before < ret->valid_before)
		ret->valid_before = additional->valid_before;

	/*
	 * When both multiple forced-command are specified, only
	 * proceed if they are identical, otherwise fail.
	 */
	if (primary->force_command != NULL &&
	    additional->force_command != NULL) {
		if (strcmp(primary->force_command,
		    additional->force_command) == 0) {
			/* ok */
			ret->force_command = strdup(primary->force_command);
			if (ret->force_command == NULL)
				goto alloc_fail;
		} else {
			errstr = "forced command options do not match";
			goto fail;
		}
	} else if (primary->force_command != NULL) {
		if ((ret->force_command = strdup(
		    primary->force_command)) == NULL)
			goto alloc_fail;
	} else if (additional->force_command != NULL) {
		if ((ret->force_command = strdup(
		    additional->force_command)) == NULL)
			goto alloc_fail;
	}
	/* success */
	if (errstrp != NULL)
		*errstrp = NULL;
	return ret;

 alloc_fail:
	errstr = "memory allocation failed";
 fail:
	if (errstrp != NULL)
		*errstrp = errstr;
	sshauthopt_free(ret);
	return NULL;
}