From 68b909726b25255437f4f7500bcb16d29cb924f6 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 4 Sep 2006 17:55:28 +0000 Subject: Fixed the Ruby/MySQL adapter we ship with Active Record to work with the new authentication handshake that was introduced in MySQL 4.1, along with the other protocol changes made at that time (closes #5723) [jimw@mysql.com] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4990 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/CHANGELOG | 2 ++ activerecord/lib/active_record/vendor/mysql.rb | 25 ++++++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index c316f3b66d..c0815198c2 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Fixed the Ruby/MySQL adapter we ship with Active Record to work with the new authentication handshake that was introduced in MySQL 4.1, along with the other protocol changes made at that time #5723 [jimw@mysql.com] + * Deprecation: use :dependent => :delete_all rather than :exclusively_dependent => true. #6024 [Josh Susser] * Document validates_presences_of behavior with booleans: you probably want validates_inclusion_of :attr, :in => [true, false]. #2253 [Bob Silva] diff --git a/activerecord/lib/active_record/vendor/mysql.rb b/activerecord/lib/active_record/vendor/mysql.rb index 2599f4337b..0d8cc2efd8 100644 --- a/activerecord/lib/active_record/vendor/mysql.rb +++ b/activerecord/lib/active_record/vendor/mysql.rb @@ -6,7 +6,7 @@ class Mysql - VERSION = "4.0-ruby-0.2.5" + VERSION = "4.0-ruby-0.2.6-plus-changes" require "socket" require "digest/sha1" @@ -18,6 +18,9 @@ class Mysql MYSQL_PORT = 3306 PROTOCOL_VERSION = 10 + SCRAMBLE_LENGTH = 20 + SCRAMBLE_LENGTH_323 = 8 + # Command COM_SLEEP = 0 COM_QUIT = 1 @@ -147,12 +150,23 @@ class Mysql @db = db.dup end write data - read + pkt = read + handle_auth_fallback(pkt, passwd) ObjectSpace.define_finalizer(self, Mysql.finalizer(@net)) self end alias :connect :real_connect + def handle_auth_fallback(pkt, passwd) + # A packet like this means that we need to send an old-format password + if pkt.size == 1 and pkt[0] == 254 and + @server_capabilities & CLIENT_SECURE_CONNECTION != 0 then + data = scramble(passwd, @scramble_buff, @protocol_version == 9) + write data + "\0" + read + end + end + def escape_string(str) Mysql::escape_string str end @@ -208,7 +222,8 @@ class Mysql else data = user+"\0"+scramble41(passwd, @scramble_buff)+db end - command COM_CHANGE_USER, data + pkt = command COM_CHANGE_USER, data + handle_auth_fallback(pkt, passwd) @user = user @passwd = passwd @db = db @@ -534,10 +549,10 @@ class Mysql return "" if password == nil or password == "" raise "old version password is not implemented" if old_ver hash_pass = hash_password password - hash_message = hash_password message + hash_message = hash_password message.slice(0,SCRAMBLE_LENGTH_323) rnd = Random::new hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1] to = [] - 1.upto(message.length) do + 1.upto(SCRAMBLE_LENGTH_323) do to << ((rnd.rnd*31)+64).floor end extra = (rnd.rnd*31).floor -- cgit v1.2.3