def read_volume_pubkey( volume_name, prefix=None ): # support prefix, since sometimes this can be called before storage is initialized if prefix is None: prefix = "/" pubkey_path = storage.path_join(prefix, volume_pubkey_path( volume_name )) return storage.read_file( pubkey_path, volume=None )
def stored_message_path( sender_pubkey_str, folder, message_timestamp, message_id ): # message path for messages hosted on our own Volume sh = hashlib.sha256() sh.update( sender_pubkey_str ) sh.update( str(message_timestamp) ) sh.update( message_id ) tail = sh.hexdigest() return storage.path_join( folder_dir( folder ), message_handle( message_timestamp, message_id ) + "-" + tail )
def make_gateway( pubkey_str, mail_password, syndicate_user_id, syndicate_user_signingkey_str, syndicate_user_verifyingkey_str, ms_url, volume_name, gateway_name, gateway_port, gateway_pkey_pem ): global CREATED, EXISTS if gateway_name is None: gateway_name = make_default_gateway_name() log.info("Check gateway for %s" % volume_name ) ms_url_api = os.path.join( ms_url, "api" ) # store user data in a convenient place, so we can blow it away later tmpdir, syntool_conf = setup_syntool( syndicate_user_id, ms_url_api, syndicate_user_signingkey_str, syndicate_user_verifyingkey_str, "user", syndicate_user_id ) expected_gateway_pkey_path = storage.path_join( tmpdir, Gateway.RUNTIME_KEY_TYPE, privkey_basename( gateway_name ) ) expected_gateway_signingkey_path = storage.path_join( tmpdir, Gateway.SIGNING_KEY_TYPE, privkey_basename( gateway_name ) ) # see if the gateway exists. If so, then get its key and be done with it gateway_exists = False gateway_info = None try: gateway_info = syntool.client_call( syntool_conf, "read_gateway", gateway_name ) gateway_exists = True readwrite_gateway_caps, _ = Gateway.parse_gateway_caps( "READWRITE" ) assert (gateway_info['caps'] & readwrite_gateway_caps) == readwrite_gateway_caps except Exception, e: # FIXME: use exception subclasses if is_signature_failure(e): raise Exception("Invalid private key: signature verification failure") if not gateway_exists: log.info("No gateway %s exists; will try to create one" % gateway_name) else: # assertion failed log.error("Gateway %s is not suitable for SyndicateMail") cleanup_syntool( [], tmpdir ) return False
def download_user_syndicate_pubkey(volume_name, MS_host, use_http=False): scheme = "https://" if use_http or "localhost" in MS_host: scheme = "http://" MS_pubkey_url = storage.path_join(scheme + MS_host, "VOLUMEOWNER", volume_name) user_json_str = download(MS_pubkey_url) if user_json_str is None: log.error("Download %s returned None" % MS_pubkey_url) return None try: user_json = json.loads(user_json_str) except Exception, e: log.exception(e) log.error("Bad JSON '%s'" % user_json_str) return None
def list_contacts( pubkey_str, privkey_str, start_idx=None, length=None ): global STORAGE_DIR, CACHED_CONTACT_LIST cached_contacts = storage.get_cached_data( privkey_str, CACHED_CONTACT_LIST ) if cached_contacts == None: log.info("No cached contacts") else: return cached_contacts contact_dir = storage.volume_path( STORAGE_DIR ) dir_ents = storage.listdir( contact_dir ) dir_ents.sort() if start_idx == None: start_idx = 0 if length == None: length = len(dir_ents) if start_idx + length > len(dir_ents): length = len(dir_ents) - start_idx dir_ents = dir_ents[start_idx:start_idx + length] contact_emails = [] for contact_filename in dir_ents: contact_path = storage.path_join( contact_dir, contact_filename ) contact = read_contact_from_path( privkey_str, contact_path ) if contact == None: log.warning("Failed to read contact file %s" % contact_path) continue contact_emails.append( contact.addr ) storage.cache_data( pubkey_str, CACHED_CONTACT_LIST, contact_emails ) return contact_emails
def folder_dir_atroot( folder_name ): global FOLDERS_DIR return storage.path_join( FOLDERS_DIR, folder_name )
import pickle import base64 import time import math from Crypto.Hash import SHA256 as HashAlg from Crypto.Hash import HMAC from Crypto.PublicKey import RSA as CryptoKey from Crypto.Protocol.KDF import PBKDF2 from Crypto.Signature import PKCS1_PSS as CryptoSigner from Crypto import Random log = Log.get_logger() STORAGE_DIR = "/messages" ATTACHMENTS_DIR = storage.path_join( STORAGE_DIR, "attachments" ) INCOMING_DIR = storage.path_join( STORAGE_DIR, "incoming" ) FOLDERS_DIR = storage.path_join( STORAGE_DIR, "folders" ) INBOX_FOLDER = "Inbox" SENT_FOLDER = "Sent" DRAFTS_FOLDER = "Drafts" SPAM_FOLDER = "Spam" TRASH_FOLDER = "Trash" DEFAULT_FOLDERS = [ INBOX_FOLDER, SENT_FOLDER, DRAFTS_FOLDER, SPAM_FOLDER, TRASH_FOLDER
# ------------------------------------- def download_user_mail_pubkey(addr, use_http=False): try: parsed_addr = contact.parse_addr(addr) except Exception, e: log.exception(e) log.error("Invalid email address %s" % addr) return None scheme = "https://" if use_http or "localhost" in parsed_addr.MS: scheme = "http://" server_url = storage.path_join(scheme + parsed_addr.server, "/USERKEY", addr) pubkey_str = download(server_url) return pubkey_str # ------------------------------------- def download_user_mail_pubkey_sig(addr, use_http=False): try: parsed_addr = contact.parse_addr(addr) except Exception, e: log.exception(e) log.error("Invalid email address %s" % addr) return None scheme = "https://"