| 159 | } |
| 160 | |
| 161 | pub async fn parse_auth_request(&self, cursor: &mut Cursor<&[u8]>) -> Result<AuthenticationRequest, ParseError> { |
| 162 | let auth_type = cursor.read_u32::<BigEndian>()?; |
| 163 | |
| 164 | match auth_type { |
| 165 | 0 => Ok(AuthenticationRequest::Ok), |
| 166 | 3 => Ok(AuthenticationRequest::Password), |
| 167 | 5 => { |
| 168 | let mut salt = [0u8; 4]; |
| 169 | cursor.read_exact(&mut salt)?; |
| 170 | Ok(AuthenticationRequest::MD5Password { salt }) |
| 171 | } |
| 172 | 10 => { |
| 173 | // SASL authentication |
| 174 | let mut mechanisms = Vec::new(); |
| 175 | loop { |
| 176 | let mechanism = self.read_cstring(cursor).await?; |
| 177 | if mechanism.is_empty() { |
| 178 | break; |
| 179 | } |
| 180 | if mechanisms.len() >= 10 { |
| 181 | return Err(ParseError::ProtocolViolation("Too many SASL mechanisms".to_string())); |
| 182 | } |
| 183 | mechanisms.push(mechanism); |
| 184 | } |
| 185 | Ok(AuthenticationRequest::SASL { mechanisms }) |
| 186 | } |
| 187 | 11 => { |
| 188 | // SASL continue |
| 189 | let remaining = cursor.get_ref().len() - cursor.position() as usize; |
| 190 | let mut data = vec![0u8; remaining]; |
| 191 | cursor.read_exact(&mut data)?; |
| 192 | Ok(AuthenticationRequest::SASLContinue { data }) |
| 193 | } |
| 194 | 12 => { |
| 195 | // SASL final |
| 196 | let remaining = cursor.get_ref().len() - cursor.position() as usize; |
| 197 | let mut data = vec![0u8; remaining]; |
| 198 | cursor.read_exact(&mut data)?; |
| 199 | Ok(AuthenticationRequest::SASLFinal { data }) |
| 200 | } |
| 201 | _ => Err(ParseError::ProtocolViolation(format!("Unknown auth type: {}", auth_type))) |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | pub async fn parse_query(&self, cursor: &mut Cursor<&[u8]>, length: u32) -> Result<FrontendMessage, ParseError> { |
| 206 | let sql = self.read_cstring_with_length(cursor, length as usize).await?; |