Refactored imports

This commit is contained in:
Lonami 2016-09-04 12:42:11 +02:00
parent 39a23559f0
commit 7c8c65560e
20 changed files with 98 additions and 86 deletions

View File

View File

@ -0,0 +1,4 @@
from .aes import AES
from .rsa import RSA, RSAServerKey
from .auth_key import AuthKey
from .factorizator import Factorizator

View File

@ -1,8 +1,7 @@
# This file is based on TLSharp # This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/AuthKey.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/AuthKey.cs
import utils.helpers as utils import utils
from utils.binary_writer import BinaryWriter from utils import BinaryWriter, BinaryReader
from utils.binary_reader import BinaryReader
class AuthKey: class AuthKey:

View File

@ -1,7 +1,7 @@
# This file is based on TLSharp # This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/RSA.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/RSA.cs
from utils.binary_writer import BinaryWriter import utils
import utils.helpers as utils from utils import BinaryWriter
class RSAServerKey: class RSAServerKey:

View File

@ -0,0 +1,6 @@
from .mtproto_plain_sender import MtProtoPlainSender
from .tcp_client import TcpClient
from .tcp_message import TcpMessage
from .authenticator import do_authentication
from .mtproto_sender import MtProtoSender
from .tcp_transport import TcpTransport

View File

@ -5,15 +5,10 @@
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs
import time import time
import utils
import utils.helpers as utils from utils import BinaryWriter, BinaryReader
from crypto.aes import AES from crypto import AES, AuthKey, Factorizator, RSA
from crypto.auth_key import AuthKey from network import MtProtoPlainSender
from crypto.factorizator import Factorizator
from crypto.rsa import RSA
from network.mtproto_plain_sender import MtProtoPlainSender
from utils.binary_reader import BinaryReader
from utils.binary_writer import BinaryWriter
def do_authentication(transport): def do_authentication(transport):

View File

@ -1,8 +1,7 @@
# This file is based on TLSharp # This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/MtProtoPlainSender.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/MtProtoPlainSender.cs
import time import time
from utils.binary_writer import BinaryWriter from utils import BinaryWriter, BinaryReader
from utils.binary_reader import BinaryReader
class MtProtoPlainSender: class MtProtoPlainSender:

View File

@ -4,11 +4,10 @@ import re
import zlib import zlib
from time import sleep from time import sleep
from crypto.aes import AES import utils
from utils.binary_writer import BinaryWriter from crypto import AES
from utils.binary_reader import BinaryReader from utils import BinaryWriter, BinaryReader
from tl.types.msgs_ack import MsgsAck from tl.types import MsgsAck
import utils.helpers as helpers
class MtProtoSender: class MtProtoSender:
@ -74,9 +73,9 @@ class MtProtoSender:
writer.write_int(len(packet)) writer.write_int(len(packet))
writer.write(packet) writer.write(packet)
msg_key = helpers.calc_msg_key(writer.get_bytes()) msg_key = utils.calc_msg_key(writer.get_bytes())
key, iv = helpers.calc_key(self.session.auth_key.key, msg_key, True) key, iv = utils.calc_key(self.session.auth_key.key, msg_key, True)
cipher_text = AES.encrypt_ige(writer.get_bytes(), key, iv) cipher_text = AES.encrypt_ige(writer.get_bytes(), key, iv)
# And then finally send the packet # And then finally send the packet
@ -101,7 +100,7 @@ class MtProtoSender:
remote_auth_key_id = reader.read_long() remote_auth_key_id = reader.read_long()
msg_key = reader.read(16) msg_key = reader.read(16)
key, iv = helpers.calc_key(self.session.auth_key.data, msg_key, False) key, iv = utils.calc_key(self.session.auth_key.data, msg_key, False)
plain_text = AES.decrypt_ige(reader.read(len(body) - reader.tell_position()), key, iv) plain_text = AES.decrypt_ige(reader.read(len(body) - reader.tell_position()), key, iv)
with BinaryReader(plain_text) as plain_text_reader: with BinaryReader(plain_text) as plain_text_reader:

View File

@ -2,8 +2,7 @@
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/TcpMessage.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/TcpMessage.cs
from zlib import crc32 from zlib import crc32
from utils.binary_writer import BinaryWriter from utils import BinaryWriter, BinaryReader
from utils.binary_reader import BinaryReader
class TcpMessage: class TcpMessage:

View File

@ -1,8 +1,7 @@
# This file is based on TLSharp # This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/TcpTransport.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/TcpTransport.cs
from zlib import crc32 from zlib import crc32
from network.tcp_message import TcpMessage from network import TcpMessage, TcpClient
from network.tcp_client import TcpClient
class TcpTransport: class TcpTransport:

View File

@ -0,0 +1,2 @@
from .source_builder import SourceBuilder
from .tl_parser import TLParser, TLObject

View File

@ -1,5 +1,5 @@
import re import re
from tl.tlobject import TLObject from tl import TLObject
class TLParser: class TLParser:

View File

@ -0,0 +1,5 @@
from .all_tlobjects import tlobjects
from .session import Session
from .mtproto_request import MTProtoRequest
from .telegram_client import TelegramClient
from .tlobject import TLObject, TLArg

View File

@ -3,7 +3,7 @@
from os.path import isfile as file_exists from os.path import isfile as file_exists
import time import time
import pickle import pickle
import utils.helpers as utils import utils
class Session: class Session:

View File

@ -1,29 +1,25 @@
# This file is based on TLSharp # This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/TelegramClient.cs # https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/TelegramClient.cs
from network.mtproto_sender import MtProtoSender
from network.tcp_transport import TcpTransport
import network.authenticator as authenticator
from tl.session import Session
import utils.helpers as utils
import platform
import re import re
import platform
from tl.functions.invoke_with_layer import InvokeWithLayer import utils
from tl.functions.init_connection import InitConnection import network.authenticator
from tl.functions.help.get_config import GetConfig from network import MtProtoSender, TcpTransport
from tl.functions.auth.check_phone import CheckPhone
from tl.functions.auth.send_code import SendCode from tl import Session
from tl.functions.auth.sign_in import SignIn from tl.types import InputPeerUser
from tl.functions.contacts.get_contacts import GetContacts from tl.functions import InvokeWithLayerRequest, InitConnectionRequest
from tl.types.input_peer_user import InputPeerUser from tl.functions.help import GetConfigRequest
from tl.functions.messages.send_message import SendMessage from tl.functions.auth import CheckPhoneRequest, SendCodeRequest, SignInRequest
from tl.functions.contacts import GetContactsRequest
from tl.functions.messages import SendMessageRequest
class TelegramClient: class TelegramClient:
def __init__(self, session_user_id, layer, api_id=None, api_hash=None): def __init__(self, session_user_id, layer, api_id=None, api_hash=None):
if api_id is None or api_hash is None: if api_id is None or api_hash is None:
raise PermissionError('Your API ID or Hash are invalid. Make sure to obtain yours in http://my.telegram.org') raise PermissionError('Your API ID or Hash are invalid. Please read "Requirements" on README.md')
self.api_id = api_id self.api_id = api_id
self.api_hash = api_hash self.api_hash = api_hash
@ -32,23 +28,26 @@ class TelegramClient:
self.session = Session.try_load_or_create_new(session_user_id) self.session = Session.try_load_or_create_new(session_user_id)
self.transport = TcpTransport(self.session.server_address, self.session.port) self.transport = TcpTransport(self.session.server_address, self.session.port)
# These will be set later
self.dc_options = None self.dc_options = None
self.sender = None
# TODO Should this be async? # TODO Should this be async?
def connect(self, reconnect=False): def connect(self, reconnect=False):
if self.session.auth_key is None or reconnect: if not self.session.auth_key or reconnect:
self.session.auth_key, self.session.time_offset= authenticator.do_authentication(self.transport) self.session.auth_key, self.session.time_offset = network.authenticator.do_authentication(self.transport)
self.sender = MtProtoSender(self.transport, self.session) self.sender = MtProtoSender(self.transport, self.session)
if not reconnect: if not reconnect:
request = InvokeWithLayer(layer=self.layer, request = InvokeWithLayerRequest(layer=self.layer,
query=InitConnection(api_id=self.api_id, query=InitConnectionRequest(api_id=self.api_id,
device_model=platform.node(), device_model=platform.node(),
system_version=platform.system(), system_version=platform.system(),
app_version='0.1', app_version='0.1',
lang_code='en', lang_code='en',
query=GetConfig())) query=GetConfigRequest()))
self.sender.send(request) self.sender.send(request)
self.sender.receive(request) self.sender.receive(request)
@ -77,22 +76,15 @@ class TelegramClient:
def is_phone_registered(self, phone_number): def is_phone_registered(self, phone_number):
assert self.sender is not None, 'Not connected!' assert self.sender is not None, 'Not connected!'
request = CheckPhone(phone_number) request = CheckPhoneRequest(phone_number)
self.sender.send(request) self.sender.send(request)
self.sender.receive(request) self.sender.receive(request)
# Result is an Auth.CheckedPhone # Result is an Auth.CheckedPhone
return request.result.phone_registered return request.result.phone_registered
def send_code_request(self, phone_number, destination='code'): def send_code_request(self, phone_number):
if destination == 'code': request = SendCodeRequest(phone_number, self.api_id, self.api_hash)
destination = 5
elif destination == 'sms':
destination = 0
else:
raise ValueError('Destination must be either "code" or "sms"')
request = SendCode(phone_number, self.api_id, self.api_hash)
completed = False completed = False
while not completed: while not completed:
try: try:
@ -109,7 +101,7 @@ class TelegramClient:
return request.result.phone_code_hash return request.result.phone_code_hash
def make_auth(self, phone_number, phone_code_hash, code): def make_auth(self, phone_number, phone_code_hash, code):
request = SignIn(phone_number, phone_code_hash, code) request = SignInRequest(phone_number, phone_code_hash, code)
self.sender.send(request) self.sender.send(request)
self.sender.receive(request) self.sender.receive(request)
@ -120,14 +112,14 @@ class TelegramClient:
return self.session.user return self.session.user
def import_contacts(self, phone_code_hash): def import_contacts(self, phone_code_hash):
request = GetContacts(phone_code_hash) request = GetContactsRequest(phone_code_hash)
self.sender.send(request) self.sender.send(request)
self.sender.receive(request) self.sender.receive(request)
return request.result.contacts, request.result.users return request.result.contacts, request.result.users
def send_message(self, user, message): def send_message(self, user, message):
peer = InputPeerUser(user.id, user.access_hash) peer = InputPeerUser(user.id, user.access_hash)
request = SendMessage(peer, message, utils.generate_random_long()) request = SendMessageRequest(peer, message, utils.generate_random_long())
self.sender.send(request) self.sender.send(request)
self.sender.send(request) self.sender.send(request)

View File

@ -2,8 +2,8 @@ import os
import re import re
import shutil import shutil
from parser.tl_parser import TLParser from parser import TLParser
from parser.source_builder import SourceBuilder from parser import SourceBuilder
def tlobjects_exist(): def tlobjects_exist():
@ -43,10 +43,12 @@ def generate_tlobjects(scheme_file):
os.makedirs(out_dir, exist_ok=True) os.makedirs(out_dir, exist_ok=True)
# Also create __init__.py # Also add this object to __init__.py, so we can import the whole packet at once
init_py = os.path.join(out_dir, '__init__.py') init_py = os.path.join(out_dir, '__init__.py')
if not os.path.isfile(init_py): with open(init_py, 'a', encoding='utf-8') as file:
open(init_py, 'a').close() with SourceBuilder(file) as builder:
builder.writeln('from {} import {}'.format(
get_full_file_name(tlobject), get_class_name(tlobject)))
# Create the file for this TLObject # Create the file for this TLObject
filename = os.path.join(out_dir, get_file_name(tlobject, add_extension=True)) filename = os.path.join(out_dir, get_file_name(tlobject, add_extension=True))
@ -165,7 +167,11 @@ def get_class_name(tlobject):
# Courtesy of http://stackoverflow.com/a/31531797/4759433 # Courtesy of http://stackoverflow.com/a/31531797/4759433
# Also, '_' could be replaced for ' ', then use .title(), and then remove ' ' # Also, '_' could be replaced for ' ', then use .title(), and then remove ' '
result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), tlobject.name) result = re.sub(r'_([a-z])', lambda m: m.group(1).upper(), tlobject.name)
return result[:1].upper() + result[1:].replace('_', '') # Replace again to fully ensure! result = result[:1].upper() + result[1:].replace('_', '') # Replace again to fully ensure!
# If it's a function, let it end with "Request" to identify them more easily
if tlobject.is_function:
result += 'Request'
return result
def get_full_file_name(tlobject): def get_full_file_name(tlobject):

View File

@ -2,15 +2,19 @@ import random
import socket import socket
import threading import threading
import unittest import unittest
import os
import platform
import utils.helpers as utils import utils
from crypto.aes import AES import network.authenticator
from crypto.factorizator import Factorizator
from network.authenticator import do_authentication from crypto import AES, Factorizator
from network.tcp_client import TcpClient from network import TcpTransport, TcpClient, MtProtoSender
from network.tcp_transport import TcpTransport from utils import BinaryWriter, BinaryReader
from utils.binary_reader import BinaryReader
from utils.binary_writer import BinaryWriter from tl import Session
from tl.functions import InvokeWithLayerRequest, InitConnectionRequest
from tl.functions.help import GetConfigRequest
host = 'localhost' host = 'localhost'
port = random.randint(50000, 60000) # Arbitrary non-privileged port port = random.randint(50000, 60000) # Arbitrary non-privileged port
@ -218,7 +222,7 @@ class UnitTest(unittest.TestCase):
@staticmethod @staticmethod
def test_authenticator(): def test_authenticator():
transport = TcpTransport('149.154.167.91', 443) transport = TcpTransport('149.154.167.91', 443)
auth_key, time_offset = do_authentication(transport) network.authenticator.do_authentication(transport)
transport.dispose() transport.dispose()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -0,0 +1,3 @@
from .binary_writer import BinaryWriter
from .binary_reader import BinaryReader
from .helpers import *

View File

@ -1,5 +1,5 @@
from io import BytesIO, BufferedReader from io import BytesIO, BufferedReader
from tl.all_tlobjects import tlobjects from tl import tlobjects
from struct import unpack from struct import unpack
import inspect import inspect
import os import os

View File

@ -1,5 +1,5 @@
import os import os
from utils.binary_writer import BinaryWriter from utils import BinaryWriter
import hashlib import hashlib