1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use bytes::{Buf, Bytes};
use crate::binary::BinaryReader;
use crate::command::wtlogin::{LoginResponse, QRCodeConfirmed, QRCodeImageFetch, QRCodeState};
use crate::{RQError, RQResult};
impl super::super::super::Engine {
pub fn decode_trans_emp_response(&self, mut payload: Bytes) -> RQResult<QRCodeState> {
if payload.len() < 48 {
return Err(RQError::Decode("invalid payload length".into()));
}
payload.advance(5);
payload.get_u8();
payload.get_u16();
let cmd = payload.get_u16();
payload.advance(21);
payload.get_u8();
payload.get_u16();
payload.get_u16();
payload.get_i32();
payload.get_i64();
let len = payload.remaining() - 1;
let mut body = payload.copy_to_bytes(len);
if cmd == 0x31 {
body.get_u16();
body.get_i32();
let code = body.get_u8();
if code != 0 {
return Err(RQError::Decode(format!("body code: {}", code)));
}
let sig = body.read_bytes_short();
body.get_u16();
let mut m = body.read_tlv_map(2);
if m.contains_key(&0x17) {
return Ok(QRCodeState::ImageFetch(QRCodeImageFetch {
image_data: m
.remove(&0x17)
.ok_or_else(|| RQError::Decode("missing 0x17".into()))?,
sig,
}));
}
}
if cmd == 0x12 {
let mut a_var_len = body.get_u16();
if a_var_len != 0 {
a_var_len -= 1;
if body.get_u8() == 2 {
body.get_i64();
a_var_len -= 8;
}
}
if a_var_len > 0 {
body.advance(a_var_len as usize);
}
body.get_i32();
let code = body.get_u8();
if code != 0 {
return match code {
0x30 => Ok(QRCodeState::WaitingForScan),
0x35 => Ok(QRCodeState::WaitingForConfirm),
0x36 => Ok(QRCodeState::Canceled),
0x11 => Ok(QRCodeState::Timeout),
_ => Err(RQError::Decode("invalid body code".to_string())),
};
}
let uin = body.get_i64();
body.get_i32();
body.get_u16();
let mut m = body.read_tlv_map(2);
return Ok(QRCodeState::Confirmed(QRCodeConfirmed {
uin,
tmp_pwd: m
.remove(&0x18)
.ok_or_else(|| RQError::Decode("missing 0x18".into()))?,
tmp_no_pic_sig: m
.remove(&0x19)
.ok_or_else(|| RQError::Decode("missing 0x19".into()))?,
tgt_qr: m
.remove(&0x65)
.ok_or_else(|| RQError::Decode("missing 0x65".into()))?,
tgtgt_key: m
.remove(&0x1e)
.ok_or_else(|| RQError::Decode("missing 0x1e".into()))?,
}));
}
Err(RQError::Decode(
"decode_trans_emp_response unknown error".to_string(),
))
}
pub fn decode_login_response(&self, mut reader: Bytes) -> RQResult<LoginResponse> {
let _sub_command = reader.get_u16();
let status = reader.get_u8();
reader.get_u16();
let tlv_map = reader.read_tlv_map(2);
LoginResponse::decode(status, tlv_map, &self.transport.sig.tgtgt_key)
}
pub fn decode_exchange_emp_response(&self, mut payload: Bytes) -> RQResult<LoginResponse> {
let sub_command = payload.get_u16();
let status = payload.get_u8();
payload.get_u16();
let tlv_map = payload.read_tlv_map(2);
if status != 0 {
return Err(RQError::Decode(format!(
"decode_exchange_emp_response status: {}",
status
)));
}
let encrypt_key = if sub_command == 11 {
md5::compute(&self.transport.sig.d2key).to_vec()
} else {
self.transport.sig.tgtgt_key.to_vec()
};
LoginResponse::decode(status, tlv_map, &encrypt_key)
}
}