public String authenticate(UserManager userMgr, Subject subject, Callback[] callbacks)
			throws LoginException {

		GhidraPrincipal user = GhidraPrincipal.getGhidraPrincipal(subject);
		if (user == null) {
			throw new FailedLoginException("GhidraPrincipal required");
		}
		String username = user.getName();

		NameCallback nameCb = null;
		SSHSignatureCallback sshCb = null;
		if (callbacks != null) {
			for (int i = 0; i < callbacks.length; i++) {
				if (callbacks[i] instanceof NameCallback) {
					nameCb = (NameCallback) callbacks[i];
				}
				if (callbacks[i] instanceof SSHSignatureCallback) {
					sshCb = (SSHSignatureCallback) callbacks[i];
				}
			}
		}

		if (nameCallbackAllowed && nameCb != null) {
			username = nameCb.getName();
		}
		if (username == null || username.length() == 0) {
			throw new FailedLoginException("User ID must be specified");
		}
		if (!userMgr.isValidUser(username)) {
			throw new FailedLoginException("Unknown user: " + username);
		}

		if (sshCb == null) {
			throw new FailedLoginException(
				"SSH Signature callback not found for user: " + username);
		}

		File sshPublicKeyFile = userMgr.getSSHPubKeyFile(username);
		if (sshPublicKeyFile == null) {
			throw new FailedLoginException("SSH public key file not found for user: " + username);
		}

		byte[] sigBytes = sshCb.getSignature();
		if (sigBytes == null) {
			throw new FailedLoginException("SSH Signature missing");
		}

		byte[] token = sshCb.getToken();
		if (!TokenGenerator.isRecentToken(token, MAX_TOKEN_TIME)) {
			throw new FailedLoginException("Stale SSH Signature callback");
		}

		boolean isValid = false;
		try {
			boolean usingSelfSignedCert =
				ApplicationKeyManagerFactory.usingGeneratedSelfSignedCertificate();
			isValid = ApplicationKeyManagerUtils.isMySignature(
				usingSelfSignedCert ? null : ApplicationKeyManagerUtils.getTrustedIssuers(), token,
				sshCb.getServerSignature());
		}
		catch (Exception e) {
			throw new RuntimeException("Unable to verify signed token", e);
		}
		if (!isValid) {
			throw new FailedLoginException("Invalid SSH Signature callback");
		}

		try {
			ByteArrayInputStream in = new ByteArrayInputStream(sigBytes);
			String keyAlgorithm = Strings.fromByteArray(sshBufferReadBlock(in));
			byte[] sig = sshBufferReadBlock(in);
			if (in.available() != 0) {
				throw new FailedLoginException("SSH Signature contained extra bytes");
			}

			CipherParameters cipherParams = SSHKeyManager.getSSHPublicKey(sshPublicKeyFile);

			if (cipherParams instanceof RSAKeyParameters) {
				if (!"ssh-rsa".equals(keyAlgorithm)) {
					throw new FailedLoginException("Invalid SSH RSA Signature");
				}
				RSADigestSigner signer = new RSADigestSigner(new SHA1Digest());
				signer.init(false, cipherParams);
				signer.update(token, 0, token.length);
				if (!signer.verifySignature(sig)) {
					throw new FailedLoginException("Incorrect signature");
				}
			}
			else if (cipherParams instanceof DSAKeyParameters) {
				if (!"ssh-dss".equals(keyAlgorithm)) {
					throw new FailedLoginException("Invalid SSH DSA Signature");
				}
				DSADigestSigner signer = new DSADigestSigner(new DSASigner(), new SHA1Digest());
				signer.init(false, cipherParams);
				signer.update(token, 0, token.length);
				if (!signer.verifySignature(sig)) {
					throw new FailedLoginException("Incorrect signature");
				}
			}
			else {
				throw new FailedLoginException("Unsupported public key");
			}

		}
		catch (LoginException e) {
			throw e;
		}
		catch (Throwable t) {
			String msg = t.getMessage();
			if (msg == null) {
				msg = t.toString();
			}
			throw new FailedLoginException(msg);
		}
		return username;
	}
Complete the authentication process
@param userMgr Ghidra server user manager
@param subject unauthenticated user ID (must be used if name callback not provided/allowed)
@param callbacks authentication callbacks
@return authenticated user ID (may come from callbacks)
@throws LoginException if authentication failure occurs
Ghidra/Features/GhidraServer/src/main/java/ghidra/server/security/SSHAuthenticationModule.java