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
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/AuthKey.cs
import utils.helpers as utils
from utils.binary_writer import BinaryWriter
from utils.binary_reader import BinaryReader
import utils
from utils import BinaryWriter, BinaryReader
class AuthKey:

View File

@ -1,7 +1,7 @@
# This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/MTProto/Crypto/RSA.cs
from utils.binary_writer import BinaryWriter
import utils.helpers as utils
import utils
from utils import BinaryWriter
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
import time
import utils.helpers as utils
from crypto.aes import AES
from crypto.auth_key import AuthKey
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
import utils
from utils import BinaryWriter, BinaryReader
from crypto import AES, AuthKey, Factorizator, RSA
from network import MtProtoPlainSender
def do_authentication(transport):

View File

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

View File

@ -4,11 +4,10 @@ import re
import zlib
from time import sleep
from crypto.aes import AES
from utils.binary_writer import BinaryWriter
from utils.binary_reader import BinaryReader
from tl.types.msgs_ack import MsgsAck
import utils.helpers as helpers
import utils
from crypto import AES
from utils import BinaryWriter, BinaryReader
from tl.types import MsgsAck
class MtProtoSender:
@ -74,9 +73,9 @@ class MtProtoSender:
writer.write_int(len(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)
# And then finally send the packet
@ -101,7 +100,7 @@ class MtProtoSender:
remote_auth_key_id = reader.read_long()
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)
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
from zlib import crc32
from utils.binary_writer import BinaryWriter
from utils.binary_reader import BinaryReader
from utils import BinaryWriter, BinaryReader
class TcpMessage:

View File

@ -1,8 +1,7 @@
# This file is based on TLSharp
# https://github.com/sochix/TLSharp/blob/master/TLSharp.Core/Network/TcpTransport.cs
from zlib import crc32
from network.tcp_message import TcpMessage
from network.tcp_client import TcpClient
from network import TcpMessage, TcpClient
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
from tl.tlobject import TLObject
from tl import TLObject
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
import time
import pickle
import utils.helpers as utils
import utils
class Session:

View File

@ -1,29 +1,25 @@
# This file is based on TLSharp
# 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 platform
from tl.functions.invoke_with_layer import InvokeWithLayer
from tl.functions.init_connection import InitConnection
from tl.functions.help.get_config import GetConfig
from tl.functions.auth.check_phone import CheckPhone
from tl.functions.auth.send_code import SendCode
from tl.functions.auth.sign_in import SignIn
from tl.functions.contacts.get_contacts import GetContacts
from tl.types.input_peer_user import InputPeerUser
from tl.functions.messages.send_message import SendMessage
import utils
import network.authenticator
from network import MtProtoSender, TcpTransport
from tl import Session
from tl.types import InputPeerUser
from tl.functions import InvokeWithLayerRequest, InitConnectionRequest
from tl.functions.help import GetConfigRequest
from tl.functions.auth import CheckPhoneRequest, SendCodeRequest, SignInRequest
from tl.functions.contacts import GetContactsRequest
from tl.functions.messages import SendMessageRequest
class TelegramClient:
def __init__(self, session_user_id, layer, api_id=None, api_hash=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_hash = api_hash
@ -32,23 +28,26 @@ class TelegramClient:
self.session = Session.try_load_or_create_new(session_user_id)
self.transport = TcpTransport(self.session.server_address, self.session.port)
# These will be set later
self.dc_options = None
self.sender = None
# TODO Should this be async?
def connect(self, reconnect=False):
if self.session.auth_key is None or reconnect:
self.session.auth_key, self.session.time_offset= authenticator.do_authentication(self.transport)
if not self.session.auth_key or reconnect:
self.session.auth_key, self.session.time_offset = network.authenticator.do_authentication(self.transport)
self.sender = MtProtoSender(self.transport, self.session)
if not reconnect:
request = InvokeWithLayer(layer=self.layer,
query=InitConnection(api_id=self.api_id,
device_model=platform.node(),
system_version=platform.system(),
app_version='0.1',
lang_code='en',
query=GetConfig()))
request = InvokeWithLayerRequest(layer=self.layer,
query=InitConnectionRequest(api_id=self.api_id,
device_model=platform.node(),
system_version=platform.system(),
app_version='0.1',
lang_code='en',
query=GetConfigRequest()))
self.sender.send(request)
self.sender.receive(request)
@ -77,22 +76,15 @@ class TelegramClient:
def is_phone_registered(self, phone_number):
assert self.sender is not None, 'Not connected!'
request = CheckPhone(phone_number)
request = CheckPhoneRequest(phone_number)
self.sender.send(request)
self.sender.receive(request)
# Result is an Auth.CheckedPhone
return request.result.phone_registered
def send_code_request(self, phone_number, destination='code'):
if destination == 'code':
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)
def send_code_request(self, phone_number):
request = SendCodeRequest(phone_number, self.api_id, self.api_hash)
completed = False
while not completed:
try:
@ -109,7 +101,7 @@ class TelegramClient:
return request.result.phone_code_hash
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.receive(request)
@ -120,14 +112,14 @@ class TelegramClient:
return self.session.user
def import_contacts(self, phone_code_hash):
request = GetContacts(phone_code_hash)
request = GetContactsRequest(phone_code_hash)
self.sender.send(request)
self.sender.receive(request)
return request.result.contacts, request.result.users
def send_message(self, user, message):
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)

View File

@ -2,8 +2,8 @@ import os
import re
import shutil
from parser.tl_parser import TLParser
from parser.source_builder import SourceBuilder
from parser import TLParser
from parser import SourceBuilder
def tlobjects_exist():
@ -43,10 +43,12 @@ def generate_tlobjects(scheme_file):
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')
if not os.path.isfile(init_py):
open(init_py, 'a').close()
with open(init_py, 'a', encoding='utf-8') as file:
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
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
# 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)
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):

View File

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

View File

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