Esempio n. 1
0
File: client.py Progetto: yelban/LLL
class LineClient(object):
    def __init__(self):
        self.line_thrift = thriftpy2.load(os.path.dirname(__file__) +
                                          "/line.thrift",
                                          module_name="line_thrift")

        self.transport = THttpClient("https://gd2.line.naver.jp:443")
        self.transport.setCustomHeaders({
            "User-Agent": "Line/7.14.0 iPad5,1 10.2.0",
            "X-Line-Application": "IOSIPAD\t7.14.0\tiPhone OS\t10.12.0",
            "X-LHM": "POST",
            "X-lal": "ja-JP_JP"
        })
        self.protocol = TCompactProtocol(self.transport)
        self.transport.open()
        self.client = TClient(self.line_thrift.LineService, self.protocol)
        self._session = requests.session()

    def __write_val(self, data):
        return (chr(len(data)) + data)

    def __gen_message(self, tuple_msg):
        return (''.join(tuple_msg)).encode('utf-8')

    def __rsa_crypt(self, message, RSA):
        pub_key = rsa.PublicKey(int(RSA.nvalue, 16), int(RSA.evalue, 16))
        crypto = rsa.encrypt(message, pub_key)
        return crypto

    def _encryptedEmailAndPassword(self, mail, passwd, RSA):
        message_ = (
            self.__write_val(RSA.sessionKey),
            self.__write_val(mail),
            self.__write_val(passwd),
        )
        message = self.__gen_message(message_)
        crypto = self.__rsa_crypt(message, RSA).hex()
        return crypto

    def wait_for_confirm(self, verifier):
        r = requests.get("https://gd2.line.naver.jp/Q",
                         headers={
                             "User-Agent": LEGY_ENDPOINT.UA,
                             "X-Line-Application": LEGY_ENDPOINT.LA,
                             "x-lal": "ja-US_US",
                             "x-lpqs": LEGY_ENDPOINT.REGISTRATION,
                             "X-Line-Access": verifier
                         })
        return r.json()

    def email_login(self, email, password, cert=None):
        self.transport.path = LEGY_ENDPOINT.REGISTRATION
        rsa_key = self.client.getRSAKeyInfo(1)
        crypt = self._encryptedEmailAndPassword(email, password, rsa_key)
        self.transport.path = LEGY_ENDPOINT.AUTH_REGISTRATION
        req = self.line_thrift.loginRequest()
        req.type = 0
        req.identityProvider = 3
        req.identifier = rsa_key.keynm
        req.password = crypt
        req.keepLoggedIn = True
        req.accessLocation = "127.0.0.0"
        req.systemName = "LLL"
        req.certificate = cert
        req.verifier = None
        req.secret = crypt.encode() if type(crypt) == str else crypt
        req.e2eeVersion = 2
        result = self.client.loginZ(req)
        self.transport.path = LEGY_ENDPOINT.REGISTRATION
        if result.type == 3:
            print("Check your phone and input this pin %s" % (result.pinCode))
            r = self.wait_for_confirm(result.verifier)
            req = self.line_thrift.loginRequest(1, 1, None, None, True,
                                                "127.0.0.0", "LLL", cert,
                                                r['result']['verifier'], None,
                                                2)
            self.transport.path = LEGY_ENDPOINT.AUTH_REGISTRATION
            result = self.client.loginZ(req)
            self.authToken = result.authToken
            self.certificate = result.certificate
            self.transport.setCustomHeaders({
                "User-Agent":
                LEGY_ENDPOINT.UA,
                "X-Line-Application":
                LEGY_ENDPOINT.LA,
                "X-Line-Access":
                self.authToken
            })
        if result.type == 1:
            self.transport.path = LEGY_ENDPOINT.AUTH_REGISTRATION
            result = self.client.loginZ(req)
            self.authToken = result.authToken
            self.certificate = result.certificate
            self.transport.setCustomHeaders({
                "User-Agent":
                LEGY_ENDPOINT.UA,
                "X-Line-Application":
                LEGY_ENDPOINT.LA,
                "X-Line-Access":
                self.authToken
            })

        self.transport.path = LEGY_ENDPOINT.NORMAL

    def qr_login(self):
        self.transport.path = LEGY_ENDPOINT.REGISTRATION
        qrcode = self.client.getAuthQrcode(keepLoggedIn=1, systemName='LLL')
        url = "line://au/q/" + qrcode.verifier
        #Some user have confuced using Qrcode, so just print URL
        print(url)
        getAccessKey = self.wait_for_confirm(qrcode.verifier)
        self.transport.path = LEGY_ENDPOINT.AUTH_REGISTRATION
        req = self.line_thrift.loginRequest()
        req.type = 1
        req.verifier = qrcode.verifier
        req.e2eeVersion = 1

        res = self.client.loginZ(req)

        self.authToken = res.authToken
        self.certificate = res.certificate

        self.transport.setCustomHeaders({
            "User-Agent": LEGY_ENDPOINT.UA,
            "X-Line-Application": LEGY_ENDPOINT.LA,
            "X-Line-Access": self.authToken
        })

        self.transport.path = LEGY_ENDPOINT.NORMAL
Esempio n. 2
0
class LINE(object):
    def __init__(self):
        self.thrift = thriftpy2.load("line.thrift")

        self.transport = THttpClient(Config.HOST)
        self.transport.setCustomHeaders({
            "User-Agent": Config.UA,
            "X-Line-Application": Config.LA,
            "X-Line-Carrier": Config.CARRIER,
            "X-LHM": "POST",
            "X-lal": "ja-JP_JP"
        })
        self.protocol = TCompactProtocol(self.transport)
        self.transport.open()
        self.client = TClient(self.thrift.Service, self.protocol)
        self.certificate = None

    def __loadSession(self):
        # Talk Service
        self.transport.setCustomHeaders({
            "User-Agent": Config.UA,
            "X-Line-Carrier": Config.CARRIER,
            "X-Line-Application": Config.LA,
            "X-Line-Access": self.authToken
        })

        self.transport.path = Config.LINE_API_QUERY_PATH_FIR
        self.talk = TClient(self.thrift.Service, self.protocol)
        self.profile = self.talk.getProfile()
        print("[Login success] " + self.profile.displayName)

        self.transport.path = Config.LONG_POLLING
        self.poll = TClient(self.thrift.Service, self.protocol)
        self.revision = self.poll.getLastOpRevision()

    def loginWithQrCode(self):

        self.transport.path = Config.AUTH_QUERY_PATH
        res = self.client.getAuthQrcode(True, Config.SYSTEM_NAME)
        print("line://au/q/" + res.verifier)

        headers = {
            "User-Agent": Config.UA,
            "X-Line-Application": Config.LA,
            "X-Line-Carrier": Config.CARRIER,
            "x-lal": "ja-US_US",
            "x-lpqs": Config.AUTH_QUERY_PATH,
            "X-Line-Access": res.verifier
        }
        verifier = requests.get(Config.HOST + Config.LINE_CERTIFICATE_PATH,
                                headers=headers).json()["result"]["verifier"]

        try:
            self.transport.path = Config.AUTH_REGISTRATION
            LR = self.thrift.LoginRequest()
            LR.type = self.thrift.LoginType.QRCODE
            LR.identityProvider = self.thrift.IdentityProvider.LINE
            LR.keepLoggedIn = True
            LR.accessLocation = Config.IP_ADDR
            LR.verifier = verifier
            LR.e2eeVersion = 1
            result = self.client.loginZ(LR)
        except:
            raise Exception('Login failed')

        if result.type == LoginResultType.SUCCESS:
            if result.authToken is not None:
                self.loginWithAuthToken(result.authToken)
            else:
                return False
        else:
            raise Exception('Login failed')

    def loginWithCredential(self, mail, password, certificate=None):

        self.transport.path = Config.AUTH_QUERY_PATH
        RSAKey = self.client.getRSAKeyInfo(self.thrift.IdentityProvider.LINE)
        message = (chr(len(RSAKey.sessionKey)) + RSAKey.sessionKey +
                   chr(len(mail)) + mail + chr(len(password)) +
                   password).encode('utf-8')
        pub_key = rsa.PublicKey(int(RSAKey.nvalue, 16), int(RSAKey.evalue, 16))
        crypto = rsa.encrypt(message, pub_key).hex()

        try:
            with open(mail + '.crt', 'r') as f:
                self.certificate = f.read()
        except:
            if certificate is not None:
                self.certificate = certificate

        LR = self.thrift.LoginRequest()
        LR.type = self.thrift.LoginType.ID_CREDENTIAL
        LR.identityProvider = self.thrift.IdentityProvider.LINE
        LR.identifier = RSAKey.keynm
        LR.password = crypto
        LR.keepLoggedIn = True
        LR.accessLocation = Config.IP_ADDR
        LR.systemName = Config.SYSTEM_NAME
        LR.certificate = self.certificate
        LR.e2eeVersion = 1

        self.transport.path = Config.AUTH_REGISTRATION
        result = self.client.loginZ(LR)

        if result.type == self.thrift.LoginResultType.REQUIRE_DEVICE_CONFIRM:
            print("Enter pincode: " + result.pinCode)

            headers = {
                "User-Agent": Config.UA,
                "X-Line-Application": Config.LA,
                "X-Line-Carrier": Config.CARRIER,
                "X-Line-Access": result.verifier
            }
            verifier = requests.get(
                Config.HOST + Config.LINE_CERTIFICATE_PATH,
                headers=headers).json()["result"]["verifier"]

            try:
                LR = self.thrift.LoginRequest()
                LR.type = self.thrift.LoginType.QRCODE
                LR.keepLoggedIn = True
                LR.verifier = verifier
                LR.e2eeVersion = 1
                result = self.client.loginZ(LR)
            except:
                raise Exception('Login failed')

            if result.type == self.thrift.LoginResultType.SUCCESS:
                if result.certificate is not None:
                    with open(mail + '.crt', 'w') as f:
                        f.write(result.certificate)
                    self.certificate = result.certificate
                if result.authToken is not None:
                    self.loginWithAuthToken(result.authToken)
                else:
                    return False
            else:
                raise Exception('Login failed')

        elif result.type == self.thrift.LoginResultType.REQUIRE_QRCODE:
            self.loginWithQrCode()
            pass

        elif result.type == self.thrift.LoginResultType.SUCCESS:
            self.certificate = result.certificate
            self.loginWithAuthToken(result.authToken)

    def loginWithAuthToken(self, authToken=None):
        if authToken is None:
            raise Exception('Please provide Auth Token')

        self.authToken = authToken
        self.__loadSession()