Ejemplo n.º 1
0
def parse_oem_options(api_key):
    """
    解析oem帐号选项
    :param api_key:
    """
    if not isinstance(api_key, str):
        return None
    if not OEM_KEY_PATTERN.search(api_key):
        #正则已修改
        return None

    if api_key.startswith('a685'):
        #兼容山西旧key
        api_key = '9006'

    head = int(api_key[:4], 16)
    #版本
    ver = span_bits(head, 15, 12)
    if not (ver >> 3):
        return None

    ver &= 0b111
    #todo: 检查版本号
    #短信相关选项。批量推送,凌拓帐号,短信,手机号码,密码
    return span_bits(head, 5, 0, 0)
Ejemplo n.º 2
0
def extract_ref_l(ref):
    """
    解析ref:长字符串
    :param ref:
    :return:
    """
    logger.debug('extract ref begin')

    if not ref or not isinstance(ref, str) or ref == '':
        return None
    ref = rc4_decrypt(ref, ref_pwd, a2b_hex)
    logger.debug(u'ref = %r', ref)
    if len(ref) <= 3:
        #至少要求3字节
        return None

    head, acc_len, key_cipher_len = struct.unpack('>BBB', ref[:3])
    logger.debug(u'head = %r, acc_len = %r, key_cipher_len = %r', head,
                 acc_len, key_cipher_len)
    if len(ref) != 3 + acc_len + key_cipher_len + MAX_FILENAME_LEN:
        return None

    acc = ref[3:acc_len + 3]
    key_cipher = ref[acc_len + 3:acc_len + 3 + key_cipher_len]
    logger.debug(u'acc = %r, key_cipher = %r', acc, key_cipher)
    logger.debug(u'rc4 decrypt result = %r',
                 rc4_decrypt(key_cipher, ref_pwd, None))
    if acc != rc4_decrypt(key_cipher, ref_pwd, None):
        return None

    share, by_app = span_bits(head, 7, 6, 0)

    logger.debug('extract ref end')

    return share, by_app, acc, unpad(ref[-MAX_FILENAME_LEN:])
Ejemplo n.º 3
0
def extract_ref_s(ref):
    """
    解析ref:短字符串
    :param ref:
    :return:
    """
    b64str = base64.b64decode(str(ref))
    head, acc_len = struct.unpack('>BB', b64str[:2])
    share, by_app = span_bits(head, 7, 6, 0)
    return share, by_app, b64str[2:acc_len + 2], b64str[acc_len + 2:]
Ejemplo n.º 4
0
def parse_io_options(bits, split=True):
    """
    io选项在绑定设备和用户关系时需要提取,其他时候用不到
    id格式的转换需要把io选项排除在外

    :param split: io选项拆分
    """
    assert isinstance(bits, int) and bits <= 0b111
    if not split:
        return bits
    # 数据,短信,蓝牙
    return span_bits(bits, 2, 0, 0)
Ejemplo n.º 5
0
def extract_tk_s(tk, ul):
    """
    :param ul: 上传:短字符串
    """
    b64str = base64.b64decode(str(tk))
    head, acc_len = struct.unpack('>BB', b64str[:2])
    share, by_app, is_ul = span_bits(head, 7, 5, 0)

    #10分钟有效
    ts_offset = 2 + acc_len
    t = struct.unpack('>I', b64str[ts_offset:ts_offset + 4])[0]
    if time.time() - t >= 600:
        return None
    return share, by_app, b64str[2:acc_len + 2], b64str[ts_offset + 4:]
Ejemplo n.º 6
0
def extract_tk_l(tk, ul):
    """
    :param ul: 上传:长字符串
    """
    logger.debug('extract tk begin')
    if not tk or not isinstance(tk, str) or len(tk) <= 2:
        logger.info('tk too short')
        return None
    tk = rc4_decrypt(tk, tk_pwd, a2b_hex)
    logger.debug(u'tk = %r', tk)
    rnd, val = tk[-2:]
    val = rc4_decrypt(val, tk_pwd, None)
    logger.debug('rnd = %r, val = %r', rnd, val)
    rnd = struct.unpack('>B', rnd)[0]
    val = struct.unpack('>B', val)[0]
    logger.debug('rnd = %r, val = %r', rnd, val)

    if rnd + 1 != val:
        logger.warn('rnd={0} & val={1} unmatch'.format(rnd, val))
        return None

    head, acc_len = struct.unpack('>BB', tk[:2])
    logger.debug('head = %r, acc_len = %r', head, acc_len)
    if len(tk) != 2 + acc_len + 4 + MAX_FILENAME_LEN + 2:
        logger.warn('tk len not ok')
        return None

    #10分钟有效
    ts_offset = 2 + acc_len
    t = struct.unpack('>I', tk[ts_offset:ts_offset + 4])[0]
    now = time.time()
    logger.debug('now = %r, t = %r', now, t)

    if now - struct.unpack('>I', tk[ts_offset:ts_offset + 4])[0] >= 600:
        logger.warn('tk timeout')
        logger.debug('now = %r, t = %r', now, t)
        return None

    share, by_app, is_ul = span_bits(head, 7, 5, 0)
    logger.debug('share = %r, by_app = %r, is_ul = %r, ul=%r', share, by_app,
                 is_ul, ul)
    if is_ul != ul:
        logger.warn('ul param invalid')
        return None

    logger.debug('extract tk end')

    return share, by_app, tk[2:acc_len + 2], unpad(tk[ts_offset + 4:ts_offset +
                                                      4 + MAX_FILENAME_LEN])