Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/yowsup/common/tools.py b/yowsup/common/tools.py
- index 328fbb1..edf95c0 100644
- --- a/yowsup/common/tools.py
- +++ b/yowsup/common/tools.py
- @@ -46,7 +46,17 @@ class WATools:
- f.close()
- b64Hash = base64.b64encode(sha1.digest())
- return b64Hash if type(b64Hash) is str else b64Hash.decode()
- -
- +
- + @staticmethod
- + def getFileHashForUpload2(filePath):
- + sha1 = hashlib.sha256()
- + f = open(filePath, 'rb')
- + try:
- + hash = hashlib.sha256(f.read()).hexdigest()
- + finally:
- + f.close()
- + return hash
- +
- class StorageTools:
- @staticmethod
- def constructPath(*path):
- diff --git a/yowsup/demos/cli/layer.py b/yowsup/demos/cli/layer.py
- index e6b319d..c56fa6d 100644
- --- a/yowsup/demos/cli/layer.py
- +++ b/yowsup/demos/cli/layer.py
- @@ -22,7 +22,13 @@ from yowsup.layers.protocol_profiles.protocolentities import *
- from yowsup.common.tools import Jid
- from yowsup.common.optionalmodules import PILOptionalModule, AxolotlOptionalModule
- -logger = logging.getLogger(__name__)
- +logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
- +logger = logging.getLogger()
- +
- +fileHandler = logging.FileHandler("{0}/{1}.log".format("/tmp", "yowsup"))
- +fileHandler.setFormatter(logFormatter)
- +logger.addHandler(fileHandler)
- +
- class YowsupCliLayer(Cli, YowInterfaceLayer):
- PROP_RECEIPT_AUTO = "org.openwhatsapp.yowsup.prop.cli.autoreceipt"
- PROP_RECEIPT_KEEPALIVE = "org.openwhatsapp.yowsup.prop.cli.keepalive"
- @@ -404,7 +410,6 @@ class YowsupCliLayer(Cli, YowInterfaceLayer):
- errorFn = lambda errorEntity, originalEntity: self.onRequestUploadError(jid, path, errorEntity, originalEntity)
- self._sendIq(entity, successFn, errorFn)
- - self._sendIq(entity, successFn, errorFn)
- @clicmd("Send typing state")
- def state_typing(self, jid):
- if self.assertConnected():
- @@ -508,7 +513,8 @@ class YowsupCliLayer(Cli, YowInterfaceLayer):
- output = self.__class__.MESSAGE_FORMAT.format(
- FROM = sender,
- TIME = formattedDate,
- - MESSAGE = messageOut.encode('latin-1').decode() if sys.version_info >= (3, 0) else messageOut,
- + MESSAGE = messageOut,
- + #MESSAGE = messageOut if sys.version_info >= (3, 0) else messageOut,
- MESSAGE_ID = message.getId()
- )
- diff --git a/yowsup/layers/axolotl/layer_send.py b/yowsup/layers/axolotl/layer_send.py
- index bbeacd8..55296cf 100644
- --- a/yowsup/layers/axolotl/layer_send.py
- +++ b/yowsup/layers/axolotl/layer_send.py
- @@ -9,7 +9,7 @@ from axolotl.axolotladdress import AxolotlAddress
- from axolotl.protocol.whispermessage import WhisperMessage
- from axolotl.groups.senderkeyname import SenderKeyName
- from axolotl.groups.groupsessionbuilder import GroupSessionBuilder
- -
- +import binascii
- import logging
- from random import randint
- @@ -42,21 +42,49 @@ class AxolotlSendLayer(AxolotlBaseLayer):
- def __str__(self):
- return "Axolotl Layer"
- + def handleEncNode(self, node):
- + recipient_id = node["to"].split('@')[0]
- + v2 = node["to"]
- + if node.getChild("enc"): # media enc is only for v2 messsages
- + messageData = self.serializeToProtobuf(node)
- + # print (messageData)
- + if messageData:
- + sessionCipher = self.getSessionCipher(recipient_id)
- + messageData = messageData.SerializeToString() + self.getPadding()
- + ciphertext = sessionCipher.encrypt(messageData)
- + print ("masuk ENC")
- +
- + mediaType = node.getChild("enc")["type"] if node.getChild("enc") else None
- +
- + encEntity = EncryptedMessageProtocolEntity(
- + [
- + EncProtocolEntity(
- + EncProtocolEntity.TYPE_MSG if ciphertext.__class__ == WhisperMessage else EncProtocolEntity.TYPE_PKMSG,
- + 2 if v2 else 1,
- + ciphertext.serialize(), mediaType)],
- + "text" if not mediaType else "media",
- + _id=node["id"],
- + to=node["to"],
- + notify=node["notify"],
- + timestamp=node["timestamp"],
- + participant=node["participant"],
- + offline=node["offline"],
- + retry=node["retry"]
- + )
- + self.toLower(encEntity.toProtocolTreeNode())
- + else: # case of unserializable messages (audio, video) ?
- + print ("kok masuk sini?")
- + self.toLower(node)
- + else:
- + self.toLower(node)
- +
- def send(self, node):
- if node.tag == "message" and node["to"] not in self.skipEncJids and not node.getChild("enc") and (not node.getChild("media") or node.getChild("media")["mediakey"]):
- self.processPlaintextNodeAndSend(node)
- - # elif node.tag == "iq" and node["xmlns"] == "w:m":
- - # mediaNode = node.getChild("media")
- - # if mediaNode and mediaNode["type"] == "image":
- - # iqNode = IqProtocolEntity.fromProtocolTreeNode(node).toProtocolTreeNode()
- - # iqNode.addChild(ProtocolTreeNode(
- - # "encr_media", {
- - # "type": mediaNode["type"],
- - # "hash": mediaNode["hash"]
- - # }
- - # ))
- - # self.toLower(iqNode)
- + elif node.getChild("enc"):
- + print ("Masuk enc")
- + self.handleEncNode(node)
- else:
- self.toLower(node)
- @@ -229,8 +257,8 @@ class AxolotlSendLayer(AxolotlBaseLayer):
- def serializeToProtobuf(self, node, message = None):
- if node.getChild("body"):
- return self.serializeTextToProtobuf(node, message)
- - elif node.getChild("media"):
- - return self.serializeMediaToProtobuf(node.getChild("media"), message)
- + elif node.getChild("enc"):
- + return self.serializeMediaToProtobuf(node.getChild("enc"), message)
- else:
- raise ValueError("No body or media nodes found")
- @@ -279,14 +307,20 @@ class AxolotlSendLayer(AxolotlBaseLayer):
- image_message.width = int(mediaNode["width"])
- image_message.height = int(mediaNode["height"])
- image_message.mime_type = mediaNode["mimetype"]
- - image_message.file_sha256 = mediaNode["filehash"]
- + image_message.file_sha256 = binascii.unhexlify(mediaNode["filehash"].encode())
- image_message.file_length = int(mediaNode["size"])
- + image_message.media_key = binascii.unhexlify(mediaNode["anu"])
- + #image_message.media_key = mediaNode["anu"]
- image_message.caption = mediaNode["caption"] or ""
- image_message.jpeg_thumbnail = mediaNode.getData()
- +
- + print ("mimeType: "+ mediaNode["mimetype"])
- m.image_message.MergeFrom(image_message)
- return m
- + # return
- + # return image_message
- def serializeUrlToProtobuf(self, node, message = None):
- pass
- diff --git a/yowsup/layers/protocol_media/mediauploader.py b/yowsup/layers/protocol_media/mediauploader.py
- index da9b3d1..3eeeeba 100644
- --- a/yowsup/layers/protocol_media/mediauploader.py
- +++ b/yowsup/layers/protocol_media/mediauploader.py
- @@ -1,3 +1,11 @@
- +import base64
- +import hmac
- +from Crypto.Cipher import AES
- +import binascii
- +from axolotl.kdf.hkdfv3 import HKDFv3
- +from axolotl.sessioncipher import pad
- +from axolotl.util.byteutil import ByteUtil
- +
- from yowsup.common.http.warequest import WARequest
- from yowsup.common.http.waresponseparser import JSONResponseParser
- import socket, ssl, os, hashlib, sys
- @@ -36,6 +44,17 @@ class MediaUploader(WARequest, threading.Thread):
- else:
- self.run()
- + def encryptImg(self,img, refkey):
- + img = pad(img)
- + derivative = HKDFv3().deriveSecrets(binascii.unhexlify(refkey),
- + binascii.unhexlify("576861747341707020496d616765204b657973"), 112)
- + parts = ByteUtil.split(derivative, 16, 32)
- + iv = parts[0]
- + cipherKey = parts[1]
- + cipher = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
- + imgEnc = cipher.encrypt(img)
- + return imgEnc[:-22]
- +
- def run(self):
- sourcePath = self.sourcePath
- @@ -48,7 +67,24 @@ class MediaUploader(WARequest, threading.Thread):
- try:
- filename = os.path.basename(sourcePath)
- filetype = MimeTools.getMIME(filename)
- - filesize = os.path.getsize(sourcePath)
- + f = open(sourcePath, 'rb')
- + stream = f.read()
- + f.close()
- + refkey = binascii.hexlify(os.urandom(32))
- + print (refkey)
- + stream=self.encryptImg(stream,refkey)
- + fenc = open(filename+".enc", 'wb') # bahtiar
- + fenc.write(stream)
- + fenc.seek(0, 2)
- + filesize=fenc.tell()
- + fenc.close()
- +
- + sha1 = hashlib.sha256()
- + sha1.update(stream)
- + b64Hash = base64.b64encode(sha1.digest())
- + # b64Hash = base64.b64encode(sha1.hexdigest())
- +
- + # filesize = os.path.getsize(sourcePath)
- self.sock.connect((self.url, self.port))
- ssl_sock = ssl.wrap_socket(self.sock)
- @@ -60,16 +96,25 @@ class MediaUploader(WARequest, threading.Thread):
- boundary = "zzXXzzYYzzXXzzQQ"#"-------" + m.hexdigest() #"zzXXzzYYzzXXzzQQ"
- contentLength = 0
- + digTo = hmac.new("".encode("utf-8"), self.jid.replace("@s.whatsapp.net", "@c.us").encode("utf-8"),
- + hashlib.sha256).digest()[:20]
- + refTo = base64.b64encode(digTo).decode()
- + digFrom = hmac.new("".encode("utf-8"), self.accountJid.replace("@s.whatsapp.net", "@c.us").encode("utf-8"),
- + hashlib.sha256).digest()[:20]
- + refFrom = base64.b64encode(digFrom).decode()
- +
- hBAOS = "--" + boundary + "\r\n"
- - hBAOS += "Content-Disposition: form-data; name=\"to\"\r\n\r\n"
- - hBAOS += self.jid + "\r\n"
- + hBAOS += "Content-Disposition: form-data; name=\"hash\"\r\n\r\n"
- + hBAOS += b64Hash.decode() + "\r\n"
- +
- hBAOS += "--" + boundary + "\r\n"
- - hBAOS += "Content-Disposition: form-data; name=\"from\"\r\n\r\n"
- - hBAOS += self.accountJid.replace("@whatsapp.net","") + "\r\n"
- + hBAOS += "Content-Disposition: form-data; name=\"refs\"\r\n\r\n"
- + hBAOS += refFrom + "\r\n"
- + hBAOS += refTo + "\r\n"
- hBAOS += "--" + boundary + "\r\n"
- - hBAOS += "Content-Disposition: form-data; name=\"file\"; filename=\"" + crypto + "\"\r\n"
- - hBAOS += "Content-Type: " + filetype + "\r\n\r\n"
- + hBAOS += "Content-Disposition: form-data; name=\"file\"; filename=\"" + "blob" + "\"\r\n"
- + hBAOS += "Content-Type: " + "application/octet-stream" + "\r\n\r\n"
- fBAOS = "\r\n--" + boundary + "--\r\n"
- @@ -88,9 +133,6 @@ class MediaUploader(WARequest, threading.Thread):
- totalsent = 0
- buf = 1024
- - f = open(sourcePath, 'rb')
- - stream = f.read()
- - f.close()
- status = 0
- lastEmit = 0
- @@ -118,6 +160,9 @@ class MediaUploader(WARequest, threading.Thread):
- if self.progressCallback:
- self.progressCallback(self.sourcePath, self.jid, uploadUrl, 100)
- + # f = open("/tmp/data.log", 'wb') #bahtiar
- + # f.write("\n"+hBAOS.encode()+"\nRESPONSE:\n"+data)
- + # f.close()
- lines = data.decode().splitlines()
- @@ -135,7 +180,10 @@ class MediaUploader(WARequest, threading.Thread):
- if result["url"] is not None:
- if self.successCallback:
- - self.successCallback(sourcePath, self.jid, result["url"])
- + # self.successCallback(sourcePath, self.jid, result["url"])
- + print (result)
- + result["mediaKey"]=refkey
- + self.successCallback(sourcePath, self.jid, result)
- else:
- logger.exception("uploadUrl: %s, result of uploading media has no url" % uploadUrl)
- if self.errorCallback:
- diff --git a/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py b/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py
- index bdd1e69..7a2a1a8 100644
- --- a/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py
- +++ b/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py
- @@ -62,7 +62,7 @@ class RequestUploadIqProtocolEntity(IqProtocolEntity):
- }
- if self.origHash:
- attribs["orighash"] = self.origHash
- - mediaNode = ProtocolTreeNode("media", attribs)
- + mediaNode = ProtocolTreeNode("encr_media", attribs)
- node.addChild(mediaNode)
- return node
- @@ -71,7 +71,7 @@ class RequestUploadIqProtocolEntity(IqProtocolEntity):
- assert node.getAttributeValue("type") == "set", "Expected set as iq type in request upload, got %s" % node.getAttributeValue("type")
- entity = IqProtocolEntity.fromProtocolTreeNode(node)
- entity.__class__ = RequestUploadIqProtocolEntity
- - mediaNode = node.getChild("media")
- + mediaNode = node.getChild("encr_media")
- entity.setRequestArguments(
- mediaNode.getAttributeValue("type"),
- mediaNode.getAttributeValue("hash"),
- diff --git a/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py b/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py
- index 45e7eb8..2ca58c4 100644
- --- a/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py
- +++ b/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py
- @@ -35,7 +35,7 @@ class ResultRequestUploadIqProtocolEntity(ResultIqProtocolEntity):
- node = super(ResultRequestUploadIqProtocolEntity, self).toProtocolTreeNode()
- if not self.isDuplicate():
- - mediaNode = ProtocolTreeNode("media", {"url": self.url})
- + mediaNode = ProtocolTreeNode("encr_media", {"url": self.url})
- if self.ip:
- mediaNode["ip"] = self.ip
- @@ -51,7 +51,7 @@ class ResultRequestUploadIqProtocolEntity(ResultIqProtocolEntity):
- def fromProtocolTreeNode(node):
- entity= ResultIqProtocolEntity.fromProtocolTreeNode(node)
- entity.__class__ = ResultRequestUploadIqProtocolEntity
- - mediaNode = node.getChild("media")
- + mediaNode = node.getChild("encr_media")
- if mediaNode:
- entity.setUploadProps(mediaNode["url"], mediaNode["ip"], mediaNode["resume"])
- else:
- diff --git a/yowsup/layers/protocol_media/protocolentities/message_media.py b/yowsup/layers/protocol_media/protocolentities/message_media.py
- index b86c3d5..15499dc 100644
- --- a/yowsup/layers/protocol_media/protocolentities/message_media.py
- +++ b/yowsup/layers/protocol_media/protocolentities/message_media.py
- @@ -124,7 +124,7 @@ class MediaMessageProtocolEntity(MessageProtocolEntity):
- def toProtocolTreeNode(self):
- node = super(MediaMessageProtocolEntity, self).toProtocolTreeNode()
- - mediaNode = ProtocolTreeNode("media", {"type": self.mediaType}, None, None)
- + mediaNode = ProtocolTreeNode("enc", {"type": self.mediaType}, None, None)
- node.addChild(mediaNode)
- if self.preview:
- mediaNode.setData(self.preview)
- diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py
- index 2694fa3..5ef7310 100644
- --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py
- +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py
- @@ -34,6 +34,8 @@ class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity):
- out += "IP: %s\n" % self.ip
- out += "File Size: %s\n" % self.size
- out += "File name: %s\n" % self.fileName
- + print (out)
- +
- return out
- def getMediaSize(self):
- @@ -56,18 +58,22 @@ class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity):
- def toProtocolTreeNode(self):
- node = super(DownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
- - mediaNode = node.getChild("media")
- + mediaNode = node.getChild("enc")
- mediaNode.setAttribute("mimetype", self.mimeType)
- mediaNode.setAttribute("filehash", self.fileHash)
- - mediaNode.setAttribute("url", self.url)
- + mediaNode.setAttribute("url", self.url["url"].encode())
- if self.ip:
- mediaNode.setAttribute("ip", self.ip)
- mediaNode.setAttribute("size", str(self.size))
- mediaNode.setAttribute("file", self.fileName)
- - if self.mediaKey:
- - mediaNode.setAttribute("mediakey", self.mediaKey)
- -
- + mediaNode.setAttribute("mediakey", self.url["mediaKey"])
- + mediaNode.setAttribute("anu", self.url["mediaKey"])
- + print ("MEDIAKEY:" + str(self.url["mediaKey"]))
- + print ("MIMETYPE:" + self.mimeType)
- + print ("FILEHASH:" + self.fileHash)
- + print ("FILEHASH:" + self.fileHash)
- return node
- + # return node
- def isEncrypted(self):
- return self.mediaKey is not None
- @@ -93,8 +99,17 @@ class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity):
- url = builder.get("url")
- ip = builder.get("ip")
- assert url, "Url is required"
- - mimeType = builder.get("mimetype", MimeTools.getMIME(builder.getOriginalFilepath())[0])
- - filehash = WATools.getFileHashForUpload(builder.getFilepath())
- + mimeType = builder.get("mimetype", MimeTools.getMIME(builder.getOriginalFilepath()))
- + filehash = WATools.getFileHashForUpload2(builder.getFilepath())
- size = os.path.getsize(builder.getFilepath())
- fileName = os.path.basename(builder.getFilepath())
- return DownloadableMediaMessageProtocolEntity(builder.mediaType, mimeType, filehash, url, ip, size, fileName, to = builder.jid, preview = builder.get("preview"))
- +
- + @staticmethod
- + def fromFilePath(fpath, url, mediaType, ip, to, mimeType = None, preview = None, filehash = None, filesize = None):
- + mimeType = mimeType or MimeTools.getMIME(fpath)
- + filehash = filehash or WATools.getFileHashForUpload(fpath)
- + size = filesize or os.path.getsize(fpath)
- + fileName = os.path.basename(fpath)
- +
- + return DownloadableMediaMessageProtocolEntity(mediaType, mimeType, filehash, url, ip, size, fileName, to = to, preview = preview)
- diff --git a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py
- index cc7b2e5..66e421c 100644
- --- a/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py
- +++ b/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py
- @@ -56,7 +56,8 @@ class ImageDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtoc
- def toProtocolTreeNode(self):
- node = super(ImageDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
- - mediaNode = node.getChild("media")
- + mediaNode = node.getChild("enc")
- + print ("MIME:" + self.mimeType)
- mediaNode.setAttribute("encoding", self.encoding)
- mediaNode.setAttribute("width", str(self.width))
Add Comment
Please, Sign In to add comment