2020-09-09 10:41:48 +00:00
import os , sys ; sys . path . append ( os . path . abspath ( os . path . join ( os . path . abspath ( os . path . join ( os . path . dirname ( __file__ ) , ' .. ' ) ) , ' .. ' ) ) )
from komrade import *
from komrade . backend import *
def is_valid_msg_d ( msg_d ) :
if not type ( msg_d ) == dict : return False
2020-09-12 18:18:37 +00:00
to_name = msg_d . get ( ' to_name ' )
to_pub = msg_d . get ( ' to ' )
from_name = msg_d . get ( ' from_name ' )
from_pub = msg_d . get ( ' from ' )
msg = msg_d . get ( ' msg ' )
# if to_name and to_pub and from_name and from_pub and msg: return True
if to_pub and from_pub and msg : return True
2020-09-09 10:41:48 +00:00
return False
class Message ( Logger ) :
2020-09-15 06:39:11 +00:00
def __init__ ( self , msg_d = { } , from_whom = None , to_whom = None , msg = None ) :
2020-09-09 10:41:48 +00:00
# check input
self . msg_d = msg_d
2020-09-15 06:39:11 +00:00
self . to_name = msg_d . get ( ' to_name ' ) if not to_whom else to_whom . name
self . to_pubkey = msg_d . get ( ' to ' ) if not to_whom else to_whom . uri
self . from_name = msg_d . get ( ' from_name ' ) if not from_whom else from_whom . name
2020-09-15 07:04:01 +00:00
self . from_pubkey = msg_d . get ( ' from ' ) if not from_whom else from_whom . uri
2020-09-15 06:39:11 +00:00
self . msg = msg_d . get ( ' msg ' ) if not msg else msg
2020-09-09 10:58:00 +00:00
self . _route = msg_d . get ( ROUTE_KEYNAME )
2020-09-09 21:30:14 +00:00
self . _is_encrypted = None
2020-09-14 06:02:17 +00:00
2020-09-15 06:42:42 +00:00
# reset msg_d
self . msg_d = {
' msg ' : self . msg ,
' to ' : self . to_pubkey ,
' to_name ' : self . to_name ,
' from ' : self . from_pubkey ,
' from_name ' : self . from_name
}
2020-09-12 22:06:28 +00:00
2020-09-10 08:19:08 +00:00
def __repr__ ( self ) :
2020-09-12 22:10:42 +00:00
# self.log('my type??',type(self.msg),self.msg)
2020-09-12 18:18:37 +00:00
if type ( self . msg ) == dict :
2020-09-12 21:15:25 +00:00
if is_valid_msg_d ( self . msg ) :
2020-09-12 21:47:08 +00:00
import textwrap
msg = textwrap . indent ( repr ( Message ( self . msg ) ) , ' ' * 10 )
2020-09-15 13:54:00 +00:00
elif ' txt ' in self . msg :
msg = self . msg . get ( ' txt ' )
2020-09-12 21:15:25 +00:00
else :
2020-09-13 08:54:01 +00:00
msg = dict_format ( self . msg , tab = 6 )
2020-09-12 21:50:28 +00:00
elif type ( self . msg ) == bytes :
2020-09-13 07:12:22 +00:00
msg = b64enc_s ( self . msg )
2020-09-12 18:18:37 +00:00
else :
msg = self . msg
2020-09-15 10:17:06 +00:00
2020-09-17 08:59:27 +00:00
# return str(msg)
msg_s = wrapp ( str ( msg ) )
hdr = ' # ' * CLI_WIDTH
2020-09-16 12:41:42 +00:00
return f """
{ hdr }
2020-09-16 19:13:41 +00:00
from : @ { self . from_name if self . from_name else ' ' }
to : @ { self . to_name if self . to_name else ' ' }
2020-09-16 12:41:42 +00:00
{ hdr }
{ msg_s }
{ hdr }
2020-09-12 18:18:37 +00:00
"""
2020-09-10 08:19:08 +00:00
2020-09-09 19:53:58 +00:00
@property
2020-09-09 21:30:14 +00:00
def data ( self ) :
2020-09-09 19:53:58 +00:00
md = { }
2020-09-09 20:07:50 +00:00
msg_d = self . msg_d
while msg_d :
2020-09-09 20:09:30 +00:00
for k , v in msg_d . items ( ) : md [ k ] = v
2020-09-12 18:18:37 +00:00
msg_d = msg_d . get ( ' msg ' , { } )
2020-09-09 20:14:49 +00:00
if type ( msg_d ) != dict : msg_d = None
2020-09-12 18:18:37 +00:00
if ' msg ' in md and type ( md [ ' msg ' ] ) == dict :
del md [ ' msg ' ]
2020-09-15 13:33:43 +00:00
if ROUTE_KEYNAME in md :
2020-09-15 13:33:14 +00:00
del md [ ROUTE_KEYNAME ]
2020-09-09 20:03:39 +00:00
return md
2020-09-09 10:58:00 +00:00
2020-09-14 04:07:06 +00:00
def return_to_sender ( self , new_msg = None ) :
2020-09-13 09:13:02 +00:00
2020-09-14 04:07:06 +00:00
self . log ( ' making return to sender. v1: ' , self )
2020-09-13 09:13:02 +00:00
2020-09-14 04:07:06 +00:00
new_msg = Message (
{
' from ' : self . msg_d . get ( ' to ' ) ,
' to ' : self . msg_d . get ( ' from ' ) ,
' from_name ' : self . msg_d . get ( ' to_name ' ) ,
' to_name ' : self . msg_d . get ( ' from_name ' ) ,
' msg ' : new_msg if new_msg else self . msg_d . get ( ' msg ' )
2020-09-14 06:02:17 +00:00
}
2020-09-14 04:07:06 +00:00
)
self . log ( ' returning: ' , new_msg )
return new_msg
2020-09-09 14:38:37 +00:00
@property
2020-09-09 22:01:41 +00:00
def from_whom ( self ) :
2020-09-14 06:25:43 +00:00
# from komrade.backend.komrades import Komrade
2020-09-14 06:02:17 +00:00
return Komrade ( self . from_name , pubkey = self . from_pubkey )
2020-09-09 14:38:37 +00:00
@property
2020-09-09 22:01:41 +00:00
def to_whom ( self ) :
2020-09-14 06:25:43 +00:00
# from komrade.backend.komrades import Komrade
2020-09-14 06:02:17 +00:00
return Komrade ( self . to_name , pubkey = self . to_pubkey )
2020-09-09 14:38:37 +00:00
2020-09-09 10:41:48 +00:00
2020-09-09 23:07:03 +00:00
def decrypt ( self , recursive = False ) :
2020-09-10 07:57:02 +00:00
# check if needs decryption
2020-09-09 21:42:01 +00:00
if not self . is_encrypted : return
2020-09-10 07:57:02 +00:00
# otherwise lets do it
self . msg_encr = self . msg
2020-09-13 11:27:26 +00:00
self . log ( f ' Attempting to decrypt: \n { self } ' )
2020-09-09 19:41:14 +00:00
2020-09-09 10:41:48 +00:00
# decrypt msg
2020-09-14 08:25:55 +00:00
# self.log('attempting to decrypt',self.msg,'from',self.from_pubkey,'to',self.to_pubkey, self.to_whom,dict_format(self.to_whom.keychain()),self.to_whom.assemble(self.to_whom.keychain()))
2020-09-14 04:12:32 +00:00
if not self . to_whom . privkey :
2020-09-14 06:21:17 +00:00
self . log ( f ' { self . to_whom } cannot decrypt this message! { dict_format ( self . to_whom . keychain ( ) ) } ! \n \n { self . to_whom . name } { self . to_whom . pubkey } { self . to_name } { self . to_pubkey } { self . to_whom . keychain ( ) } ' )
2020-09-14 04:12:32 +00:00
return
2020-09-12 18:18:37 +00:00
self . msg = self . msg_d [ ' msg ' ] = decr_msg_b = SMessage (
2020-09-12 19:31:29 +00:00
self . to_whom . privkey . data ,
2020-09-14 21:19:19 +00:00
b64dec ( self . from_pubkey )
2020-09-09 19:41:14 +00:00
) . unwrap ( self . msg )
2020-09-10 07:57:02 +00:00
# unpickle
2020-09-12 18:18:37 +00:00
self . msg = self . msg_d [ ' msg ' ] = decr_msg = pickle . loads ( decr_msg_b )
2020-09-13 11:22:35 +00:00
self . log ( ' Message decrypted: \n ' , self )
2020-09-10 07:57:02 +00:00
2020-09-09 10:41:48 +00:00
# now, is the decrypted message itself a message?
2020-09-09 21:30:14 +00:00
if is_valid_msg_d ( decr_msg ) :
2020-09-13 10:26:15 +00:00
self . log ( ' Once decrypted, I discovered that I contain an enclosed encrypted message! \n \n ' , self )
2020-09-09 10:58:00 +00:00
# then ... make that, a message object and decrypt it too!
2020-09-09 14:52:18 +00:00
self . msg = Message ( decr_msg )
2020-09-09 23:05:34 +00:00
if recursive and self . msg . is_encrypted :
2020-09-09 23:01:08 +00:00
self . msg . decrypt ( )
2020-09-09 21:30:14 +00:00
2020-09-10 08:28:03 +00:00
# self.log(f'done decrypting! {self}')
2020-09-09 10:41:48 +00:00
return decr_msg
2020-09-09 10:58:00 +00:00
2020-09-09 21:30:14 +00:00
@property
def is_encrypted ( self ) :
return type ( self . msg ) == bytes
2020-09-09 21:40:28 +00:00
# if self.msg._is_encrypted is not None:
# return self.msg._is_encrypted
2020-09-09 21:30:14 +00:00
2020-09-09 10:58:00 +00:00
2020-09-09 19:41:14 +00:00
def encrypt ( self ) : # each child message should already be encrypted before coming to its parent message ,recursive=False):
2020-09-09 21:30:14 +00:00
if self . _is_encrypted : return
2020-09-09 22:01:41 +00:00
# self.log(f'attempting to encrypt msg {self.msg} from {self.from_whom} to {self.to_whom}')
2020-09-12 21:08:53 +00:00
self . log ( f ' Before encrypting the message from @ { self . from_name } to @ { self . to_name } , it looks like: \n { self } ' )
2020-09-09 14:38:37 +00:00
2020-09-10 07:58:52 +00:00
# make sure msg is not meeta
if self . has_embedded_msg :
self . msg = self . msg . msg_d
2020-09-13 08:51:10 +00:00
# self.log('woops, first had to replace Message object with dict',self)
2020-09-10 07:58:52 +00:00
2020-09-09 19:41:14 +00:00
# binarize msg
msg_b = pickle . dumps ( self . msg )
# encrypt it!
2020-09-13 07:12:49 +00:00
# self.log('from whom keychain:',self.from_whom.keychain())
# self.log('to pubkey:',self.to_pubkey)
2020-09-09 19:41:14 +00:00
msg_encr = SMessage (
2020-09-12 21:04:44 +00:00
self . from_whom . privkey . data ,
2020-09-14 21:19:19 +00:00
b64dec ( self . to_pubkey )
2020-09-12 21:10:54 +00:00
) . wrap ( msg_b )
2020-09-09 19:41:14 +00:00
2020-09-09 14:38:37 +00:00
self . msg_decr = self . msg
2020-09-12 18:18:37 +00:00
self . msg_d [ ' msg ' ] = self . msg = b64encode ( msg_encr )
2020-09-12 18:43:50 +00:00
self . log ( f ' After encrypting the message from { self . from_whom } to { self . to_whom } , it looks like: \n { self } ' )
2020-09-12 18:18:37 +00:00
self . msg_d [ ' msg ' ] = self . msg = msg_encr
2020-09-09 21:30:14 +00:00
self . _is_encrypted = True
2020-09-09 19:41:14 +00:00
2020-09-15 07:17:12 +00:00
@property
def msg_b ( self ) :
return pickle . dumps ( self . msg_d )
2020-09-09 14:38:37 +00:00
2020-09-09 10:58:00 +00:00
## msg properties
2020-09-09 14:38:37 +00:00
@property
2020-09-09 10:58:00 +00:00
def has_embedded_msg ( self ) :
2020-09-09 14:38:37 +00:00
return type ( self . msg ) == Message
2020-09-09 10:58:00 +00:00
2020-09-15 07:17:12 +00:00
2020-09-09 10:58:00 +00:00
@property
def messages ( self ) :
# move through msgs recursively
2020-09-09 20:00:21 +00:00
def _msgs ( ) :
msg = self
while True :
yield msg
if msg . has_embedded_msg :
msg = msg . msg
break
return list ( _msgs ( ) )
2020-09-09 10:58:00 +00:00
@property
def route ( self ) :
2020-09-09 15:03:52 +00:00
if type ( self . msg ) == dict :
rte = self . msg . get ( ROUTE_KEYNAME )
if rte :
return rte
if self . has_embedded_msg :
return self . msg . route
return None
2020-09-10 11:38:59 +00:00
def delete_route ( self ) :
if type ( self . msg ) == dict :
del self . msg [ ROUTE_KEYNAME ]
2020-09-12 18:18:37 +00:00
if ROUTE_KEYNAME in self . msg_d [ ' msg ' ] :
del self . msg_d [ ' msg ' ] [ ROUTE_KEYNAME ]
2020-09-10 11:38:59 +00:00
if self . has_embedded_msg :
self . msg . delete_route ( )
2020-09-10 12:04:12 +00:00
2020-09-09 15:03:52 +00:00
2020-09-09 14:38:37 +00:00
def test_msg ( ) :
phone = TheTelephone ( )
op = TheOperator ( )
pprint ( op . pubkey )
print ( ' ?keychains? ' )
pprint ( phone . pubkey )
2020-09-09 18:31:36 +00:00
msg = { ' _route ' : ' forge_new_keys ' }
2020-09-09 14:38:37 +00:00
resp_msp_obj = phone . ring_ring ( msg )
print ( resp_msp_obj )
2020-09-09 14:50:10 +00:00
if __name__ == ' __main__ ' :
test_msg ( )