Пример #1
0
int
ssh_remove_identity(AuthenticationConnection *auth, Key *key)
{
	Buffer msg;
	int type;
	u_char *blob;
	u_int blen;

	buffer_init(&msg);

	if (key->type == KEY_RSA1) {
		buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
		buffer_put_int(&msg, BN_num_bits(key->rsa->n));
		buffer_put_bignum(&msg, key->rsa->e);
		buffer_put_bignum(&msg, key->rsa->n);
	} else if (key_type_plain(key->type) == KEY_DSA ||
	    key_type_plain(key->type) == KEY_RSA ||
	    key_type_plain(key->type) == KEY_ECDSA) {
		key_to_blob(key, &blob, &blen);
		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
		buffer_put_string(&msg, blob, blen);
		free(blob);
	} else {
		buffer_free(&msg);
		return 0;
	}
	if (ssh_request_reply(auth, &msg, &msg) == 0) {
		buffer_free(&msg);
		return 0;
	}
	type = buffer_get_char(&msg);
	buffer_free(&msg);
	return decode_reply(type);
}
Пример #2
0
int
ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	int hash_alg;
	u_char digest[SSH_DIGEST_MAX_LENGTH];
	u_int len, dlen;
	Buffer b, bb;

	if (key == NULL || key_type_plain(key->type) != KEY_ECDSA ||
	    key->ecdsa == NULL) {
		error("%s: no ECDSA key", __func__);
		return -1;
	}

	hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
		error("%s: bad hash algorithm %d", __func__, hash_alg);
		return -1;
	}
	if (ssh_digest_memory(hash_alg, data, datalen,
	    digest, sizeof(digest)) != 0) {
		error("%s: digest_memory failed", __func__);
		return -1;
	}

	sig = ECDSA_do_sign(digest, dlen, key->ecdsa);
	explicit_bzero(digest, sizeof(digest));

	if (sig == NULL) {
		error("%s: sign failed", __func__);
		return -1;
	}

	buffer_init(&bb);
	buffer_put_bignum2(&bb, sig->r);
	buffer_put_bignum2(&bb, sig->s);
	ECDSA_SIG_free(sig);

	buffer_init(&b);
	buffer_put_cstring(&b, key_ssh_name_plain(key));
	buffer_put_string(&b, buffer_ptr(&bb), buffer_len(&bb));
	buffer_free(&bb);
	len = buffer_len(&b);
	if (lenp != NULL)
		*lenp = len;
	if (sigp != NULL) {
		*sigp = xmalloc(len);
		memcpy(*sigp, buffer_ptr(&b), len);
	}
	buffer_free(&b);

	return 0;
}
Пример #3
0
int
ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
    const u_char *data, u_int datalen)
{
	u_char *sig;
	u_int slen, len;
	unsigned long long smlen;
	int ret;
	Buffer b;

	if (key == NULL || key_type_plain(key->type) != KEY_ED25519 ||
	    key->ed25519_sk == NULL) {
		error("%s: no ED25519 key", __func__);
		return -1;
	}

	if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) {
		error("%s: datalen %u too long", __func__, datalen);
		return -1;
	}
	smlen = slen = datalen + crypto_sign_ed25519_BYTES;
	sig = xmalloc(slen);

	if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
	    key->ed25519_sk)) != 0 || smlen <= datalen) {
		error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
		free(sig);
		return -1;
	}
	/* encode signature */
	buffer_init(&b);
	buffer_put_cstring(&b, "ssh-ed25519");
	buffer_put_string(&b, sig, smlen - datalen);
	len = buffer_len(&b);
	if (lenp != NULL)
		*lenp = len;
	if (sigp != NULL) {
		*sigp = xmalloc(len);
		memcpy(*sigp, buffer_ptr(&b), len);
	}
	buffer_free(&b);
	explicit_bzero(sig, slen);
	free(sig);

	return 0;
}
Пример #4
0
static int
userauth_pubkey(Authctxt *authctxt)
{
	Buffer b;
	Key *key = NULL;
	char *pkalg, *userstyle;
	u_char *pkblob, *sig;
	u_int alen, blen, slen;
	int have_sig, pktype;
	int authenticated = 0;

	if (!authctxt->valid) {
		debug2("userauth_pubkey: disabled because of invalid user");
		return 0;
	}
	have_sig = packet_get_char();
	if (datafellows & SSH_BUG_PKAUTH) {
		debug2("userauth_pubkey: SSH_BUG_PKAUTH");
		/* no explicit pkalg given */
		pkblob = packet_get_string(&blen);
		buffer_init(&b);
		buffer_append(&b, pkblob, blen);
		/* so we have to extract the pkalg from the pkblob */
		pkalg = buffer_get_string(&b, &alen);
		buffer_free(&b);
	} else {
		pkalg = packet_get_string(&alen);
		pkblob = packet_get_string(&blen);
	}
	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC) {
		/* this is perfectly legal */
		logit("userauth_pubkey: unsupported public key algorithm: %s",
		    pkalg);
		goto done;
	}
	key = key_from_blob(pkblob, blen);
	if (key == NULL) {
		error("userauth_pubkey: cannot decode key: %s", pkalg);
		goto done;
	}
	if (key->type != pktype) {
		error("userauth_pubkey: type mismatch for decoded key "
		    "(received %d, expected %d)", key->type, pktype);
		goto done;
	}
	if (key_type_plain(key->type) == KEY_RSA &&
	    (datafellows & SSH_BUG_RSASIGMD5) != 0) {
		logit("Refusing RSA key because client uses unsafe "
		    "signature scheme");
		goto done;
	}
	if (auth2_userkey_already_used(authctxt, key)) {
		logit("refusing previously-used %s key", key_type(key));
		goto done;
	}
	if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types,
	    strlen(options.pubkey_key_types), 0) != 1) {
		logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
		    __func__, sshkey_ssh_name(key));
		goto done;
	}

	if (have_sig) {
		sig = packet_get_string(&slen);
		packet_check_eom();
		buffer_init(&b);
		if (datafellows & SSH_OLD_SESSIONID) {
			buffer_append(&b, session_id2, session_id2_len);
		} else {
			buffer_put_string(&b, session_id2, session_id2_len);
		}
		/* reconstruct packet */
		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
		xasprintf(&userstyle, "%s%s%s", authctxt->user,
		    authctxt->style ? ":" : "",
		    authctxt->style ? authctxt->style : "");
		buffer_put_cstring(&b, userstyle);
		free(userstyle);
		buffer_put_cstring(&b,
		    datafellows & SSH_BUG_PKSERVICE ?
		    "ssh-userauth" :
		    authctxt->service);
		if (datafellows & SSH_BUG_PKAUTH) {
			buffer_put_char(&b, have_sig);
		} else {
			buffer_put_cstring(&b, "publickey");
			buffer_put_char(&b, have_sig);
			buffer_put_cstring(&b, pkalg);
		}
		buffer_put_string(&b, pkblob, blen);
#ifdef DEBUG_PK
		buffer_dump(&b);
#endif
		pubkey_auth_info(authctxt, key, NULL);

		/* test for correct signature */
		authenticated = 0;
		if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
		    buffer_len(&b))) == 1) {
			authenticated = 1;
			/* Record the successful key to prevent reuse */
			auth2_record_userkey(authctxt, key);
			key = NULL; /* Don't free below */
		}
		buffer_free(&b);
		free(sig);
	} else {
		debug("test whether pkalg/pkblob are acceptable");
		packet_check_eom();

		/* XXX fake reply and always send PK_OK ? */
		/*
		 * XXX this allows testing whether a user is allowed
		 * to login: if you happen to have a valid pubkey this
		 * message is sent. the message is NEVER sent at all
		 * if a user is not allowed to login. is this an
		 * issue? -markus
		 */
		if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
			packet_start(SSH2_MSG_USERAUTH_PK_OK);
			packet_put_string(pkalg, alen);
			packet_put_string(pkblob, blen);
			packet_send();
			packet_write_wait();
			authctxt->postponed = 1;
		}
	}
	if (authenticated != 1)
		auth_clear_options();
done:
	debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
	if (key != NULL)
		key_free(key);
	free(pkalg);
	free(pkblob);
	return authenticated;
}
Пример #5
0
static int
userauth_pubkey(Authctxt *authctxt)
{
  #ifdef WIN32_FIXME
  
  int loginStat = 1;

  char currentUser[MAX_PATH] = {0};
  
  DWORD currentUserSize = sizeof(currentUser);
  
  int targetIsCurrent = 0;

  # ifdef USE_NTCREATETOKEN
  int doOpenSSHVerify = 1;
  # else
  int doOpenSSHVerify = 0;
  # endif

  #endif
  
	Buffer b;
	Key *key = NULL;
	char *pkalg, *userstyle;
	u_char *pkblob, *sig;
	u_int alen, blen, slen;
	int have_sig, pktype;
	int authenticated = 0;

	if (!authctxt->valid) {
		debug2("userauth_pubkey: disabled because of invalid user");
		return 0;
	}
	have_sig = packet_get_char();
	if (datafellows & SSH_BUG_PKAUTH) {
		debug2("userauth_pubkey: SSH_BUG_PKAUTH");
		/* no explicit pkalg given */
		pkblob = packet_get_string(&blen);
		buffer_init(&b);
		buffer_append(&b, pkblob, blen);
		/* so we have to extract the pkalg from the pkblob */
		pkalg = buffer_get_string(&b, &alen);
		buffer_free(&b);
	} else {
		pkalg = packet_get_string(&alen);
		pkblob = packet_get_string(&blen);
	}
	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC) {
		/* this is perfectly legal */
		logit("userauth_pubkey: unsupported public key algorithm: %s",
		    pkalg);
		goto done;
	}
	key = key_from_blob(pkblob, blen);
	if (key == NULL) {
		error("userauth_pubkey: cannot decode key: %s", pkalg);
		goto done;
	}
	if (key->type != pktype) {
		error("userauth_pubkey: type mismatch for decoded key "
		    "(received %d, expected %d)", key->type, pktype);
		goto done;
	}
	if (key_type_plain(key->type) == KEY_RSA &&
	    (datafellows & SSH_BUG_RSASIGMD5) != 0) {
		logit("Refusing RSA key because client uses unsafe "
		    "signature scheme");
		goto done;
	}
	if (auth2_userkey_already_used(authctxt, key)) {
		logit("refusing previously-used %s key", key_type(key));
		goto done;
	}
	if (match_pattern_list(sshkey_ssh_name(key),
	    options.pubkey_key_types, 0) != 1) {
		logit("%s: key type %s not in PubkeyAcceptedKeyTypes",
		    __func__, sshkey_ssh_name(key));
		goto done;
	}

	if (have_sig) {
		sig = packet_get_string(&slen);
		packet_check_eom();
		buffer_init(&b);
		if (datafellows & SSH_OLD_SESSIONID) {
			buffer_append(&b, session_id2, session_id2_len);
		} else {
			buffer_put_string(&b, session_id2, session_id2_len);
		}
		/* reconstruct packet */
		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
		xasprintf(&userstyle, "%s%s%s", authctxt->user,
		    authctxt->style ? ":" : "",
		    authctxt->style ? authctxt->style : "");
		buffer_put_cstring(&b, userstyle);
		free(userstyle);
		buffer_put_cstring(&b,
		    datafellows & SSH_BUG_PKSERVICE ?
		    "ssh-userauth" :
		    authctxt->service);
		if (datafellows & SSH_BUG_PKAUTH) {
			buffer_put_char(&b, have_sig);
		} else {
			buffer_put_cstring(&b, "publickey");
			buffer_put_char(&b, have_sig);
			buffer_put_cstring(&b, pkalg);
		}
		buffer_put_string(&b, pkblob, blen);
#ifdef DEBUG_PK
		buffer_dump(&b);
#endif
		pubkey_auth_info(authctxt, key, NULL);

		/* test for correct signature */
		authenticated = 0;
   /*
     * On pure win32 try to logon using lsa first.
     */

    #ifdef WIN32_FIXME

    authctxt -> hTokenLsa_ = NULL;
    authctxt -> methoddata = NULL;
 
    /*
     * Retrieve name of current login user (i.e. sshd process owner).
     */
     
    GetUserName(currentUser, &currentUserSize);

    /*
     * Try to get token from lsa, but only if targetUser != currentUser.
     * Owerthise we already have targetUser's token in current thread, so
     * we only need key verify from original OpenSSH code.
     */

    targetIsCurrent = (strcmp(currentUser, authctxt -> user) == 0);
    
    if (targetIsCurrent)
    {
      doOpenSSHVerify = 1;
    }
    else
    {
      loginStat = LsaLogon(&authctxt -> hTokenLsa_, HomeDirLsaW,
                               authctxt -> user, pkblob, blen, sig, slen,
                                 buffer_ptr(&b), buffer_len(&b), datafellows);

      /*
       * If lsa logon process success.
       */
  
      if (loginStat == 0)
      {
        /*
         * And user authorized OK.
         */
    
        if (authctxt -> hTokenLsa_)
        {
          doOpenSSHVerify = 0;
          
          /*
           * This is part of openssh authorization needed for parsing
           * 'options' block in key.
           */
      
          authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user);
      
          if (PRIVSEP(user_key_allowed(authctxt -> pw, key, 1))) // PRAGMA:TODO
          {
            authenticated = 1;
          }
          else
          {
            authenticated = 0;
          }
          
          buffer_free(&b);

          free(sig);
        }
      }
    }
    
    if (doOpenSSHVerify)
    {
      /*
       * If lsa fails, test for correct signature using openssh code.
       */
      
      authctxt -> pw -> pw_dir = GetHomeDir(authctxt -> user);
  
      if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))  //PRAGMA:TODO
		  &&
              PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b))) == 1)
    
      {
        authenticated = 1;
      }
    }
    
    /*
     * Original code.
     */

    #else /* #ifdef WIN32_FIXME */

		if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) &&
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
		    buffer_len(&b))) == 1) {
			authenticated = 1;
			/* Record the successful key to prevent reuse */
			auth2_record_userkey(authctxt, key);
			key = NULL; /* Don't free below */
		}
		buffer_free(&b);
		free(sig);
   #endif /* else #ifdef WIN32_FIXME. */

	} else {
		debug("test whether pkalg/pkblob are acceptable");
		packet_check_eom();

		/* XXX fake reply and always send PK_OK ? */
		/*
		 * XXX this allows testing whether a user is allowed
		 * to login: if you happen to have a valid pubkey this
		 * message is sent. the message is NEVER sent at all
		 * if a user is not allowed to login. is this an
		 * issue? -markus
		 */
		

      #ifndef WIN32_FIXME

     if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0)))  
 
      #endif		
		{
			packet_start(SSH2_MSG_USERAUTH_PK_OK);
			packet_put_string(pkalg, alen);
			packet_put_string(pkblob, blen);
			packet_send();
			packet_write_wait();
			authctxt->postponed = 1;
		}
	}
	if (authenticated != 1)
		auth_clear_options();
done:
	debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
	if (key != NULL)
		key_free(key);
	free(pkalg);
	free(pkblob);
	return authenticated;
}
Пример #6
0
int
ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	Buffer b;
	char *ktype;
	u_char *sigblob, *sm, *m;
	u_int len;
	unsigned long long smlen, mlen;
	int rlen, ret;

	if (key == NULL || key_type_plain(key->type) != KEY_ED25519 ||
	    key->ed25519_pk == NULL) {
		error("%s: no ED25519 key", __func__);
		return -1;
	}
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_cstring(&b, NULL);
	if (strcmp("ssh-ed25519", ktype) != 0) {
		error("%s: cannot handle type %s", __func__, ktype);
		buffer_free(&b);
		free(ktype);
		return -1;
	}
	free(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("%s: remaining bytes in signature %d", __func__, rlen);
		free(sigblob);
		return -1;
	}
	if (len > crypto_sign_ed25519_BYTES) {
		error("%s: len %u > crypto_sign_ed25519_BYTES %u", __func__,
		    len, crypto_sign_ed25519_BYTES);
		free(sigblob);
		return -1;
	}
	smlen = len + datalen;
	sm = xmalloc(smlen);
	memcpy(sm, sigblob, len);
	memcpy(sm+len, data, datalen);
	mlen = smlen;
	m = xmalloc(mlen);
	if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
	    key->ed25519_pk)) != 0) {
		debug2("%s: crypto_sign_ed25519_open failed: %d",
		    __func__, ret);
	}
	if (ret == 0 && mlen != datalen) {
		debug2("%s: crypto_sign_ed25519_open "
		    "mlen != datalen (%llu != %u)", __func__, mlen, datalen);
		ret = -1;
	}
	/* XXX compare 'm' and 'data' ? */

	explicit_bzero(sigblob, len);
	explicit_bzero(sm, smlen);
	explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */
	free(sigblob);
	free(sm);
	free(m);
	debug("%s: signature %scorrect", __func__, (ret != 0) ? "in" : "");

	/* translate return code carefully */
	return (ret == 0) ? 1 : -1;
}
Пример #7
0
static int
userauth_hostbased(Authctxt *authctxt)
{
	Buffer b;
	Key *key = NULL;
	char *pkalg, *cuser, *chost, *service;
	u_char *pkblob, *sig;
	u_int alen, blen, slen;
	int pktype;
	int authenticated = 0;

	if (!authctxt->valid) {
		debug2("userauth_hostbased: disabled because of invalid user");
		return 0;
	}
	pkalg = packet_get_string(&alen);
	pkblob = packet_get_string(&blen);
	chost = packet_get_string(NULL);
	cuser = packet_get_string(NULL);
	sig = packet_get_string(&slen);

	debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
	    cuser, chost, pkalg, slen);
#ifdef DEBUG_PK
	debug("signature:");
	buffer_init(&b);
	buffer_append(&b, sig, slen);
	buffer_dump(&b);
	buffer_free(&b);
#endif
	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC) {
		/* this is perfectly legal */
		logit("userauth_hostbased: unsupported "
		    "public key algorithm: %s", pkalg);
		goto done;
	}
	key = key_from_blob(pkblob, blen);
	if (key == NULL) {
		error("userauth_hostbased: cannot decode key: %s", pkalg);
		goto done;
	}
	if (key->type != pktype) {
		error("userauth_hostbased: type mismatch for decoded key "
		    "(received %d, expected %d)", key->type, pktype);
		goto done;
	}
	if (key_type_plain(key->type) == KEY_RSA &&
	    (datafellows & SSH_BUG_RSASIGMD5) != 0) {
		error("Refusing RSA key because peer uses unsafe "
		    "signature format");
		goto done;
	}
	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
	    authctxt->service;
	buffer_init(&b);
	buffer_put_string(&b, session_id2, session_id2_len);
	/* reconstruct packet */
	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
	buffer_put_cstring(&b, authctxt->user);
	buffer_put_cstring(&b, service);
	buffer_put_cstring(&b, "hostbased");
	buffer_put_string(&b, pkalg, alen);
	buffer_put_string(&b, pkblob, blen);
	buffer_put_cstring(&b, chost);
	buffer_put_cstring(&b, cuser);
#ifdef DEBUG_PK
	buffer_dump(&b);
#endif

	pubkey_auth_info(authctxt, key,
	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);

	/* test for allowed key and correct signature */
	authenticated = 0;
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
			buffer_len(&b))) == 1)
		authenticated = 1;

	buffer_free(&b);
done:
	debug2("userauth_hostbased: authenticated %d", authenticated);
	if (key != NULL)
		key_free(key);
	free(pkalg);
	free(pkblob);
	free(cuser);
	free(chost);
	free(sig);
	return authenticated;
}
Пример #8
0
int
ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	int hash_alg;
	u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b, bb;
	char *ktype;

	if (key == NULL || key_type_plain(key->type) != KEY_ECDSA ||
	    key->ecdsa == NULL) {
		error("%s: no ECDSA key", __func__);
		return -1;
	}

	/* fetch signature */
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_string(&b, NULL);
	if (strcmp(key_ssh_name_plain(key), ktype) != 0) {
		error("%s: cannot handle type %s", __func__, ktype);
		buffer_free(&b);
		free(ktype);
		return -1;
	}
	free(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("%s: remaining bytes in signature %d", __func__, rlen);
		free(sigblob);
		return -1;
	}

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		fatal("%s: ECDSA_SIG_new failed", __func__);

	buffer_init(&bb);
	buffer_append(&bb, sigblob, len);
	buffer_get_bignum2(&bb, sig->r);
	buffer_get_bignum2(&bb, sig->s);
	if (buffer_len(&bb) != 0)
		fatal("%s: remaining bytes in inner sigblob", __func__);
	buffer_free(&bb);

	/* clean up */
	explicit_bzero(sigblob, len);
	free(sigblob);

	/* hash the data */
	hash_alg = key_ec_nid_to_hash_alg(key->ecdsa_nid);
	if ((dlen = ssh_digest_bytes(hash_alg)) == 0) {
		error("%s: bad hash algorithm %d", __func__, hash_alg);
		return -1;
	}
	if (ssh_digest_memory(hash_alg, data, datalen,
	    digest, sizeof(digest)) != 0) {
		error("%s: digest_memory failed", __func__);
		return -1;
	}

	ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
	explicit_bzero(digest, sizeof(digest));

	ECDSA_SIG_free(sig);

	debug("%s: signature %s", __func__,
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}
Пример #9
0
int
mm_answer_keyallowed(int sock, Buffer *m)
{
	struct sshkey *key;
	char *cuser, *chost;
	u_char *blob;
	u_int bloblen, pubkey_auth_attempt;
	enum mm_keytype type = 0;
	int allowed = 0;

	debug3("%s entering", __func__);

	type = buffer_get_int(m);
	cuser = buffer_get_string(m, NULL);
	chost = buffer_get_string(m, NULL);
	blob = buffer_get_string(m, &bloblen);
	pubkey_auth_attempt = buffer_get_int(m);

	key = key_from_blob(blob, bloblen);

	debug3("%s: key_from_blob: %p", __func__, key);

	if (key != NULL && authctxt->valid) {
		/* These should not make it past the privsep child */
		if (key_type_plain(key->type) == KEY_RSA &&
		    (datafellows & SSH_BUG_RSASIGMD5) != 0)
			fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__);

		switch (type) {
		case MM_USERKEY:
			allowed = options.pubkey_authentication &&
			    !auth2_key_already_used(authctxt, key) &&
			    match_pattern_list(sshkey_ssh_name(key),
			    options.pubkey_key_types, 0) == 1 &&
			    user_key_allowed(authctxt->pw, key,
			    pubkey_auth_attempt);
			auth_method = "publickey";
			if (options.pubkey_authentication &&
			    (!pubkey_auth_attempt || allowed != 1))
				auth_clear_options();
			break;
		case MM_HOSTKEY:
			allowed = options.hostbased_authentication &&
			    !auth2_key_already_used(authctxt, key) &&
			    match_pattern_list(sshkey_ssh_name(key),
			    options.hostbased_key_types, 0) == 1 &&
			    hostbased_key_allowed(authctxt->pw,
			    cuser, chost, key);
			auth2_record_info(authctxt,
			    "client user \"%.100s\", client host \"%.100s\"",
			    cuser, chost);
			auth_method = "hostbased";
			break;
		default:
			fatal("%s: unknown key type %d", __func__, type);
			break;
		}
	}

	debug3("%s: key is %s", __func__, allowed ? "allowed" : "not allowed");

	auth2_record_key(authctxt, 0, key);
	sshkey_free(key);

	/* clear temporarily storage (used by verify) */
	monitor_reset_key_state();

	if (allowed) {
		/* Save temporarily for comparison in verify */
		key_blob = blob;
		key_bloblen = bloblen;
		key_blobtype = type;
		hostbased_cuser = cuser;
		hostbased_chost = chost;
	} else {
		/* Log failed attempt */
		auth_log(authctxt, 0, 0, auth_method, NULL);
		free(blob);
		free(cuser);
		free(chost);
	}

	buffer_clear(m);
	buffer_put_int(m, allowed);
	buffer_put_int(m, forced_command != NULL);

	mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m);

	return (0);
}