Przeglądaj źródła

Add mtproto handshake

tags/1.0^2
9seconds 6 lat temu
rodzic
commit
b280f47731
4 zmienionych plików z 102 dodań i 1 usunięć
  1. 96
    0
      mtproto/protocol.go
  2. 5
    0
      telegram/base.go
  3. 1
    0
      telegram/interfaces.go
  4. 0
    1
      telegram/middle.go

+ 96
- 0
mtproto/protocol.go Wyświetl plik

@@ -0,0 +1,96 @@
1
+package mtproto
2
+
3
+import (
4
+	"fmt"
5
+
6
+	"github.com/9seconds/mtg/mtproto/rpc"
7
+	"github.com/9seconds/mtg/protocol"
8
+	"github.com/9seconds/mtg/telegram"
9
+	"github.com/9seconds/mtg/wrappers"
10
+)
11
+
12
+func TelegramProtocol(req *protocol.TelegramRequest) (wrappers.Wrap, error) {
13
+	conn, err := telegram.Middle.Dial(req.Ctx,
14
+		req.Cancel,
15
+		req.ClientProtocol.DC(),
16
+		req.ClientProtocol.ConnectionProtocol())
17
+	if err != nil {
18
+		return nil, fmt.Errorf("cannot connect to telegram: %w", err)
19
+	}
20
+
21
+	rpcNonceConn := wrappers.NewMtprotoFrame(conn, rpc.SeqNoNonce)
22
+	rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
23
+	if err != nil {
24
+		return nil, fmt.Errorf("cannot do nonce request: %w", err)
25
+	}
26
+
27
+	rpcNonceResp, err := getRPCNonceResponse(rpcNonceConn, rpcNonceReq)
28
+	if err != nil {
29
+		return nil, fmt.Errorf("cannot get nonce response: %w", err)
30
+	}
31
+
32
+	secureConn := wrappers.NewMiddleProxyCipher(conn, rpcNonceReq, rpcNonceResp, telegram.Middle.Secret())
33
+	frameConn := wrappers.NewMtprotoFrame(secureConn, rpc.SeqNoHandshake)
34
+
35
+	if err := doRPCHandshakeRequest(frameConn); err != nil {
36
+		return nil, fmt.Errorf("cannot do handshake request: %w", err)
37
+	}
38
+	if err := getRPCHandshakeResponse(frameConn); err != nil {
39
+		return nil, fmt.Errorf("cannot get handshake response: %w", err)
40
+	}
41
+
42
+	return frameConn, nil
43
+}
44
+
45
+func doRPCNonceRequest(conn wrappers.PacketWriter) (*rpc.NonceRequest, error) {
46
+	rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
47
+	if err != nil {
48
+		panic(err)
49
+	}
50
+	if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
51
+		return nil, err
52
+	}
53
+
54
+	return rpcNonceReq, nil
55
+}
56
+
57
+func getRPCNonceResponse(conn wrappers.PacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
58
+	packet, err := conn.Read()
59
+	if err != nil {
60
+		return nil, fmt.Errorf("cannot read from connection: %w", err)
61
+	}
62
+
63
+	resp, err := rpc.NewNonceResponse(packet)
64
+	if err != nil {
65
+		return nil, fmt.Errorf("cannot build rpc nonce responce: %w", err)
66
+	}
67
+	if err = resp.Valid(req); err != nil {
68
+		return nil, fmt.Errorf("invalid nonce response: %w", err)
69
+	}
70
+
71
+	return resp, nil
72
+}
73
+
74
+func doRPCHandshakeRequest(conn wrappers.PacketWriter) error {
75
+	if err := conn.Write(rpc.HandshakeRequest); err != nil {
76
+		return fmt.Errorf("cannot make a request: %w", err)
77
+	}
78
+	return nil
79
+}
80
+
81
+func getRPCHandshakeResponse(conn wrappers.PacketReader) error {
82
+	packet, err := conn.Read()
83
+	if err != nil {
84
+		return fmt.Errorf("cannot read a response: %w", err)
85
+	}
86
+
87
+	resp, err := rpc.NewHandshakeResponse(packet)
88
+	if err != nil {
89
+		return fmt.Errorf("cannot build a handshake response: %w", err)
90
+	}
91
+	if err := resp.Valid(); err != nil {
92
+		return fmt.Errorf("invalid handshake response: %w", err)
93
+	}
94
+
95
+	return nil
96
+}

+ 5
- 0
telegram/base.go Wyświetl plik

@@ -17,12 +17,17 @@ const telegramDialTimeout = 10 * time.Second
17 17
 type baseTelegram struct {
18 18
 	dialer net.Dialer
19 19
 
20
+	secret      []byte
20 21
 	v4DefaultDC conntypes.DC
21 22
 	V6DefaultDC conntypes.DC
22 23
 	v4Addresses map[conntypes.DC][]string
23 24
 	v6Addresses map[conntypes.DC][]string
24 25
 }
25 26
 
27
+func (b *baseTelegram) Secret() []byte {
28
+	return b.secret
29
+}
30
+
26 31
 func (b *baseTelegram) dialToAddress(ctx context.Context,
27 32
 	cancel context.CancelFunc,
28 33
 	addr string) (wrappers.StreamReadWriteCloser, error) {

+ 1
- 0
telegram/interfaces.go Wyświetl plik

@@ -12,4 +12,5 @@ type Telegram interface {
12 12
 		context.CancelFunc,
13 13
 		conntypes.DC,
14 14
 		conntypes.ConnectionProtocol) (wrappers.StreamReadWriteCloser, error)
15
+	Secret() []byte
15 16
 }

+ 0
- 1
telegram/middle.go Wyświetl plik

@@ -21,7 +21,6 @@ var Middle = NewMiddleTelegram()
21 21
 type middleTelegram struct {
22 22
 	baseTelegram
23 23
 
24
-	secret []byte
25 24
 	mutex  sync.RWMutex
26 25
 }
27 26
 

Ładowanie…
Anuluj
Zapisz