diff --git a/src/protocol/MySQLMessage.cc b/src/protocol/MySQLMessage.cc index b043ae0a..c4e96b54 100644 --- a/src/protocol/MySQLMessage.cc +++ b/src/protocol/MySQLMessage.cc @@ -434,6 +434,40 @@ int MySQLAuthResponse::decode_packet(const unsigned char *buf, size_t buflen) } } +int MySQLAuthSwitchRequest::encode(struct iovec vectors[], int max) +{ + if (auth_plugin_name_ == "mysql_clear_password") + { + buf_ = password_; + buf_.push_back('\0'); + } + else if (auth_plugin_name_ == "mysql_native_password") + { + std::string seed = std::string((const char *)challenge_, 20); + std::string first = __sha1_str(password_); + std::string second = __sha1_str(seed + __sha1_str(first)); + + buf_.clear(); + for (int i = 0; i < 20; i++) + buf_.push_back(first[i] ^ second[i]); + } + else if (auth_plugin_name_ == "sha256_password") + { + // TODO + } + else if (auth_plugin_name_ == "caching_sha2_password") + { + // TODO + } + else + { + errno = EINVAL; + return -1; + } + + return this->MySQLMessage::encode(vectors, max); +} + void MySQLResponse::set_ok_packet() { uint16_t zero16 = 0; diff --git a/src/protocol/MySQLMessage.inl b/src/protocol/MySQLMessage.inl index 564f7148..4d713108 100644 --- a/src/protocol/MySQLMessage.inl +++ b/src/protocol/MySQLMessage.inl @@ -172,33 +172,47 @@ public: MySQLAuthResponse& operator= (MySQLAuthResponse&& move) = default; }; -class MySQLBytesRequest : public MySQLRequest +class MySQLAuthSwitchRequest : public MySQLRequest { public: - void set_bytes(const void *bytes, size_t len) + void set_password(const std::string& password) { - buf_.assign((const char *)bytes, len); + password_ = password; } - std::string get_bytes() const + void set_auth_plugin_name(const std::string& name) { - return buf_; + auth_plugin_name_ = name; + } + + void set_challenge(const char *arr) + { + memcpy(challenge_, arr, 20); } private: + virtual int encode(struct iovec vectors[], int max); + virtual int decode_packet(const unsigned char *buf, size_t buflen) { buf_.assign((const char *)buf, buflen); return 1; } -private: - MySQLBytesRequest() { } - MySQLBytesRequest(MySQLBytesRequest&& move) = default; - //move operator - MySQLBytesRequest& operator= (MySQLBytesRequest&& move) = default; + std::string password_; + std::string auth_plugin_name_; + uint8_t challenge_[20]; + +public: + MySQLAuthSwitchRequest() { } + //move constructor + MySQLAuthSwitchRequest(MySQLAuthSwitchRequest&& move) = default; + //move operator + MySQLAuthSwitchRequest& operator= (MySQLAuthSwitchRequest&& move) = default; }; +using MySQLAuthSwitchResponse = MySQLResponse; + ////////// inline mysql_parser_t *MySQLMessage::get_parser() const