diff --git a/src/protocol/MySQLMessage.cc b/src/protocol/MySQLMessage.cc index b724e1a4..b043ae0a 100644 --- a/src/protocol/MySQLMessage.cc +++ b/src/protocol/MySQLMessage.cc @@ -186,14 +186,14 @@ int MySQLHandshakeResponse::encode(struct iovec vectors[], int max) buf_.append((const char *)&protocol_version_, 1); buf_.append(server_version_.c_str(), server_version_.size() + 1); buf_.append((const char *)&connection_id_, 4); - buf_.append((const char *)auth_plugin_data_part_1_, 8); + buf_.append((const char *)auth_plugin_data_, 8); buf_.append(empty, 1); buf_.append((const char *)&cap_flags_lower, 2); buf_.append((const char *)&character_set_, 1); buf_.append((const char *)&status_flags_, 2); buf_.append((const char *)&cap_flags_upper, 2); buf_.append(empty, 11); - buf_.append((const char *)auth_plugin_data_part_2_, 12); + buf_.append((const char *)auth_plugin_data_ + 8, 12); return this->MySQLMessage::encode(vectors, max); } @@ -213,7 +213,6 @@ int MySQLHandshakeResponse::decode_packet(const unsigned char *buf, size_t bufle const unsigned char *pos; uint16_t cap_flags_lower; uint16_t cap_flags_upper; - int len; if (buflen == 0) return -2; @@ -239,7 +238,7 @@ int MySQLHandshakeResponse::decode_packet(const unsigned char *buf, size_t bufle while (pos < end && *pos) pos++; - if (pos >= end || end - pos < 32) + if (pos >= end || end - pos < 45) return -2; server_version_.assign((const char *)buf, pos - buf); @@ -248,7 +247,7 @@ int MySQLHandshakeResponse::decode_packet(const unsigned char *buf, size_t bufle // TODO: check overflow connection_id_ = uint4korr(buf); buf += 4; - memcpy(auth_plugin_data_part_1_, buf, 8); + memcpy(auth_plugin_data_, buf, 8); buf += 9; cap_flags_lower = uint2korr(buf); buf += 2; @@ -261,22 +260,18 @@ int MySQLHandshakeResponse::decode_packet(const unsigned char *buf, size_t bufle auth_plugin_data_len_ = *buf++; // 10 bytes reserved. All 0s. buf += 10; - - len = 12; - if (auth_plugin_data_len_ >= 22) - len = auth_plugin_data_len_ - 9; - - if (end - buf < len + 1) + // auth_plugin_data always 20 bytes + if (auth_plugin_data_len_ > 21) return -2; - memcpy(auth_plugin_data_part_2_, buf, len); - buf += len + 1; + memcpy(auth_plugin_data_ + 8, buf, 12); + buf += 13; if (capability_flags_ & MYSQL_CAPFLAG_CLIENT_PLUGIN_AUTH) { if (buf == end || *(end - 1) != '\0') return -2; - auth_plugin_name_.assign((const char *)buf); + auth_plugin_name_.assign((const char *)buf, end - 1 - buf); } return 1; @@ -355,8 +350,9 @@ int MySQLAuthRequest::encode(struct iovec vectors[], int max) else { native.push_back((char)20); + std::string seed = std::string((const char *)challenge_, 20); std::string first = __sha1_str(password_); - std::string second = __sha1_str(challenge_ + __sha1_str(first)); + std::string second = __sha1_str(seed + __sha1_str(first)); for (int i = 0; i < 20; i++) native.push_back(first[i] ^ second[i]); @@ -422,12 +418,15 @@ int MySQLAuthResponse::decode_packet(const unsigned char *buf, size_t buflen) if (pos >= end) return -2; - plugin_name_.assign((const char *)buf, pos - buf); + auth_plugin_name_.assign((const char *)buf, pos - buf); buf = pos + 1; if (buf == end || *(end - 1) != '\0') return -2; - plugin_data_.assign((const char *)buf, end - 1 - buf); + if (end - 1 - buf != 20) + return -2; + + memcpy(auth_plugin_data_, buf, 20); return 1; default: diff --git a/src/protocol/MySQLMessage.inl b/src/protocol/MySQLMessage.inl index d59852e0..564f7148 100644 --- a/src/protocol/MySQLMessage.inl +++ b/src/protocol/MySQLMessage.inl @@ -35,27 +35,28 @@ private: class MySQLHandshakeResponse : public MySQLResponse { public: + std::string get_server_version() const { return server_version_; } + std::string get_auth_plugin_name() const { return auth_plugin_name_; } + void get_challenge(char *arr) const { - memcpy(arr, auth_plugin_data_part_1_, 8); - memcpy(arr + 8, auth_plugin_data_part_2_, 12); + memcpy(arr, auth_plugin_data_, 20); } virtual int encode(struct iovec vectors[], int max); void server_set(uint8_t protocol_version, const std::string server_version, - uint32_t connection_id, const uint8_t *auth1, + uint32_t connection_id, const uint8_t *auth_plugin_data, uint32_t capability_flags, uint8_t character_set, - uint16_t status_flags, const uint8_t *auth2) + uint16_t status_flags) { protocol_version_ = protocol_version; server_version_ = server_version; connection_id_ = connection_id; - memcpy(auth_plugin_data_part_1_, auth1, 8); + memcpy(auth_plugin_data_, auth_plugin_data, 20); capability_flags_ = capability_flags; character_set_ = character_set; status_flags_ = status_flags; - memcpy(auth_plugin_data_part_2_, auth2, 12); } bool host_disallowed() const { return disallowed_; } @@ -65,16 +66,15 @@ public: private: virtual int decode_packet(const unsigned char *buf, size_t buflen); - uint8_t protocol_version_; std::string server_version_; - uint32_t connection_id_; - uint8_t auth_plugin_data_part_1_[8]; - uint32_t capability_flags_; - uint8_t character_set_; - uint16_t status_flags_; - uint8_t auth_plugin_data_len_; - uint8_t auth_plugin_data_part_2_[246]; std::string auth_plugin_name_; + uint8_t auth_plugin_data_[20]; + uint32_t connection_id_; + uint32_t capability_flags_; + uint16_t status_flags_; + uint8_t character_set_; + uint8_t auth_plugin_data_len_; + uint8_t protocol_version_; bool disallowed_; public: @@ -126,7 +126,7 @@ public: void set_challenge(const char *arr) { - challenge_.assign(arr, 20); + memcpy(challenge_, arr, 20); } private: @@ -136,7 +136,7 @@ private: std::string username_; std::string password_; std::string db_; - std::string challenge_; + uint8_t challenge_[20]; int character_set_; public: @@ -150,15 +150,19 @@ public: class MySQLAuthResponse : public MySQLResponse { public: - std::string auth_plugin_name() const { return plugin_name_; } - std::string auth_plugin_data() const { return plugin_data_; } + std::string get_auth_plugin_name() const { return auth_plugin_name_; } + + void get_challenge(char *arr) const + { + memcpy(arr, auth_plugin_data_, 20); + } private: virtual int decode_packet(const unsigned char *buf, size_t buflen); private: - std::string plugin_name_; - std::string plugin_data_; + std::string auth_plugin_name_; + uint8_t auth_plugin_data_[20]; public: MySQLAuthResponse() { } diff --git a/src/server/WFMySQLServer.cc b/src/server/WFMySQLServer.cc index 012efa46..d3448f1b 100644 --- a/src/server/WFMySQLServer.cc +++ b/src/server/WFMySQLServer.cc @@ -29,8 +29,8 @@ WFConnection *WFMySQLServer::new_connection(int accept_fd) struct iovec vec[8]; int count; - resp.server_set(0x0a, "5.5", 1, (const uint8_t *)"12345678", - 0, 33, 0, (const uint8_t *)"123456789abc"); + resp.server_set(0x0a, "5.5", 1, (const uint8_t *)"12345678901234567890", + 0, 33, 0); count = resp.encode(vec, 8); if (count >= 0) {