rbdc_mysql/protocol/connect/
auth_switch.rs

1use bytes::{Buf, Bytes};
2
3use crate::protocol::auth::AuthPlugin;
4use crate::protocol::Capabilities;
5use rbdc::io::Encode;
6use rbdc::io::{BufExt, Decode};
7use rbdc::{err_protocol, Error};
8
9// https://dev.mysql.com/doc/dev/mysql-server/8.0.12/page_protocol_connection_phase_packets_protocol_auth_switch_request.html
10
11#[derive(Debug)]
12pub struct AuthSwitchRequest {
13    pub plugin: AuthPlugin,
14    pub data: Bytes,
15}
16
17impl Decode<'_> for AuthSwitchRequest {
18    fn decode_with(mut buf: Bytes, _: ()) -> Result<Self, Error> {
19        let header = buf.get_u8();
20        if header != 0xfe {
21            return Err(err_protocol!(
22                "expected 0xfe (AUTH_SWITCH) but found 0x{:x}",
23                header
24            ));
25        }
26
27        let plugin = buf.get_str_nul()?.parse()?;
28
29        // See: https://github.com/mysql/mysql-server/blob/ea7d2e2d16ac03afdd9cb72a972a95981107bf51/sql/auth/sha2_password.cc#L942
30        if buf.len() != 21 {
31            return Err(err_protocol!(
32                "expected 21 bytes but found {} bytes",
33                buf.len()
34            ));
35        }
36        let data = buf.get_bytes(20);
37        buf.advance(1); // NUL-terminator
38
39        Ok(Self { plugin, data })
40    }
41}
42
43#[derive(Debug)]
44pub struct AuthSwitchResponse(pub Vec<u8>);
45
46impl Encode<'_, Capabilities> for AuthSwitchResponse {
47    fn encode_with(&self, buf: &mut Vec<u8>, _: Capabilities) {
48        buf.extend_from_slice(&self.0);
49    }
50}