Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MySQL 8 SHA256 Support #906

Closed
normano opened this issue Jan 5, 2019 · 8 comments
Closed

MySQL 8 SHA256 Support #906

normano opened this issue Jan 5, 2019 · 8 comments

Comments

@normano
Copy link
Contributor

normano commented Jan 5, 2019

Hey, I'm wondering if you still planned on adding mysql 8 support. I did find one branch on here that has your WIP changes for it and I wonder if you will continue with it? I might switch to mysqljs since they are close to merging support. I was trying to do it myself but I don't understand it enough! The first marker in the handsahake is 254 and then it comes back with 1 and data is 0x04 which I guess it wants the FullAuthentication to be performed.

@normano normano changed the title MySQL 8 Support MySQL 8 SHA256 Support Jan 5, 2019
@sidorares
Copy link
Owner

yes, I'm planning to work on this some time but if anyone would like to contribute that would be great

One way I want to implement this differently from mysqljs/mysql#1962 is to have it part of auth plugin system and not treat specially. Unfortunately I discovered that auth plugin need big rewrite as well

I'm happy to answer any questions you have re auth plugins in general and sha256 particularily here @normano !

@normano
Copy link
Contributor Author

normano commented Jan 5, 2019

Did you have any spec for the rewrite? I don't know enough about MySQL auth, but I'm curious to know where you are going with your client side plugin support.

I'm gonna try again today, maybe I can respond to the FullAuthentication request properly and make it work.

@sidorares
Copy link
Owner

I'll try to document more later, but here are few starting points:

Auth switch packet documentation: https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest

Current api: https://github.com/sidorares/node-mysql2/blob/master/documentation/Authentication-Switch.md implemented in

connection.config.authSwitchHandler(
authSwitchHandlerParams,
(err, data) => {
if (err) {
connection.emit('error', err);
return;
}
connection.writePacket(
new Packets.AuthSwitchResponse(data).toPacket()
);
}
);

Problem with current api is that it's difficult to make plugin that supports multiple responses from server and maintains state

Also see #560

@normano
Copy link
Contributor Author

normano commented Jan 5, 2019

Still trying to attempt this, but seems fullauthentication request (plugindata == 0x04) is requested then need to send clear text pass if ssl is not enabled.

if(authSwitchHandlerParams.pluginData.toString("hex") === "04") {
connection.writePacket(new Packets.ClearText(this.password).toPacket());
}
return null; // Not sure if this is correct

if fast path (0x03) then I just return null currently.

Seems like the auth worked, but then get
Warning: got packets out of order. Expected 1 but received 5
Warning: got packets out of order. Expected 2 but received 1
Warning: got packets out of order. Expected 3 but received 2
Warning: got packets out of order. Expected 4 but received 3
Warning: got packets out of order. Expected 5 but received 4
Warning: got packets out of order. Expected 6 but received 5
Warning: got packets out of order. Expected 7 but received 6
Warning: got packets out of order. Expected 8 but received 7
Warning: got packets out of order. Expected 9 but received 8

:(

Cleartext class looks like

class ClearText {
  constructor(data) {
    if (!Buffer.isBuffer(data)) {
      data = Buffer.from(data);
    }
    this.data = data;
  }

  toPacket() {
    const length = this.data.length + 5;
    const buffer = Buffer.allocUnsafe(length);
    const packet = new Packet(0, buffer, 0, length);
    packet.writeBuffer(this.data);
    packet.writeInt8(0);
    return packet;
  }

  static fromPacket(packet) {
    const data = packet.readBuffer();
    return new ClearText(data);
  }
}

@normano
Copy link
Contributor Author

normano commented Jan 5, 2019

So i modified the return null to instead return () => false; and now I can query. I think that is for the OK packet which I guess is sequenceId 5 and when i return false that means the transaction is done, so reset the sequence Id.

Not the best if that OK packet is instead an error packet right? Error packet I think would not go through this code path anyway, but I don't know that.

@normano
Copy link
Contributor Author

normano commented Jan 5, 2019

For anyone else who is interested: https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/ has some graphs as well as exchange info here https://dev.mysql.com/doc/dev/mysql-server/8.0.4/page_caching_sha2_authentication_exchanges.html

I'm a newbie to this, but was curious about how it worked. Didn't see much getting done here from nodejs side, so I hope what I posted here was helpful enough for people to contribute. I'll likely fork the repo here and commit my partial changes.

@normano
Copy link
Contributor Author

normano commented Jan 5, 2019

Here are my changes: https://github.com/normano/node-mysql2/commit/2caf07bdab7c37646df5f9748b30b46aa845944c Definitely rough, but works for non ssl connection. @sidorares I hope you can see the need for writing custom packets to the connection here when you pass control to a custom authplugin.

@iblessedi
Copy link

How are things going now? Can I use this library with mysql 8 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants