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

insecureAuth support (was: bad handshake) #30

Open
mscdex opened this issue Aug 14, 2013 · 35 comments
Open

insecureAuth support (was: bad handshake) #30

mscdex opened this issue Aug 14, 2013 · 35 comments
Labels
enhancement mysqljs-mysql-incompatibilities Previously: feligxe-mysql-incompatibilities

Comments

@mscdex
Copy link
Contributor

mscdex commented Aug 14, 2013

Output: 'Query error: Bad handshake'

Server: MySQL server 5.0.95 (Linux)

Code:

var mysql = require('mysql2');

var config = {
  host: '127.0.0.1',
  user: 'user',
  password: 'password',
  database: 'database',
  typeCast: false,
  supportBigNumbers: true,
  bigNumberStrings: true,
  insecureAuth: true
}, c;

function doConnect() {
  c = mysql.createConnection(config);
  c.connect(function(err) {
    console.log('Client connected');
  });
  c.on('error', function(err) {
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
      console.log('Disconnected -- reconnecting ...');
      doConnect();
    } else
      throw err;
  });
}

function doQuery() {
  var count = 0;

  console.log('starting query ...');

  c.query('select * from foo')
   .on('error', function(err) {
     console.log('Query error: ' + err);
   })
   .on('result', function(row) {
     ++count;
   })
   .once('end', function(info) {
     console.log('Query finished successfully');
     console.log(count + ' rows');
   });
}

doConnect();
doQuery();
@mscdex
Copy link
Contributor Author

mscdex commented Aug 14, 2013

I should note that the same code works with the 'mysql' module.

@sidorares
Copy link
Owner

Thanks, Brian.

can't confirm it on osx/mysql 5.6.10
I'll try linux/mysql 5.0.95. Can you post foo schema? Should not affect connection error though...

sh-3.2$ node qqq.js
starting query ...
Client connected
Query finished successfully
50001 rows
tmp ❯ mysql test                                                                                                                                                                                                                                                              ⏎
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 367
Server version: 5.6.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show create table insert_test;
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                     |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| insert_test | CREATE TABLE `insert_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12313334 DEFAULT CHARSET=utf8 |
+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

@mscdex
Copy link
Contributor Author

mscdex commented Aug 14, 2013

It happens with any schema. It may have something to do with 'insecureAuth' ?

@sidorares
Copy link
Owner

probably. I think this makes client connect with no PROTOCOL_41 flag. Which version of mysql2 are you using? Is that from npm or git master?

@mscdex
Copy link
Contributor Author

mscdex commented Aug 14, 2013

npm

@sidorares
Copy link
Owner

Still can't reproduce, and I'm sure I don't support insecure auth at the moment (flag is ignored)

@sidorares
Copy link
Owner

Do you have this error if you comment out insecureAuth: true?

@sidorares
Copy link
Owner

also this is what I have:

mysql> SHOW VARIABLES LIKE 'old_passwords';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| old_passwords | OFF   |
+---------------+-------+
1 row in set (0.01 sec)

@mscdex
Copy link
Contributor Author

mscdex commented Aug 14, 2013

It looks like insecureAuth doesn't do anything currently. Grep returns:

mysql2/lib/connection_config.js:  this.insecureAuth       = options.insecureAuth || false;

@sidorares
Copy link
Owner

you are right, it is ignored. Not sure why your connection fails though

@mscdex
Copy link
Contributor Author

mscdex commented Aug 14, 2013

I created a new user using the new password format and that connected fine.

@sidorares
Copy link
Owner

I changed the caption. Will close this issue once pre insecure auth is supported.

Current problems:
secure auth is always used -
server insecure auth flag is ignored and client still tries to connect using secure auth method;
client insecure auth flag is ignored and there is no way to force insecure connection.

@sidorares sidorares added this to the 0.15.1 milestone Jan 9, 2015
@sidorares sidorares removed this from the 0.15.2 milestone May 23, 2016
@midnightcodr
Copy link

midnightcodr commented Jan 3, 2018

I am trying to switch from using mysqljs/mysql to mysql2@1.5.1 but unfortunately I can't because insecureAuth is not supported. Everything including insecureAuth is working fine with mysqljs/mysql. So far this is the only road blocker for my project. I understand that changing the password format for the user will fix the issue but that option is out of the question now as we are afraid that change might break other parts of our system. Any plan to add full support for this option @sidorares? Thanks.

@sidorares
Copy link
Owner

@midnightcodr does your server support plugin authentication / authentication switch ? ( if you connect with debug: true you'll see that in 'server capabilities flags' line

If yes, insecureAuth can be added as authentication switch plugin via config ( and I'd like to make this to happen automatically when insecureAuth is on )

@midnightcodr
Copy link

@sidorares plugin auth is in the capability flags list. How does insecureAuth can be added as authentication switch plugin via config work exactly? I am getting Unhandled promise rejection (rejection id: 1): Error: Server requires auth switch, but no auth switch handler provided with the basic { host, user, password, database, debug: true} config.

@sidorares
Copy link
Owner

@midnightcodr at the moment it's not very trivial. You'll need to port this code https://github.com/mysqljs/mysql/blob/3f371ca18a46150fc1fe1b8bb31a099b9f62f2fb/lib/protocol/Auth.js#L37-L152 and put it into handler similar to implementation for mysql_clear_plugin in #438 (comment)

@sidorares
Copy link
Owner

this is also relevant - #504

one problem could be that plugin name is reported as empty string - can you verify this? ( add console log in auth switch handler )

@midnightcodr
Copy link

I got

{ pluginName: 'mysql_old_password',
  pluginData: ...
}

with authSwitchHandler: function(data, cb) { console.log(data) }. Will give the implementations you mentioned above a try. Thank you.

@sidorares
Copy link
Owner

ok cool. So what you need to add is

function(data, cb) {
  if (data.pluginName === 'mysql_old_password') {
     cb(null, authenticateMysqlOldPassword(yourPassword, data.pluginData))
  }
}

where authenticateMysqlOldPassword is code similar to https://github.com/mysqljs/mysql/blob/3f371ca18a46150fc1fe1b8bb31a099b9f62f2fb/lib/protocol/Auth.js#L37-L152

@sidorares
Copy link
Owner

this is how it's used in mysqljs/mysql: https://github.com/mysqljs/mysql/blob/e8fea7068476ac65d78532bbf786d6393502f54b/lib/protocol/sequences/Handshake.js#L124

So basically to test you can copy/paste whole Auth.js to your code, require it and have handler like this:

function(data, cb) {
  if (data.pluginName === 'mysql_old_password') {
    cb(null, Auth.scramble323(data.pluginData, password))
  }
}

@midnightcodr
Copy link

You meant Auth.hashPassword? But it only takes one argument. Sorry for so many newbie questions.

@midnightcodr
Copy link

Never mind, just saw your new comment after I posted mine.

@sidorares
Copy link
Owner

that's ok, they don't look newbie at all!

@midnightcodr
Copy link

Got it working. Can't thank you enough @sidorares for your help.

@sidorares
Copy link
Owner

great! you you think you can find time to port this to mysql2 core that would be great!

Pseudo code:

  • add lib/auth_323.js code with scramble323 and dependent functions
  • at
    if (authSwitchHandlerParams.pluginName == 'mysql_native_password') {
    similar to native password add second if: if name is old_password, check if insecureAuth is on and respond with scramble323. If it's not on, respond with meaningful error

Don't be stressed if you don't have time or experience to do this, in that case these are notes to future me

@midnightcodr
Copy link

Would definitely give it a try.

@sidorares
Copy link
Owner

maybe would be good to allow and bundle switch handler plugin for mysql_clear_password if insecureAuth is on - see code in #438 (comment)

@midnightcodr
Copy link

@sidorares I am getting an empty authSwitchHandlerParams.pluginName when trying to implement what you suggested. marker has a value of 0xfe, asr is

AuthSwitchRequest { pluginName: '', pluginData: <Buffer > }

@sidorares
Copy link
Owner

you mentioned earlier that you getting pluginName: 'mysql_old_password'? Can you give a bit more context what's different now when you have pluginName: ''?

@midnightcodr
Copy link

@sidorares sorry my bad. I am getting empty pluginName in the if clause after line 160 in node-mysql2/lib/commands/client_handshake.js. The non-empty pluginName was from the authSwitchHandler: function(data, cb) { console.log(data) } option while initializing the connection.

The mysql server version I am testing against is 5.6.20.

I am using the following code to do a quick test:

const mysql = require('./promise')
// previously defined host, user, password & database
const opts = { host, user, password, database, insecureAuth: true}

const run = async() => {
    const conn = await mysql.createConnection(opts)
    const [rows, fields] = await conn.query('select 100 as result')
    console.log(rows)
    await conn.end()
}

run()

I have forked the repo on another computer but I was not able to commit due to a linting issue. Will show you the changes to the files you mentioned once I am able to commit and push my code.

@midnightcodr
Copy link

Pulling my hair out but I can't figure out even the simplest update I made can't pass pre-commit.

screen shot 2018-01-04 at 3 05 02 pm

To replicate:

  1. fork the repo

  2. clone the forked repo to your local computer

  3. make a simple change to, for example, lib/commands/client_handshake.js
    screen shot 2018-01-04 at 3 18 24 pm

  4. git add and git commit, I got the problem in the first screenshot

@sidorares
Copy link
Owner

@midnightcodr which version of prettier gets installed after you do npm install? Need to double check if we use exact version numbers and/or package-lock

@midnightcodr
Copy link

@sidorares

package-lock.json: "version": "https://registry.npmjs.org/prettier/-/prettier-1.3.1.tgz",
package.json: "prettier": "^1.3.1",
node_modules/prettier/package.json: "version": "1.9.2"

Somehow the version installed (1.9.2) is different to what states in package (and -lock).json. More strangely I can't uninstall prettier by

npm uninstall prettier

Which returns

npm ERR! Cannot read property '0' of undefined

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/username/.npm/_logs/2018-01-05T18_09_13_219Z-debug.log

@nwohaibi
Copy link

@sidorares
facing the same issue with empty pluginName string.
MySQL 5.0.95
same code works with the 'mysql' module.

@sidorares
Copy link
Owner

@nwohaibi this is currently relatively low priority for me ( adding insecure 323 password ). Though if we can find reliable way to handle this via authPlugins that would be good. I'll need instructions to replicate this from scratch ( ideally image on docker hub? ) to progress on this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement mysqljs-mysql-incompatibilities Previously: feligxe-mysql-incompatibilities
Projects
None yet
Development

No branches or pull requests

4 participants