proof = "p=" base64 channel-binding = "c=" base64 ;; base64 encoding of cbind-input. client-final-message-without-proof = channel-binding "," nonce ["," extensions] client-final-message = client-final-message-without-proof "," proof
(mut buf: Cursor)
| 752 | // client-final-message = |
| 753 | // client-final-message-without-proof "," proof |
| 754 | pub fn decode_sasl_response(mut buf: Cursor) -> Result<FrontendMessage, io::Error> { |
| 755 | // --- client-final-message-without-proof --- |
| 756 | let mut client_final_message_bare_raw = String::new(); |
| 757 | // channel-binding: "c=" <base64>, up to the next comma |
| 758 | expect(&mut buf, b"c=")?; |
| 759 | let channel_binding = String::from_utf8(read_until_comma(&mut buf)?) |
| 760 | .map_err(|_| input_err("invalid channel-binding utf8"))?; |
| 761 | expect(&mut buf, b",")?; |
| 762 | client_final_message_bare_raw.push_str(&format!("c={},", channel_binding)); |
| 763 | |
| 764 | // nonce: "r=" <printable>, up to the next comma |
| 765 | expect(&mut buf, b"r=")?; |
| 766 | let nonce = String::from_utf8(read_until_comma(&mut buf)?) |
| 767 | .map_err(|_| input_err("invalid nonce utf8"))?; |
| 768 | client_final_message_bare_raw.push_str(&format!("r={}", nonce)); |
| 769 | |
| 770 | // after reading channel-binding and nonce |
| 771 | let mut extensions = Vec::new(); |
| 772 | |
| 773 | // Keep reading ",<token>" until we see ",p=" |
| 774 | while buf.peek_byte()? == b',' { |
| 775 | expect(&mut buf, b",")?; |
| 776 | if buf.peek_byte()? == b'p' { |
| 777 | break; |
| 778 | } |
| 779 | let ext = String::from_utf8(read_until_comma(&mut buf)?) |
| 780 | .map_err(|_| input_err("invalid extension utf8"))?; |
| 781 | if !ext.is_empty() { |
| 782 | client_final_message_bare_raw.push_str(&format!(",{}", ext)); |
| 783 | extensions.push(ext); |
| 784 | } |
| 785 | } |
| 786 | |
| 787 | // Proof is mandatory and last |
| 788 | expect(&mut buf, b"p=")?; |
| 789 | let proof = String::from_utf8(read_until_comma(&mut buf)?) |
| 790 | .map_err(|_| input_err("invalid proof utf8"))?; |
| 791 | |
| 792 | Ok(FrontendMessage::SASLResponse(SASLClientFinalResponse { |
| 793 | channel_binding, |
| 794 | nonce, |
| 795 | extensions, |
| 796 | proof, |
| 797 | client_final_message_bare_raw, |
| 798 | })) |
| 799 | } |
| 800 | |
| 801 | pub fn decode_password(mut buf: Cursor) -> Result<FrontendMessage, io::Error> { |
| 802 | Ok(FrontendMessage::Password { |