Search in sources :

Example 6 with ServerSession

use of com.mysql.cj.protocol.ServerSession in project ABC by RuiPinto96274.

the class NativeAuthenticationProvider method proceedHandshakeWithPluggableAuthentication.

/**
 * Performs an authentication handshake to authorize connection to a given database as a given MySQL user.
 * This can happen upon initial connection to the server, after receiving Auth Challenge Packet, or
 * at any moment during the connection life-time via a Change User request.
 *
 * This method will use registered authentication plugins as requested by the server.
 *
 * @param challenge
 *            the Auth Challenge Packet received from server if
 *            this method is used during the initial connection.
 *            Otherwise null.
 */
private void proceedHandshakeWithPluggableAuthentication(final NativePacketPayload challenge) {
    ServerSession serverSession = this.protocol.getServerSession();
    if (this.authenticationPlugins == null) {
        loadAuthenticationPlugins();
    }
    boolean forChangeUser = true;
    if (challenge != null) {
        this.serverDefaultAuthenticationPluginName = challenge.readString(StringSelfDataType.STRING_TERM, "ASCII");
        forChangeUser = false;
    }
    serverSession.getCharsetSettings().configurePreHandshake(forChangeUser);
    /*
         * Select the initial plugin:
         * Choose the client-side default authentication plugin, if explicitely specified, otherwise choose the server-side default authentication plugin.
         */
    String pluginName;
    if (this.clientDefaultAuthenticationPluginExplicitelySet) {
        pluginName = this.clientDefaultAuthenticationPluginName;
    } else {
        pluginName = this.serverDefaultAuthenticationPluginName != null ? this.serverDefaultAuthenticationPluginName : this.clientDefaultAuthenticationPluginName;
    }
    AuthenticationPlugin<NativePacketPayload> plugin = getAuthenticationPlugin(pluginName);
    if (plugin == null) {
        /* Use default if there is no plugin for pluginName. */
        pluginName = this.clientDefaultAuthenticationPluginName;
        plugin = getAuthenticationPlugin(pluginName);
    }
    boolean skipPassword = false;
    if (pluginName.equals(Sha256PasswordPlugin.PLUGIN_NAME) && !pluginName.equals(this.clientDefaultAuthenticationPluginName) && !this.protocol.getSocketConnection().isSSLEstablished() && this.propertySet.getStringProperty(PropertyKey.serverRSAPublicKeyFile).getValue() == null && !this.propertySet.getBooleanProperty(PropertyKey.allowPublicKeyRetrieval).getValue()) {
        /*
             * Fall back to client default if plugin is 'sha256_password' but required conditions for this to work aren't met.
             * If client default is other than 'sha256_password', this will result in an immediate authentication switch request, allowing for other plugins to
             * authenticate successfully. If client default is 'sha256_password' then the authentication will fail as expected. In both cases user's password
             * won't be sent to avoid subjecting it to lesser security levels.
             */
        plugin = getAuthenticationPlugin(this.clientDefaultAuthenticationPluginName);
        skipPassword = true;
    }
    checkConfidentiality(plugin);
    // Servers not affected by Bug#70865 expect the Change User Request containing a correct answer to seed sent by the server during the initial handshake,
    // thus we reuse it here. Servers affected by Bug#70865 will just ignore it and send the Auth Switch.
    NativePacketPayload fromServer = new NativePacketPayload(StringUtils.getBytes(this.seed));
    String sourceOfAuthData = this.serverDefaultAuthenticationPluginName;
    boolean old_raw_challenge = false;
    NativePacketPayload last_sent = null;
    NativePacketPayload last_received = challenge;
    ArrayList<NativePacketPayload> toServer = new ArrayList<>();
    /* Max iterations number */
    int counter = 100;
    while (0 < counter--) {
        /*
             * call plugin
             */
        plugin.setAuthenticationParameters(this.username, skipPassword ? null : this.password);
        plugin.setSourceOfAuthData(sourceOfAuthData);
        plugin.nextAuthenticationStep(fromServer, toServer);
        /*
             * send response to server
             */
        if (toServer.size() > 0) {
            if (forChangeUser) {
                // write COM_CHANGE_USER Packet
                last_sent = createChangeUserPacket(serverSession, plugin.getProtocolPluginName(), toServer);
                this.protocol.send(last_sent, last_sent.getPosition());
                // this branch should be executed only once
                forChangeUser = false;
            } else if (last_received.isAuthMethodSwitchRequestPacket() || last_received.isAuthMoreData() || old_raw_challenge) {
                // write AuthSwitchResponse packet or raw packet(s)
                for (NativePacketPayload buffer : toServer) {
                    this.protocol.send(buffer, buffer.getPayloadLength());
                }
            } else {
                // write HandshakeResponse packet
                last_sent = createHandshakeResponsePacket(serverSession, plugin.getProtocolPluginName(), toServer);
                this.protocol.send(last_sent, last_sent.getPosition());
            }
        }
        /*
             * read packet from server
             */
        last_received = this.protocol.checkErrorMessage();
        old_raw_challenge = false;
        if (last_received.isOKPacket()) {
            // read OK packet
            OkPacket ok = OkPacket.parse(last_received, null);
            serverSession.setStatusFlags(ok.getStatusFlags(), true);
            serverSession.getServerSessionStateController().setSessionStateChanges(ok.getSessionStateChanges());
            // if OK packet then finish handshake
            plugin.destroy();
            break;
        } else if (last_received.isAuthMethodSwitchRequestPacket()) {
            // read AuthSwitchRequest Packet
            skipPassword = false;
            pluginName = last_received.readString(StringSelfDataType.STRING_TERM, "ASCII");
            if (plugin.getProtocolPluginName().equals(pluginName)) {
                // just reset the current one
                plugin.reset();
            } else {
                // get new plugin
                plugin.destroy();
                plugin = getAuthenticationPlugin(pluginName);
                if (plugin == null) {
                    throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("AuthenticationProvider.BadAuthenticationPlugin", new Object[] { pluginName }), getExceptionInterceptor());
                }
            }
            checkConfidentiality(plugin);
            fromServer = new NativePacketPayload(last_received.readBytes(StringSelfDataType.STRING_EOF));
        } else {
            // read raw packet
            if (!this.protocol.versionMeetsMinimum(5, 5, 16)) {
                old_raw_challenge = true;
                last_received.setPosition(last_received.getPosition() - 1);
            }
            fromServer = new NativePacketPayload(last_received.readBytes(StringSelfDataType.STRING_EOF));
        }
        sourceOfAuthData = pluginName;
    }
    if (counter == 0) {
        throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("CommunicationsException.TooManyAuthenticationPluginNegotiations"), getExceptionInterceptor());
    }
    this.protocol.afterHandshake();
    if (!this.useConnectWithDb) {
        this.protocol.changeDatabase(this.database);
    }
}
Also used : ServerSession(com.mysql.cj.protocol.ServerSession) OkPacket(com.mysql.cj.protocol.a.result.OkPacket) ArrayList(java.util.ArrayList) WrongArgumentException(com.mysql.cj.exceptions.WrongArgumentException)

Aggregations

ServerSession (com.mysql.cj.protocol.ServerSession)6 SslMode (com.mysql.cj.conf.PropertyDefinitions.SslMode)4 UnableToConnectException (com.mysql.cj.exceptions.UnableToConnectException)4 WrongArgumentException (com.mysql.cj.exceptions.WrongArgumentException)3 OkPacket (com.mysql.cj.protocol.a.result.OkPacket)3 ArrayList (java.util.ArrayList)3 Constants (com.mysql.cj.Constants)1 Messages (com.mysql.cj.Messages)1 MysqlCallbackHandler (com.mysql.cj.callback.MysqlCallbackHandler)1 UsernameCallback (com.mysql.cj.callback.UsernameCallback)1 PropertyKey (com.mysql.cj.conf.PropertyKey)1 PropertySet (com.mysql.cj.conf.PropertySet)1 RuntimeProperty (com.mysql.cj.conf.RuntimeProperty)1 ExceptionFactory (com.mysql.cj.exceptions.ExceptionFactory)1 ExceptionInterceptor (com.mysql.cj.exceptions.ExceptionInterceptor)1 AuthenticationPlugin (com.mysql.cj.protocol.AuthenticationPlugin)1 AuthenticationProvider (com.mysql.cj.protocol.AuthenticationProvider)1 Protocol (com.mysql.cj.protocol.Protocol)1 IntegerDataType (com.mysql.cj.protocol.a.NativeConstants.IntegerDataType)1 StringLengthDataType (com.mysql.cj.protocol.a.NativeConstants.StringLengthDataType)1