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
import thriftpy2 from thriftpy2.http import THttpClient from thriftpy2.protocol import TCompactProtocol from thriftpy2.thrift import TClient line_thrift = thriftpy2.load("line.thrift", module_name="line_thrift") transport = THttpClient("https://gd2.line.naver.jp:443/S4") 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" }) protocol = TCompactProtocol(transport) transport.open() client = TClient(line_thrift.LineService, protocol) transport.path = "/api/v4/TalkService.do" qr = client.getAuthQrcode(keepLoggedIn=1, systemName="LLL")
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()