This commit is contained in:
singer 2017-10-21 18:40:23 +00:00 committed by GitHub
commit de4d2bde83
4 changed files with 31 additions and 24 deletions

View File

@ -1,7 +1,7 @@
import struct import struct
from hashlib import sha1 from hashlib import sha1
from .. import helpers as utils from ..helpers import calc_msg_key
from ..extensions import BinaryReader from ..extensions import BinaryReader
@ -20,4 +20,4 @@ class AuthKey:
""" """
new_nonce = new_nonce.to_bytes(32, 'little', signed=True) new_nonce = new_nonce.to_bytes(32, 'little', signed=True)
data = new_nonce + struct.pack('<BQ', number, self.aux_hash) data = new_nonce + struct.pack('<BQ', number, self.aux_hash)
return utils.calc_msg_key(data) return calc_msg_key(data)

View File

@ -6,7 +6,7 @@ from ..tl.types import (
ResPQ, PQInnerData, ServerDHParamsFail, ServerDHParamsOk, ResPQ, PQInnerData, ServerDHParamsFail, ServerDHParamsOk,
ServerDHInnerData, ClientDHInnerData, DhGenOk, DhGenRetry, DhGenFail ServerDHInnerData, ClientDHInnerData, DhGenOk, DhGenRetry, DhGenFail
) )
from .. import helpers as utils from ..helpers import generate_key_data_from_nonce
from ..crypto import AES, AuthKey, Factorization from ..crypto import AES, AuthKey, Factorization
from ..crypto import rsa from ..crypto import rsa
from ..errors import SecurityError from ..errors import SecurityError
@ -110,7 +110,7 @@ def _do_authentication(connection):
raise SecurityError('Invalid server nonce from server') raise SecurityError('Invalid server nonce from server')
# Step 3 sending: Complete DH Exchange # Step 3 sending: Complete DH Exchange
key, iv = utils.generate_key_data_from_nonce( key, iv = generate_key_data_from_nonce(
res_pq.server_nonce, new_nonce res_pq.server_nonce, new_nonce
) )
plain_text_answer = AES.decrypt_ige( plain_text_answer = AES.decrypt_ige(

View File

@ -8,7 +8,8 @@ from io import BytesIO
from threading import Lock from threading import Lock
from time import sleep from time import sleep
from . import helpers as utils from .helpers import generate_random_long, ensure_parent_dir_exists
from .crypto import rsa, CdnDecrypter from .crypto import rsa, CdnDecrypter
from .errors import ( from .errors import (
RPCError, BrokenAuthKeyError, ServerError, RPCError, BrokenAuthKeyError, ServerError,
@ -611,7 +612,7 @@ class TelegramBareClient:
is_large = file_size > 10 * 1024 * 1024 is_large = file_size > 10 * 1024 * 1024
part_count = (file_size + part_size - 1) // part_size part_count = (file_size + part_size - 1) // part_size
file_id = utils.generate_random_long() file_id = generate_random_long()
hash_md5 = md5() hash_md5 = md5()
stream = open(file, 'rb') if isinstance(file, str) else BytesIO(file) stream = open(file, 'rb') if isinstance(file, str) else BytesIO(file)
@ -689,7 +690,7 @@ class TelegramBareClient:
if isinstance(file, str): if isinstance(file, str):
# Ensure that we'll be able to download the media # Ensure that we'll be able to download the media
utils.ensure_parent_dir_exists(file) ensure_parent_dir_exists(file)
f = open(file, 'wb') f = open(file, 'wb')
else: else:
f = file f = file

View File

@ -6,6 +6,7 @@ from zlib import crc32
from collections import defaultdict from collections import defaultdict
from .parser import SourceBuilder, TLParser, TLObject from .parser import SourceBuilder, TLParser, TLObject
AUTO_GEN_NOTICE = \ AUTO_GEN_NOTICE = \
'"""File generated by TLObjects\' generator. All changes will be ERASED"""' '"""File generated by TLObjects\' generator. All changes will be ERASED"""'
@ -117,8 +118,18 @@ class TLGenerator:
def _write_init_py(out_dir, depth, namespace_tlobjects, type_constructors): def _write_init_py(out_dir, depth, namespace_tlobjects, type_constructors):
# namespace_tlobjects: {'namespace', [TLObject]} # namespace_tlobjects: {'namespace', [TLObject]}
os.makedirs(out_dir, exist_ok=True) os.makedirs(out_dir, exist_ok=True)
# Generate __init__.py with relative imports to the namespaces
with open(os.path.join(out_dir, '__init__.py'), 'w', encoding='utf-8') as f, \
SourceBuilder(f) as builder:
builder.writeln(AUTO_GEN_NOTICE)
builder.writeln('from . import {}'.format(', '.join(
x for x in namespace_tlobjects.keys() if x
)))
builder.writeln('from .base import *')
for ns, tlobjects in namespace_tlobjects.items(): for ns, tlobjects in namespace_tlobjects.items():
file = os.path.join(out_dir, ns + '.py' if ns else '__init__.py') file = os.path.join(out_dir, ns + '.py' if ns else 'base.py')
with open(file, 'w', encoding='utf-8') as f, \ with open(file, 'w', encoding='utf-8') as f, \
SourceBuilder(f) as builder: SourceBuilder(f) as builder:
builder.writeln(AUTO_GEN_NOTICE) builder.writeln(AUTO_GEN_NOTICE)
@ -129,16 +140,12 @@ class TLGenerator:
builder.writeln( builder.writeln(
'from {}.tl.tlobject import TLObject'.format('.' * depth) 'from {}.tl.tlobject import TLObject'.format('.' * depth)
) )
builder.writeln(
'from {}.tl import types'.format('.' * depth)
)
# Add the relative imports to the namespaces, # No need to import base in base.py
# unless we already are in a namespace. if ns:
if not ns: builder.writeln(
builder.writeln('from . import {}'.format(', '.join( 'from . import base'
x for x in namespace_tlobjects.keys() if x )
)))
# Import 'get_input_*' utils # Import 'get_input_*' utils
# TODO Support them on types too # TODO Support them on types too
@ -343,7 +350,7 @@ class TLGenerator:
builder.writeln('def from_reader(reader):') builder.writeln('def from_reader(reader):')
for arg in tlobject.args: for arg in tlobject.args:
TLGenerator.write_read_code( TLGenerator.write_read_code(
builder, arg, tlobject.args, name='_' + arg.name builder, arg, tlobject, name='_' + arg.name
) )
builder.writeln('return {}({})'.format( builder.writeln('return {}({})'.format(
@ -550,15 +557,14 @@ class TLGenerator:
return True # Something was written return True # Something was written
@staticmethod @staticmethod
def write_read_code(builder, arg, args, name): def write_read_code(builder, arg, tlobject, name):
""" """
Writes the read code for the given argument, setting the Writes the read code for the given argument, setting the
arg.name variable to its read value. arg.name variable to its read value.
:param builder: The source code builder :param builder: The source code builder
:param arg: The argument to write :param arg: The argument to write
:param args: All the other arguments in TLObject same on_send. :param tlobject: The TLObject for which from_reader() method is written
This is required to determine the flags value
:param name: The name of the argument. Defaults to "self.argname" :param name: The name of the argument. Defaults to "self.argname"
This argument is an option because it's required when This argument is an option because it's required when
writing Vectors<> writing Vectors<>
@ -595,7 +601,7 @@ class TLGenerator:
builder.writeln('for _ in range(reader.read_int()):') builder.writeln('for _ in range(reader.read_int()):')
# Temporary disable .is_vector, not to enter this if again # Temporary disable .is_vector, not to enter this if again
arg.is_vector = False arg.is_vector = False
TLGenerator.write_read_code(builder, arg, args, name='_x') TLGenerator.write_read_code(builder, arg, tlobject, name='_x')
builder.writeln('{}.append(_x)'.format(name)) builder.writeln('{}.append(_x)'.format(name))
arg.is_vector = True arg.is_vector = True
@ -644,8 +650,8 @@ class TLGenerator:
if not arg.skip_constructor_id: if not arg.skip_constructor_id:
builder.writeln('{} = reader.tgread_object()'.format(name)) builder.writeln('{} = reader.tgread_object()'.format(name))
else: else:
builder.writeln('{} = types.{}.from_reader(reader)'.format( builder.writeln('{} = {}{}.from_reader(reader)'.format(
name, TLObject.class_name_for(arg.type))) name, 'base.' if tlobject.namespace else '', TLObject.class_name_for(arg.type)))
# End vector and flag blocks if required (if we opened them before) # End vector and flag blocks if required (if we opened them before)
if arg.is_vector: if arg.is_vector: