protected Boolean doAuth()

in sshd-core/src/main/java/org/apache/sshd/server/auth/hostbased/UserAuthHostBased.java [76:193]


    protected Boolean doAuth(Buffer buffer, boolean init) throws Exception {
        ValidateUtils.checkTrue(init, "Instance not initialized");

        int dataLen = buffer.available();
        String username = getUsername();
        ServerSession session = getSession();
        String keyType = buffer.getString();
        int keyLen = buffer.getInt();
        int keyOffset = buffer.rpos();
        int remaining = buffer.available();
        // Protect against malicious or corrupted packets
        if ((keyLen < 0) || (keyLen > remaining)) {
            log.error("doAuth({}@{}) Illogical {} key length={} (max. available={})",
                    username, session, keyType, keyLen, remaining);
            throw new IndexOutOfBoundsException("Illogical " + keyType + " key length: " + keyLen);
        }

        Buffer buf = new ByteArrayBuffer(buffer.array(), keyOffset, keyLen, true);
        PublicKey clientKey = buf.getRawPublicKey();
        List<X509Certificate> certs = Collections.emptyList();
        remaining = buf.available();
        if (remaining > 0) {
            CertificateFactory cf = SecurityUtils.getCertificateFactory("X.509");
            certs = new ArrayList<>();
            try (ByteArrayInputStream bais = new ByteArrayInputStream(buf.array(), buf.rpos(), remaining)) {
                X509Certificate c = (X509Certificate) cf.generateCertificate(bais);
                certs.add(c);
            }
        }

        buffer.rpos(keyOffset + keyLen);
        String clientHostName = buffer.getString();
        String clientUsername = buffer.getString();

        byte[] signature = buffer.getBytes();
        boolean debugEnabled = log.isDebugEnabled();
        if (debugEnabled) {
            log.debug("doAuth({}@{}) authenticate key type={}, fingerprint={}, client={}@{}, num-certs={}",
                    username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                    clientUsername, clientHostName, GenericUtils.size(certs));
        }

        HostBasedAuthenticator authenticator = session.getHostBasedAuthenticator();
        if (authenticator == null) {
            if (debugEnabled) {
                log.debug("doAuth({}@{}) key type={}, fingerprint={}, client={}@{}, num-certs={} - no authenticator",
                        username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                        clientUsername, clientHostName, GenericUtils.size(certs));
            }
            return Boolean.FALSE;
        }

        boolean authed;
        try {
            authed = authenticator.authenticate(
                    session, username, clientKey, clientHostName, clientUsername, certs);
        } catch (Error e) {
            warn("doAuth({}@{}) failed ({}) to consult authenticator for {} key={}: {}",
                    username, session, e.getClass().getSimpleName(),
                    keyType, KeyUtils.getFingerPrint(clientKey), e.getMessage(), e);
            throw new RuntimeSshException(e);
        }

        if (debugEnabled) {
            log.debug("doAuth({}@{}) key type={}, fingerprint={}, client={}@{}, num-certs={} - authentication result: {}",
                    username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                    clientUsername, clientHostName, GenericUtils.size(certs), authed);
        }
        if (!authed) {
            return Boolean.FALSE;
        }

        // verify signature
        Collection<NamedFactory<Signature>> factories = ValidateUtils.checkNotNullAndNotEmpty(
                SignatureFactoriesManager.resolveSignatureFactories(this, session),
                "No signature factories for session=%s",
                session);
        Signature verifier = ValidateUtils.checkNotNull(
                NamedFactory.create(factories, keyType),
                "No verifier located for algorithm=%s",
                keyType);
        verifier.initVerifier(session, clientKey);

        byte[] id = session.getSessionId();
        buf = new ByteArrayBuffer(dataLen + id.length + Long.SIZE, false);
        buf.putBytes(id);
        buf.putByte(SshConstants.SSH_MSG_USERAUTH_REQUEST);
        buf.putString(username);
        buf.putString(getService());
        buf.putString(getName());
        buf.putString(keyType);
        buf.putUInt(keyLen);
        // copy the key + certificates
        buf.putRawBytes(buffer.array(), keyOffset, keyLen);
        buf.putString(clientHostName);
        buf.putString(clientUsername);

        if (log.isTraceEnabled()) {
            log.trace("doAuth({}@{}) key type={}, fingerprint={}, client={}@{}, num-certs={} - verification data: {}",
                    username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                    clientUsername, clientHostName, GenericUtils.size(certs), buf.toHex());
            log.trace("doAuth({}@{}) key type={}, fingerprint={}, client={}@{}, num-certs={} - expected signature: {}",
                    username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                    clientUsername, clientHostName, GenericUtils.size(certs), BufferUtils.toHex(signature));
        }

        verifier.update(session, buf.array(), buf.rpos(), buf.available());
        if (!verifier.verify(session, signature)) {
            throw new SignatureException("Key verification failed");
        }

        if (debugEnabled) {
            log.debug("doAuth({}@{}) key type={}, fingerprint={}, client={}@{}, num-certs={} - verified signature",
                    username, session, keyType, KeyUtils.getFingerPrint(clientKey),
                    clientUsername, clientHostName, GenericUtils.size(certs));
        }
        return Boolean.TRUE;
    }