mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 15:34:01 +03:00
Add mtproto handshake
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package mtproto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/9seconds/mtg/mtproto/rpc"
|
||||
"github.com/9seconds/mtg/protocol"
|
||||
"github.com/9seconds/mtg/telegram"
|
||||
"github.com/9seconds/mtg/wrappers"
|
||||
)
|
||||
|
||||
func TelegramProtocol(req *protocol.TelegramRequest) (wrappers.Wrap, error) {
|
||||
conn, err := telegram.Middle.Dial(req.Ctx,
|
||||
req.Cancel,
|
||||
req.ClientProtocol.DC(),
|
||||
req.ClientProtocol.ConnectionProtocol())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot connect to telegram: %w", err)
|
||||
}
|
||||
|
||||
rpcNonceConn := wrappers.NewMtprotoFrame(conn, rpc.SeqNoNonce)
|
||||
rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot do nonce request: %w", err)
|
||||
}
|
||||
|
||||
rpcNonceResp, err := getRPCNonceResponse(rpcNonceConn, rpcNonceReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get nonce response: %w", err)
|
||||
}
|
||||
|
||||
secureConn := wrappers.NewMiddleProxyCipher(conn, rpcNonceReq, rpcNonceResp, telegram.Middle.Secret())
|
||||
frameConn := wrappers.NewMtprotoFrame(secureConn, rpc.SeqNoHandshake)
|
||||
|
||||
if err := doRPCHandshakeRequest(frameConn); err != nil {
|
||||
return nil, fmt.Errorf("cannot do handshake request: %w", err)
|
||||
}
|
||||
if err := getRPCHandshakeResponse(frameConn); err != nil {
|
||||
return nil, fmt.Errorf("cannot get handshake response: %w", err)
|
||||
}
|
||||
|
||||
return frameConn, nil
|
||||
}
|
||||
|
||||
func doRPCNonceRequest(conn wrappers.PacketWriter) (*rpc.NonceRequest, error) {
|
||||
rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rpcNonceReq, nil
|
||||
}
|
||||
|
||||
func getRPCNonceResponse(conn wrappers.PacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
|
||||
packet, err := conn.Read()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read from connection: %w", err)
|
||||
}
|
||||
|
||||
resp, err := rpc.NewNonceResponse(packet)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot build rpc nonce responce: %w", err)
|
||||
}
|
||||
if err = resp.Valid(req); err != nil {
|
||||
return nil, fmt.Errorf("invalid nonce response: %w", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func doRPCHandshakeRequest(conn wrappers.PacketWriter) error {
|
||||
if err := conn.Write(rpc.HandshakeRequest); err != nil {
|
||||
return fmt.Errorf("cannot make a request: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRPCHandshakeResponse(conn wrappers.PacketReader) error {
|
||||
packet, err := conn.Read()
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot read a response: %w", err)
|
||||
}
|
||||
|
||||
resp, err := rpc.NewHandshakeResponse(packet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot build a handshake response: %w", err)
|
||||
}
|
||||
if err := resp.Valid(); err != nil {
|
||||
return fmt.Errorf("invalid handshake response: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -17,12 +17,17 @@ const telegramDialTimeout = 10 * time.Second
|
||||
type baseTelegram struct {
|
||||
dialer net.Dialer
|
||||
|
||||
secret []byte
|
||||
v4DefaultDC conntypes.DC
|
||||
V6DefaultDC conntypes.DC
|
||||
v4Addresses map[conntypes.DC][]string
|
||||
v6Addresses map[conntypes.DC][]string
|
||||
}
|
||||
|
||||
func (b *baseTelegram) Secret() []byte {
|
||||
return b.secret
|
||||
}
|
||||
|
||||
func (b *baseTelegram) dialToAddress(ctx context.Context,
|
||||
cancel context.CancelFunc,
|
||||
addr string) (wrappers.StreamReadWriteCloser, error) {
|
||||
|
||||
@@ -12,4 +12,5 @@ type Telegram interface {
|
||||
context.CancelFunc,
|
||||
conntypes.DC,
|
||||
conntypes.ConnectionProtocol) (wrappers.StreamReadWriteCloser, error)
|
||||
Secret() []byte
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ var Middle = NewMiddleTelegram()
|
||||
type middleTelegram struct {
|
||||
baseTelegram
|
||||
|
||||
secret []byte
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user