예제 #1
0
파일: kex.py 프로젝트: tailsjoin/morphis
    def _parse_kexdh_init(self, m):
        # server mode
        self.e = m.e
        if (self.e < 1) or (self.e > self.P - 1):
            raise SshException('Client kex "e" is out of range')
        K = pow(self.e, self.x, self.P)
        if log.isEnabledFor(logging.DEBUG):
            log.debug("K=[{}].".format(K))
        key = self.protocol.server_key.asbytes()
        # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
        hm = bytearray()
        hm += sshtype.encodeString(self.protocol.remote_banner)
        hm += sshtype.encodeString(self.protocol.local_banner)
        hm += sshtype.encodeBinary(self.protocol.remote_kex_init_message)
        hm += sshtype.encodeBinary(self.protocol.local_kex_init_message)
        hm += sshtype.encodeBinary(key)
        hm += sshtype.encodeMpint(self.e)
        hm += sshtype.encodeMpint(self.f)
        hm += sshtype.encodeMpint(K)

        H = sha1(hm).digest()

        self.protocol.set_K_H(K, H)

        # sign it
        sig = self.protocol.server_key.sign_ssh_data(H)
        # send reply
        m = mnetpacket.SshKexdhReplyMessage()
        m.host_key = key
        m.f = self.f
        m.signature = sig
        m.encode()

        self.protocol.write_packet(m)
예제 #2
0
    def _parse_kexdh_reply(self, m):
        # The client runs this function.
        host_key = m.host_key

        server_f = self.dh.f = m.f

        if (server_f < 1) or (server_f > self.dh.P - 1):
            raise SshException('Server kex "f" is out of range')

        K = self.dh.calculate_k()

        if log.isEnabledFor(logging.DEBUG):
            log.debug("K=[{}].".format(K))

        # H = (V_C || V_S || I_C || I_S || K_S || e || f || K).
        hm = bytearray()
        hm += sshtype.encodeString(self.protocol.local_banner)
        hm += sshtype.encodeString(self.protocol.remote_banner)
        hm += sshtype.encodeBinary(self.protocol.local_kex_init_message)
        hm += sshtype.encodeBinary(self.protocol.remote_kex_init_message)
        hm += sshtype.encodeBinary(host_key)
        hm += sshtype.encodeMpint(self.dh.e)
        hm += sshtype.encodeMpint(server_f)
        hm += sshtype.encodeMpint(K)

        H = sha1(hm).digest()

        self.protocol.set_K_H(K, H)

        log.info("Verifying signature...")
        r = yield from self.protocol.verify_server_key(host_key, m.signature)
        return r
예제 #3
0
파일: kex.py 프로젝트: tailsjoin/morphis
    def _parse_kexdh_reply(self, m):
        # client mode
        host_key = m.host_key
        self.f = m.f
        if (self.f < 1) or (self.f > self.P - 1):
            raise SshException('Server kex "f" is out of range')
        sig = m.signature
        K = pow(self.f, self.x, self.P)
        if log.isEnabledFor(logging.DEBUG):
            log.debug("K=[{}].".format(K))
        # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
        hm = bytearray()
        hm += sshtype.encodeString(self.protocol.local_banner)
        hm += sshtype.encodeString(self.protocol.remote_banner)
        hm += sshtype.encodeBinary(self.protocol.local_kex_init_message)
        hm += sshtype.encodeBinary(self.protocol.remote_kex_init_message)
        hm += sshtype.encodeBinary(host_key)
        hm += sshtype.encodeMpint(self.e)
        hm += sshtype.encodeMpint(self.f)
        hm += sshtype.encodeMpint(K)

        H = sha1(hm).digest()

        self.protocol.set_K_H(K, H)

        log.info("Verifying signature...")
        r = yield from self.protocol.verify_server_key(host_key, sig)
        return r
예제 #4
0
    def _encode_key(self):
        "Encode the private components into an mnk structure."

        if (self.p is None) or (self.q is None):
            raise SshException('Not enough key info to write private key file')
        """
        keylist = [0, self.n, self.e, self.d, self.p, self.q,
                   self.d % (self.p - 1), self.d % (self.q - 1),
                   util.mod_inverse(self.q, self.p)]
        try:
            b = BER()
            b.encode(keylist)
        except BERException:
            raise SshException('Unable to create ber encoding of key')
        return b.asbytes()
        """
        b = bytearray()

        b += struct.pack("B", 1) # mnk version.
        b += sshtype.encodeMpint(self.e)
        b += sshtype.encodeMpint(self.n)
        b += sshtype.encodeMpint(self.d)
        b += sshtype.encodeMpint(self.p)
        b += sshtype.encodeMpint(self.q)

        return b
예제 #5
0
파일: dsskey.py 프로젝트: tailsjoin/morphis
 def asbytes(self):
     m = bytearray()
     m += sshtype.encodeString('ssh-dss')
     m += sshtype.encodeMpint(self.p)
     m += sshtype.encodeMpint(self.q)
     m += sshtype.encodeMpint(self.g)
     m += sshtype.encodeMpint(self.y)
     return m
예제 #6
0
 def asbytes(self):
     m = bytearray()
     m += sshtype.encodeString('ssh-dss')
     m += sshtype.encodeMpint(self.p)
     m += sshtype.encodeMpint(self.q)
     m += sshtype.encodeMpint(self.g)
     m += sshtype.encodeMpint(self.y)
     return m
예제 #7
0
    def encode(self, obuf=None):
        buf = obuf if obuf else bytearray()
        buf += struct.pack(">L", self.version)
        buf += sshtype.encodeString(self.ssm)
        buf += sshtype.encodeMpint(self.sse)
        buf += sshtype.encodeMpint(self.ssf)

        buf += struct.pack(">L", self.data_len)
        buf += self.data_enc
예제 #8
0
파일: dmail.py 프로젝트: tailsjoin/morphis
    def encode(self, obuf=None):
        buf = obuf if obuf else bytearray()
        buf += struct.pack(">L", self.version)
        buf += sshtype.encodeString(self.ssm)
        buf += sshtype.encodeMpint(self.sse)
        buf += sshtype.encodeMpint(self.ssf)

        buf += sshtype.encodeBinary(self.signature)

        buf += struct.pack(">L", self.data_len)
        buf += self.data_enc
예제 #9
0
    def asbytes(self):
        m = self.__public_key_bytes

        if m:
            return m

        m = bytearray()
        m += sshtype.encodeString('ssh-rsa')
        m += sshtype.encodeMpint(self.e)
        m += sshtype.encodeMpint(self.n)

        self.__public_key_bytes = m

        return m
예제 #10
0
    def _dmail_auto_publish(self, dmail_address):
        data_rw = yield from self.engine.tasks.send_get_data(\
            dmail_address.site_key, retry_factor=100)

        if data_rw.data:
            if log.isEnabledFor(logging.DEBUG):
                log.debug("Succeeded in fetching dmail site [{}]; won't"\
                    " auto-publish."\
                        .format(mbase32.encode(dmail_address.site_key)))
            return

        if log.isEnabledFor(logging.INFO):
            log.info("Failed to fetch dmail site [{}]; republishing."\
                .format(mbase32.encode(dmail_address.site_key)))

        private_key = rsakey.RsaKey(privdata=dmail_address.site_privatekey)

        dh = dhgroup14.DhGroup14()
        dh.x = sshtype.parseMpint(dmail_address.keys[0].x)[1]
        dh.generate_e()

        dms = dmail.DmailSite()
        root = dms.root
        root["ssm"] = "mdh-v1"
        root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))
        root["target"] =\
            mbase32.encode(dmail_address.keys[0].target_key)
        root["difficulty"] = int(dmail_address.keys[0].difficulty)

        storing_nodes =\
            yield from self._dmail_engine.publish_dmail_site(private_key, dms)

        if log.isEnabledFor(logging.INFO):
            log.info("Republished Dmail site with [{}] storing nodes."\
                .format(storing_nodes))
예제 #11
0
    def _dmail_auto_publish(self, dmail_address):
        data_rw = yield from self.engine.tasks.send_get_data(\
            dmail_address.site_key, retry_factor=100)

        if data_rw.data:
            if log.isEnabledFor(logging.DEBUG):
                log.debug("Succeeded in fetching dmail site [{}]; won't"\
                    " auto-publish."\
                        .format(mbase32.encode(dmail_address.site_key)))
            return

        if log.isEnabledFor(logging.INFO):
            log.info("Failed to fetch dmail site [{}]; republishing."\
                .format(mbase32.encode(dmail_address.site_key)))

        private_key = rsakey.RsaKey(privdata=dmail_address.site_privatekey)

        dh = dhgroup14.DhGroup14()
        dh.x = sshtype.parseMpint(dmail_address.keys[0].x)[1]
        dh.generate_e()

        dms = dmail.DmailSite()
        root = dms.root
        root["ssm"] = "mdh-v1"
        root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))
        root["target"] =\
            mbase32.encode(dmail_address.keys[0].target_key)
        root["difficulty"] = int(dmail_address.keys[0].difficulty)

        storing_nodes =\
            yield from self._dmail_engine.publish_dmail_site(private_key, dms)

        if log.isEnabledFor(logging.INFO):
            log.info("Republished Dmail site with [{}] storing nodes."\
                .format(storing_nodes))
예제 #12
0
    def encode(self):
        nbuf = super().encode()

        nbuf += sshtype.encodeBinary(self.host_key)
        nbuf += sshtype.encodeMpint(self.f)
        nbuf += sshtype.encodeBinary(self.signature)

        return nbuf
예제 #13
0
파일: packet.py 프로젝트: tailsjoin/morphis
    def encode(self):
        nbuf = super().encode()

        nbuf += sshtype.encodeBinary(self.host_key)
        nbuf += sshtype.encodeMpint(self.f)
        nbuf += sshtype.encodeBinary(self.signature)

        return nbuf
예제 #14
0
    def generate_ss(self):
        self.dh = dh = dhgroup14.DhGroup14()
        dh.generate_x()
        dh.generate_e()

        if log.isEnabledFor(logging.INFO):
            log.info("dmail e=[{}].".format(dh.e))

        self.root["ssm"] = _dh_method_name
        self.root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))
예제 #15
0
파일: dmail.py 프로젝트: tailsjoin/morphis
    def generate_ss(self):
        self.dh = dh = dhgroup14.DhGroup14()
        dh.generate_x()
        dh.generate_e()

        if log.isEnabledFor(logging.INFO):
            log.info("dmail e=[{}].".format(dh.e))

        self.root["ssm"] = _dh_method_name
        self.root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))
예제 #16
0
파일: mn1.py 프로젝트: tailsjoin/morphis
    def generateKey(self, extra, needed_bytes):
        assert isinstance(extra, bytes) and len(extra) == 1

        buf = bytearray()
        buf += sshtype.encodeMpint(self.k)
        buf += self.h
        buf += extra
        buf += self.session_id

        r = sha1(buf).digest()

        while len(r) < needed_bytes:
            buf.clear()
            buf += sshtype.encodeMpint(self.k)
            buf += self.h
            buf += r

            r += sha1(buf).digest()

        return r[:needed_bytes]
예제 #17
0
    def _parse_kexdh_init(self, m):
        # The server runs this function.
        client_e = self.dh.f = m.e

        if (client_e < 1) or (client_e > self.dh.P - 1):
            raise SshException("Client kex 'e' is out of range")

        K = self.dh.calculate_k()

        if log.isEnabledFor(logging.DEBUG):
            log.debug("K=[{}].".format(K))

        key = self.protocol.server_key.asbytes()

        # H = (V_C || V_S || I_C || I_S || K_S || e || f || K).
        hm = bytearray()
        hm += sshtype.encodeString(self.protocol.remote_banner)
        hm += sshtype.encodeString(self.protocol.local_banner)
        hm += sshtype.encodeBinary(self.protocol.remote_kex_init_message)
        hm += sshtype.encodeBinary(self.protocol.local_kex_init_message)
        hm += sshtype.encodeBinary(key)
        hm += sshtype.encodeMpint(client_e)
        hm += sshtype.encodeMpint(self.dh.e)
        hm += sshtype.encodeMpint(K)

        H = sha1(hm).digest()

        self.protocol.set_K_H(K, H)

        # Sign it.
        sig = self.protocol.server_key.sign_ssh_data(H)

        # Send reply.
        m = mnp.SshKexdhReplyMessage()
        m.host_key = key
        m.f = self.dh.e
        m.signature = sig
        m.encode()

        self.protocol.write_packet(m)
예제 #18
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.data)
        nbuf += struct.pack(">L", self.original_size)

        if self.version is not None:
            nbuf += sshtype.encodeMpint(self.version)
            nbuf += sshtype.encodeBinary(self.signature)
            if self.epubkey:
                nbuf += sshtype.encodeBinary(self.epubkey)
                nbuf += struct.pack(">L", self.pubkeylen)

        return nbuf
예제 #19
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.data)
        nbuf += struct.pack("?", self.targeted)

        if self.pubkey:
            # Updateable keys.
            nbuf += sshtype.encodeBinary(self.pubkey)
            nbuf += sshtype.encodeBinary(self.path_hash)
            nbuf += sshtype.encodeMpint(self.version)
            nbuf += sshtype.encodeBinary(self.signature)

        return nbuf
예제 #20
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.data)
        nbuf += struct.pack("?", self.targeted)

        if self.pubkey:
            # Updateable keys.
            nbuf += sshtype.encodeBinary(self.pubkey)
            nbuf += sshtype.encodeBinary(self.path_hash)
            nbuf += sshtype.encodeMpint(self.version)
            nbuf += sshtype.encodeBinary(self.signature)

        return nbuf
예제 #21
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.data)
        nbuf += struct.pack(">L", self.original_size)

        if self.version is not None:
            nbuf += sshtype.encodeMpint(self.version)
            nbuf += sshtype.encodeBinary(self.signature)
            if self.epubkey:
                nbuf += sshtype.encodeBinary(self.epubkey)
                nbuf += struct.pack(">L", self.pubkeylen)

        return nbuf
예제 #22
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.node_id)
        nbuf += struct.pack("B", self.data_mode.value)

        nbuf += struct.pack("?", self.version is not None)
        if self.version is not None:
            nbuf += sshtype.encodeMpint(self.version)

        if self.significant_bits:
            nbuf += struct.pack(">H", self.significant_bits)
            if self.target_key:
                nbuf += sshtype.encodeBinary(self.target_key)

        return nbuf
예제 #23
0
    def encode(self):
        nbuf = super().encode()
        nbuf += sshtype.encodeBinary(self.node_id)
        nbuf += struct.pack("B", self.data_mode.value)

        nbuf += struct.pack("?", self.version is not None)
        if self.version is not None:
            nbuf += sshtype.encodeMpint(self.version)

        if self.significant_bits:
            nbuf += struct.pack(">H", self.significant_bits)
            if self.target_key:
                nbuf += sshtype.encodeBinary(self.target_key)

        return nbuf
예제 #24
0
파일: dmail.py 프로젝트: fps/morphis-mirror
        def dbcall():
            with self.db.open_session() as sess:
                dmailaddress = db.DmailAddress()
                dmailaddress.site_key = data_key
                dmailaddress.site_privatekey = privkey._encode_key()

                dmailkey = db.DmailKey()
                dmailkey.x = sshtype.encodeMpint(dms.dh.x)
                dmailkey.target_key = mbase32.decode(dms.root["target"])
                dmailkey.difficulty = difficulty

                dmailaddress.keys.append(dmailkey)

                sess.add(dmailaddress)
                sess.commit()
예제 #25
0
        def dbcall():
            with self.db.open_session() as sess:
                dmailaddress = db.DmailAddress()
                dmailaddress.site_key = data_key
                dmailaddress.site_privatekey = privkey._encode_key()
                dmailaddress.scan_interval = 60

                dmailkey = db.DmailKey()
                dmailkey.x = sshtype.encodeMpint(dms.dh.x)
                dmailkey.target_key = mbase32.decode(dms.root["target"])
                dmailkey.difficulty = difficulty

                dmailaddress.keys.append(dmailkey)

                sess.add(dmailaddress)
                sess.commit()
예제 #26
0
파일: packet.py 프로젝트: tailsjoin/morphis
    def encode(self):
        nbuf = super().encode()

        nbuf += sshtype.encodeMpint(self.e)

        return nbuf
예제 #27
0
    def encode(self):
        nbuf = super().encode()

        nbuf += sshtype.encodeMpint(self.e)

        return nbuf
예제 #28
0
파일: dmail.py 프로젝트: tailsjoin/morphis
def serve_get(dispatcher, rpath):
    global top_tags

    log.info("Service .dmail request.")

    req = rpath[len(s_dmail) :]

    #    if log.isEnabledFor(logging.INFO):
    #        log.info("req=[{}].".format(req))

    if req == "" or req == "/" or req == "/goto_new_mail" or req.startswith("/wrapper/"):
        cacheable = False
        if req == "/goto_new_mail":
            tag = "Inbox"
            addr = yield from _load_first_address_with_new_mail(dispatcher)
            if addr:
                log.info("NEW")
                addr_enc = mbase32.encode(addr.site_key)
            else:
                log.info("NO NEW")
                addr_enc = ""
            qline = None
        elif req.startswith("/wrapper/"):
            params = req[9:]

            pq = params.find("?")

            if pq != -1:
                qline = params[pq + 1 :]
                params = params[:pq]
            else:
                qline = None

            p0 = params.find("/")
            if p0 == -1:
                p0 = len(params)
                tag = "Inbox"
            else:
                tag = params[p0 + 1 :]

            addr_enc = params[:p0]

            if addr_enc:
                cacheable = True
                if dispatcher.handle_cache(req):
                    return
        else:
            tag = "Inbox"
            addr_enc = ""
            qline = None

        if not addr_enc:
            dmail_address = yield from _load_default_dmail_address(dispatcher)
            if dmail_address:
                addr_enc = mbase32.encode(dmail_address.site_key)

        msg_list = None
        if qline:
            eparams = parse_qs(qline)
            msg_list = eparams.get("msg_list")
            if msg_list:
                msg_list = msg_list[0]

        if not msg_list:
            msg_list = "morphis://.dmail/msg_list/" + addr_enc + "/" + tag

        template = templates.dmail_page_wrapper[0]
        template = template.format(tag=tag, addr=addr_enc, msg_list_iframe_url=msg_list)

        if cacheable:
            dispatcher.send_content([template, req])
        else:
            dispatcher.send_content(template)
        return

    if req == "/style.css":
        dispatcher.send_content(templates.dmail_css, content_type="text/css")
    elif req == "/logo":
        template = templates.dmail_logo[0]

        current_version = dispatcher.node.morphis_version
        latest_version_number = dispatcher.latest_version_number

        if latest_version_number and current_version != latest_version_number:
            version_str = '<span class="strikethrough nomargin">{}</span>]' '&nbsp;[<a href="{}{}">GET {}</a>'.format(
                current_version,
                dispatcher.handler.maalstroom_url_prefix_str,
                "sp1nara3xhndtgswh7fznt414we4mi3y6kdwbkz4jmt8ocb6"
                "x4w1faqjotjkcrefta11swe3h53dt6oru3r13t667pr7"
                "cpe3ocxeuma/latest_version",
                latest_version_number,
            )
        else:
            version_str = current_version

        connections = dispatcher.connection_count
        if connections == 1:
            connection_str = "1 Connection"
        else:
            connection_str = str(connections) + " Connections"

        template = template.format(version=version_str, connections=connection_str)

        dispatcher.send_content(template)
    elif req.startswith("/nav/"):
        params = req[5:]

        p0 = params.index("/")

        addr_enc = params[:p0]
        tag = params[p0 + 1 :]

        template = templates.dmail_nav[0]

        template = template.format(csrf_token=dispatcher.client_engine.csrf_token, addr=addr_enc, tag=tag)

        dispatcher.send_content(template)
    elif req.startswith("/aside/"):
        params = req[7:]
        p0 = params.index("/")
        addr_enc = params[:p0]
        tag = params[p0 + 1 :]

        addr = mbase32.decode(addr_enc)

        template = templates.dmail_aside[0]

        fmt = {}

        for top_tag in top_tags:
            active = top_tag == tag
            unread_count = yield from _count_unread_dmails(dispatcher, addr, top_tag)

            fmt[top_tag + "_active"] = "active-mailbox" if active else ""
            fmt[top_tag + "_unread_count"] = unread_count if unread_count else ""
            fmt[top_tag + "_unread_class"] = ("active-notify" if active else "inactive-notify") if unread_count else ""

        tags = yield from _load_tags(dispatcher, top_tags)

        tag_rows = []

        unquoted_tag = unquote(tag)

        for tag in tags:
            if unquoted_tag == tag.name:
                active = " active_tag"
            else:
                active = ""

            row = (
                '<li class="bullet{active}"><span class="mailbox-pad">'
                '<a href="morphis://.dmail/wrapper/{addr}/{tag}">{tag}</a>'
                "</span></li>".format(active=active, addr=addr_enc, tag=tag.name)
            )
            tag_rows.append(row)

        template = template.format(
            csrf_token=dispatcher.client_engine.csrf_token, addr=addr_enc, tag=tag, tag_rows="".join(tag_rows), **fmt
        )

        acharset = dispatcher.get_accept_charset()

        dispatcher.send_content(template)
    elif req.startswith("/msg_list/list/"):
        params = req[15:]
        p0 = params.index("/")
        addr_enc = params[:p0]
        tag = unquote(params[p0 + 1 :])

        template = templates.dmail_msg_list_list_start[0]

        addr_heading = "TO" if tag in ("Outbox", "Sent", "Drafts") else "FROM"

        if tag == "Inbox" or tag == "":
            unread_check = '<meta target="self" http-equiv="refresh" content="60"/>'
        else:
            unread_check = ""

        template = template.format(unread_check=unread_check, addr_heading=addr_heading)

        acharset = dispatcher.get_accept_charset()
        dispatcher.send_partial_content(template, True, content_type="text/html; charset={}".format(acharset))

        yield from _list_dmails_for_tag(dispatcher, addr_enc, unquote(tag))

        dispatcher.send_partial_content(templates.dmail_msg_list_list_end[0])
        dispatcher.end_partial_content()
    elif req.startswith("/msg_list/"):
        params = req[10:]

        p0 = params.index("/")
        addr_enc = params[:p0]
        tag = params[p0 + 1 :]

        if dispatcher.handle_cache(req):
            return

        if tag == "Trash":
            empty_trash_button_class = "link-button"
        else:
            empty_trash_button_class = "display_none"

        template = templates.dmail_msg_list[0]
        template = template.format(
            csrf_token=dispatcher.client_engine.csrf_token,
            tag=unquote(tag),
            addr=addr_enc,
            empty_trash_button_class=empty_trash_button_class,
        )

        dispatcher.send_content([template, req])
    elif req == "/new_mail":
        template = templates.dmail_new_mail[0]

        unread_count = yield from _count_unread_dmails(dispatcher)

        template = template.format(unread_count=unread_count)

        dispatcher.send_content(template)

    elif req.startswith("/images/"):
        dispatcher.send_content(templates.imgs[req[8:]])

    elif req.startswith("/tag/view/list/"):
        params = req[15:]

        p0 = params.index("/")
        tag = params[:p0]
        addr_enc = params[p0 + 1 :]

        if log.isEnabledFor(logging.INFO):
            log.info("Viewing dmails with tag [{}] for address [{}].".format(tag, addr_enc))

        start = templates.dmail_tag_view_list_start.replace(b"${TAG_NAME}", tag.encode())
        # FIXME: This is getting inefficient now, maybe time for Flask or
        # something like it. Maybe we can use just it's template renderer.
        start = start.replace(b"${DMAIL_ADDRESS}", addr_enc.encode())
        start = start.replace(b"${DMAIL_ADDRESS2}", "{}...".format(addr_enc[:32]).encode())

        acharset = dispatcher.get_accept_charset()

        dispatcher.send_partial_content(start, True, content_type="text/html; charset={}".format(acharset))

        yield from _list_dmails_for_tag(dispatcher, mbase32.decode(addr_enc), tag)

        dispatcher.send_partial_content(templates.dmail_tag_view_list_end)
        dispatcher.end_partial_content()

    elif req.startswith("/read/content/"):
        params = req[14:]

        msg_dbid = params

        dm = yield from _load_dmail(dispatcher, msg_dbid, fetch_parts=True)

        dmail_text = _format_dmail_content(dm)

        acharset = dispatcher.get_accept_charset()

        dispatcher.send_content(dmail_text.encode(acharset), content_type="text/plain; charset={}".format(acharset))

    elif req.startswith("/read/subject/"):
        params = req[14:]

        msg_dbid = params

        dm = yield from _load_dmail(dispatcher, msg_dbid)

        acharset = dispatcher.get_accept_charset()

        dispatcher.send_content(dm.subject.encode(acharset), content_type="text/plain; charset={}".format(acharset))

    elif req.startswith("/read/"):
        params = req[6:]

        p0 = params.index("/")
        p1 = params.index("/", p0 + 1)

        addr_enc = params[:p0]
        tag = params[p0 + 1 : p1]
        msg_dbid = params[p1 + 1 :]

        def processor(sess, dm):
            dm.read = True
            return True

        dm = yield from _process_dmail_message(dispatcher, msg_dbid, processor, fetch_parts=True, fetch_tags=True)

        if dm.hidden:
            trash_msg = "REMOVE FROM TRASH"
        else:
            trash_msg = "MOVE TO TRASH"

        safe_reply_subject = generate_safe_reply_subject(dm)

        if dm.sender_dmail_key:
            sender_addr = mbase32.encode(dm.sender_dmail_key)
            if dm.sender_valid:
                sender_class = "valid_sender"
            else:
                sender_class = "invalid_sender"
        else:
            sender_addr = "[Anonymous]"
            sender_class = "valid_sender"

        if dm.destination_dmail_key:
            dest_addr_enc = mbase32.encode(dm.destination_dmail_key)
            dest_class = ""
        else:
            dest_addr_enc = ""
            dest_class = " display_none"

        unquoted_tag = unquote(tag)

        existing_tag_rows = []
        if len(dm.tags) > 1:
            remove_tag_class = ""

            for etag in dm.tags:
                if etag.name == unquoted_tag:
                    selected = "selected "
                else:
                    selected = ""

                row = '<option {selected}value"{tag_id}">{tag_name}</option>'.format(
                    selected=selected, tag_id=etag.id, tag_name=etag.name
                )
                existing_tag_rows.append(row)
        else:
            remove_tag_class = "display_none"

        current_tag_names = [x.name for x in dm.tags]
        current_tag_names.extend(top_tags)
        current_tag_names.remove("Inbox")
        tags = yield from _load_tags(dispatcher, current_tag_names)

        available_tag_rows = []

        for atag in tags:
            row = '<option value"{tag_id}">{tag_name}</option>'.format(tag_id=atag.id, tag_name=atag.name)
            available_tag_rows.append(row)

        template = templates.dmail_read[0]
        template = template.format(
            csrf_token=dispatcher.client_engine.csrf_token,
            addr=addr_enc,
            tag=tag,
            safe_reply_subject=safe_reply_subject,
            trash_msg=trash_msg,
            msg_id=msg_dbid,
            sender_class=sender_class,
            sender=sender_addr,
            dest_class=dest_class,
            dest_addr=dest_addr_enc,
            date=mutil.format_human_no_ms_datetime(dm.date),
            remove_tag_class=remove_tag_class,
            existing_tags="".join(existing_tag_rows),
            available_tags="".join(available_tag_rows),
        )

        dispatcher.send_content(template)
    elif req.startswith("/compose/"):
        if len(req) > 8 and req[8] == "/":
            params = req[9:]
        else:
            params = req[8:]

        p0 = params.find("?")
        if p0 != -1:
            eparams = parse_qs(params[p0 + 1 :])

            subject = eparams.get("subject")
            if subject:
                subject = subject[0].replace('"', "&quot;")
            else:
                subject = ""

            sender_addr_enc = eparams.get("sender")
            if sender_addr_enc:
                sender_addr_enc = sender_addr_enc[0]
            else:
                sender_addr_enc = ""

            message_text = eparams.get("message")
            if message_text:
                message_text = message_text[0]
            else:
                message_text = ""
        else:
            subject = ""
            sender_addr_enc = ""
            message_text = ""
            p0 = len(params)

        dest_addr_enc = params[:p0]

        autofocus_fields = {"dest_addr_autofocus": "", "subject_autofocus": "", "message_text_autofocus": ""}
        if not dest_addr_enc:
            autofocus_fields["dest_addr_autofocus"] = " autofocus"
        elif not subject:
            autofocus_fields["subject_autofocus"] = " autofocus"
        elif not message_text:
            autofocus_fields["message_text_autofocus"] = " autofocus"

        addrs = yield from _list_dmail_addresses(dispatcher)

        if sender_addr_enc:
            sender_addr = mbase32.decode(sender_addr_enc)
            default_id = None
        else:
            sender_addr = None
            default_id = yield from _load_default_dmail_address_id(dispatcher)
            if not default_id:
                owner_if_anon_id = ""

        from_addr_options = []

        for addr in addrs:
            if sender_addr:
                selected = addr.site_key.startswith(sender_addr)
            elif default_id:
                selected = addr.id == default_id
            else:
                selected = False

            if selected:
                option = '<option value="{}" selected>{}</option>'
                owner_if_anon_id = addr.id
            else:
                option = '<option value="{}">{}</option>'

            addr_enc = mbase32.encode(addr.site_key)

            from_addr_options.append(option.format(addr.id, addr_enc))

        from_addr_options.append("<option value=" ">[Anonymous]</option>")

        from_addr_options = "".join(from_addr_options)

        template = templates.dmail_compose[0]

        template = template.format(
            csrf_token=dispatcher.client_engine.csrf_token,
            delete_class="display_none",
            owner_if_anon=owner_if_anon_id,
            from_addr_options=from_addr_options,
            dest_addr=dest_addr_enc,
            subject=subject,
            message_text=message_text,
            **autofocus_fields
        )

        acharset = dispatcher.get_accept_charset()
        dispatcher.send_content(template, content_type="text/html; charset={}".format(acharset))
    elif req == "/address_list":
        addrs = yield from _list_dmail_addresses(dispatcher)
        default_id = yield from _load_default_dmail_address_id(dispatcher)

        csrf_token = dispatcher.client_engine.csrf_token

        row_template = templates.dmail_address_list_row[0]

        rows = []

        for addr in addrs:
            site_key_enc = mbase32.encode(addr.site_key)

            if default_id and addr.id == default_id:
                set_default_class = "hidden"
            else:
                set_default_class = ""

            if addr.scan_interval:
                autoscan_link_text = "disable autoscan"
                autoscan_interval = 0
            else:
                autoscan_link_text = "enable autoscan"
                autoscan_interval = 60

            resp = row_template.format(
                csrf_token=csrf_token,
                addr=site_key_enc,
                addr_dbid=addr.id,
                set_default_class=set_default_class,
                autoscan_link_text=autoscan_link_text,
                autoscan_interval=autoscan_interval,
            )

            rows.append(resp)

        rows_content = "".join(rows)

        template = templates.dmail_address_list[0]
        template = template.format(address_list=rows_content)

        dispatcher.send_content(template)

    # Actions.

    elif req.startswith("/create_tag?"):
        query = req[12:]

        qdict = parse_qs(query, keep_blank_values=True)

        csrf_token = qdict["csrf_token"][0]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        tag_name = qdict["tag_name"][0]

        if not tag_name:
            dispatcher.send_204()
            return

        r = yield from _create_tag(dispatcher, tag_name)

        redirect = qdict.get("redirect")
        if r and redirect:
            dispatcher.send_301(redirect[0])
        else:
            dispatcher.send_204()
    elif req.startswith("/modify_message_tag?"):
        query = req[20:]

        qdict = parse_qs(query, keep_blank_values=True)

        csrf_token = qdict["csrf_token"][0]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        submit = qdict["submit"][0]

        def processor(sess, dm):
            if submit == "add_tag":
                dmail.attach_dmail_tag(sess, dm, qdict["add_tag"][0])
                return True
            elif submit == "move_to_tag":
                dm.tags.clear()
                dmail.attach_dmail_tag(sess, dm, qdict["add_tag"][0])
                return True
            elif submit == "remove_tag":
                if len(dm.tags) <= 1:
                    return False

                remove_tag = qdict["remove_tag"][0]
                remove_target = None
                for tag in dm.tags:
                    if tag.name == remove_tag:
                        remove_target = tag
                        break
                dm.tags.remove(remove_target)
                return True
            else:
                return False

        msg_id = qdict["msg_id"][0]

        dm = yield from _process_dmail_message(dispatcher, msg_id, processor, fetch_tags=True)

        redirect = qdict.get("redirect")
        if redirect:
            dispatcher.send_301(redirect[0])
        else:
            dispatcher.send_204()
    elif req.startswith("/refresh/"):
        params = req[9:]

        p0 = params.index("/")

        csrf_token = params[:p0]
        addr_enc = params[p0 + 1 :]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        dmail_address = yield from _load_dmail_address(dispatcher, site_key=mbase32.decode(addr_enc), fetch_keys=True)

        dispatcher.client_engine.trigger_dmail_scan(dmail_address)

        dispatcher.send_204()
    elif req.startswith("/toggle_read/"):
        params = req[13:]

        pq = params.find("?redirect=")
        if pq != -1:
            redirect = params[pq + 10 :]
        else:
            redirect = None
            pq = len(params)

        p0 = params.index("/", 0, pq)

        csrf_token = params[:p0]
        msg_dbid = params[p0 + 1 : pq]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        def processor(sess, dm):
            dm.read = not dm.read
            return True

        yield from _process_dmail_message(dispatcher, msg_dbid, processor)

        if redirect:
            dispatcher.send_301(redirect)
        else:
            dispatcher.send_204()
    elif req.startswith("/toggle_trashed/"):
        params = req[16:]
        pq = params.find("?redirect=")
        if pq != -1:
            redirect = params[pq + 10 :]
        else:
            redirect = None
            pq = len(params)

        p0 = params.index("/", 0, pq)

        csrf_token = params[:p0]
        msg_dbid = params[p0 + 1 : pq]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        def processor(sess, dm):
            dm.hidden = not dm.hidden
            return True

        yield from _process_dmail_message(dispatcher, msg_dbid, processor)

        if redirect:
            dispatcher.send_301(redirect)
        else:
            dispatcher.send_204()
    elif req.startswith("/set_autoscan/"):
        params = req[14:]

        pq = params.find("?redirect=")
        if pq != -1:
            redirect = params[pq + 10 :]
        else:
            redirect = None
            pq = len(params)

        p0 = params.index("/", 0, pq)
        p1 = params.index("/", p0 + 1, pq)

        csrf_token = params[:p0]
        addr_id = int(params[p0 + 1 : p1])
        interval = int(params[p1 + 1 : pq])

        if not dispatcher.check_csrf_token(csrf_token):
            return

        def processor(sess, addr):
            addr.scan_interval = interval
            return True

        addr = yield from _process_dmail_address(dispatcher, processor, addr_id, fetch_keys=True)

        dispatcher.client_engine.update_dmail_autoscan(addr)

        if redirect:
            dispatcher.send_301(redirect)
        else:
            dispatcher.send_204()
    elif req.startswith("/empty_trash/"):
        params = req[13:]

        pq = params.find("?redirect=")
        if pq != -1:
            redirect = params[pq + 10 :]
        else:
            redirect = None
            pq = len(params)

        p0 = params.index("/", 0, pq)

        csrf_token = params[:p0]
        addr_enc = params[p0 + 1 : pq]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        yield from _empty_trash(dispatcher, addr_enc)

        if redirect:
            dispatcher.send_301(redirect)
        else:
            dispatcher.send_204()
    elif req.startswith("/make_address_default/"):
        params = req[22:]

        pq = params.find("?redirect=")
        if pq != -1:
            redirect = params[pq + 10 :]
        else:
            redirect = None
            pq = len(params)

        p0 = params.index("/")

        csrf_token = params[:p0]
        addr_dbid = params[p0 + 1 : pq]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        yield from _set_default_dmail_address(dispatcher, addr_dbid)

        if redirect:
            dispatcher.send_301(redirect)
        else:
            dispatcher.send_204()

    ##### OLD:

    elif req == "/create_address":
        if dispatcher.handle_cache(req):
            return

        template = templates.dmail_create_address[0]

        template = template.format(csrf_token=dispatcher.client_engine.csrf_token)

        dispatcher.send_content([template, req])
    elif req.startswith("/address_config/"):
        params = req[16:]

        addr_enc = params

        dmail_address = yield from _load_dmail_address(dispatcher, site_key=mbase32.decode(addr_enc), fetch_keys=True)

        content = templates.dmail_address_config[0]

        content = content.replace("{csrf_token}", dispatcher.client_engine.csrf_token)
        content = content.replace("${DIFFICULTY}", str(dmail_address.keys[0].difficulty))
        content = content.replace("${DMAIL_ADDRESS_SHORT}", addr_enc[:32])
        content = content.replace("${DMAIL_ADDRESS}", addr_enc)
        content = content.replace("${PRIVATE_KEY}", base58.encode(dmail_address.site_privatekey))
        content = content.replace("${X}", base58.encode(dmail_address.keys[0].x))
        content = content.replace("${TARGET_KEY}", base58.encode(dmail_address.keys[0].target_key))

        dispatcher.send_content([content, None])
    ##### OLD ACTIONS:
    elif req.startswith("/create_address/make_it_so?"):
        query = req[27:]

        qdict = parse_qs(query, keep_blank_values=True)

        prefix = qdict["prefix"][0]
        difficulty = int(qdict["difficulty"][0])
        csrf_token = qdict["csrf_token"][0]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        log.info("prefix=[{}].".format(prefix))
        privkey, dmail_key, dms, storing_nodes = yield from _create_dmail_address(dispatcher, prefix, difficulty)

        dmail_key_enc = mbase32.encode(dmail_key)

        dispatcher.send_partial_content(templates.dmail_frame_start, True)
        if storing_nodes:
            dispatcher.send_partial_content(b"SUCCESS<br/>")
        else:
            dispatcher.send_partial_content(
                "PARTIAL SUCCESS<br/>"
                "<p>Your Dmail site was generated successfully; however,"
                " it failed to be stored on the network. To remedy this,"
                " simply go to your Dmail address page and click the"
                ' [<a target="_self" href="morphis://.dmail/'
                'address_config/{}">Address Settings</a>] link, and then'
                ' click the "Republish Dmail Site" button.</p>'.format(dmail_key_enc).encode()
            )

        dispatcher.send_partial_content(
            '<p>New dmail address: <a href="morphis://.dmail/wrapper/'
            '{addr_enc}">{addr_enc}</a></p>'.format(addr_enc=dmail_key_enc).encode()
        )
        dispatcher.send_partial_content(templates.dmail_frame_end)
        dispatcher.end_partial_content()
    elif req.startswith("/save_address_config/publish?"):
        query = req[29:]

        qdict = parse_qs(query, keep_blank_values=True)

        addr_enc = qdict["dmail_address"][0]
        difficulty = qdict["difficulty"][0]
        csrf_token = qdict["csrf_token"][0]

        if not dispatcher.check_csrf_token(csrf_token):
            return

        def processor(sess, dmail_address):
            if difficulty != dmail_address.keys[0].difficulty:
                dmail_address.keys[0].difficulty = difficulty
                return True
            else:
                return False

        dmail_address = yield from _process_dmail_address(
            dispatcher, processor, site_key=mbase32.decode(addr_enc), fetch_keys=True
        )

        dh = dhgroup14.DhGroup14()
        dh.x = sshtype.parseMpint(dmail_address.keys[0].x)[1]
        dh.generate_e()

        dms = dmail.DmailSite()
        root = dms.root
        root["ssm"] = "mdh-v1"
        root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))
        root["target"] = mbase32.encode(dmail_address.keys[0].target_key)
        root["difficulty"] = int(difficulty)

        private_key = rsakey.RsaKey(privdata=dmail_address.site_privatekey)

        de = dmail.DmailEngine(dispatcher.node.chord_engine.tasks, dispatcher.node.db)

        storing_nodes = yield from de.publish_dmail_site(private_key, dms)

        if storing_nodes:
            dispatcher.send_content(
                templates.dmail_addr_settings_edit_success_content[0].format(addr_enc, addr_enc[:32]).encode()
            )
        else:
            dispatcher.send_content(
                templates.dmail_addr_settings_edit_fail_content[0].format(addr_enc, addr_enc[:32]).encode()
            )
    else:
        dispatcher.send_error(errcode=400)
예제 #29
0
파일: dmail.py 프로젝트: tailsjoin/morphis
 def _generate_encryption_key(self, target_key, k):
     return enc.generate_ID(\
         b"The life forms running github are more retarded than any retard!"\
         + target_key + sshtype.encodeMpint(k)\
         + b"https://github.com/nixxquality/WebMConverter/commit/"\
         + b"c1ac0baac06fa7175677a4a1bf65860a84708d67")
예제 #30
0
 def _generate_encryption_key(self, target_key, k):
     return enc.generate_ID(\
         b"The life forms running github are more retarded than any"\
         + b" retard!" + target_key + sshtype.encodeMpint(k)\
         + b"https://github.com/nixxquality/WebMConverter/commit/"\
         + b"c1ac0baac06fa7175677a4a1bf65860a84708d67")
예제 #31
0
파일: dmail.py 프로젝트: fps/morphis-mirror
def __serve_get(handler, rpath, done_event):
    if len(rpath) == len(s_dmail):
        handler._send_content(pages.dmail_page_content)
    else:
        req = rpath[len(s_dmail):]
        log.info("req=[{}].".format(req))
        if req == "/css":
            handler._send_content(\
                pages.dmail_css_content, content_type="text/css")
        elif req == "/address_list":
            handler._send_partial_content(
                pages.dmail_page_content__f1_start, True)

            site_keys = yield from _list_dmail_addresses(handler)

            for dbid, site_key in site_keys:
                site_key_enc = mbase32.encode(site_key)

                resp = """<span class="nowrap">[<a href="addr/{}">view</a>]"""\
                    """ {}</span><br/>"""\
                        .format(site_key_enc, site_key_enc)

                handler._send_partial_content(resp)

            handler._send_partial_content(pages.dmail_page_content__f1_end)
            handler._end_partial_content()
        elif req.startswith("/compose/form"):
            dest_addr_enc = req[14:] if len(req) > 14 else ""

            handler._send_partial_content(\
                pages.dmail_compose_dmail_form_start, True)

            site_keys = yield from _list_dmail_addresses(handler)

            for dbid, site_key in site_keys:
                site_key_enc = mbase32.encode(site_key)

                sender_element = """<option value="{}">{}</option>"""\
                    .format(dbid, site_key_enc)

                handler._send_partial_content(sender_element)

            handler._send_partial_content(\
                "<option value="">[Anonymous]</option>")

            handler._send_partial_content(\
                pages.dmail_compose_dmail_form_end.replace(\
                    b"${DEST_ADDR}", dest_addr_enc.encode()))

            handler._end_partial_content()
        elif req.startswith("/compose"):
            from_addr = req[9:] if len(req) > 9 else ""

            if from_addr:
                iframe_src = "../compose/form/{}".format(from_addr).encode()
            else:
                iframe_src = "compose/form".encode()

            content = pages.dmail_compose_dmail_content[0].replace(\
                    b"${IFRAME_SRC}", iframe_src)

            handler._send_content([content, None])
        elif req.startswith("/addr/view/"):
            addr_enc = req[11:]

            start = pages.dmail_addr_view_start.replace(\
                b"${DMAIL_ADDRESS}", addr_enc.encode())
            start = start.replace(\
                b"${DMAIL_ADDRESS_SHORT}", addr_enc[:32].encode())

            handler._send_partial_content(start, True)

            handler._send_partial_content(pages.dmail_addr_view_end)
            handler._end_partial_content()
        elif req.startswith("/addr/settings/edit/publish?"):
            query = req[28:]

            qdict = urllib.parse.parse_qs(query, keep_blank_values=True)

            addr_enc = qdict["dmail_address"][0]
            difficulty = qdict["difficulty"][0]

            def processor(dmail_address):
                if difficulty != dmail_address.keys[0].difficulty:
                    dmail_address.keys[0].difficulty = difficulty
                    return True
                else:
                    return False

            dmail_address = yield from\
                _process_dmail_address(\
                    handler, mbase32.decode(addr_enc), processor)

            dh = dhgroup14.DhGroup14()
            dh.x = sshtype.parseMpint(dmail_address.keys[0].x)[1]
            dh.generate_e()

            dms = dmail.DmailSite()
            root = dms.root
            root["target"] =\
                mbase32.encode(dmail_address.keys[0].target_key)
            root["difficulty"] = int(difficulty)
            root["ssm"] = "mdh-v1"
            root["sse"] = base58.encode(sshtype.encodeMpint(dh.e))

            private_key = rsakey.RsaKey(privdata=dmail_address.site_privatekey)

            r = yield from\
                handler.node.chord_engine.tasks.send_store_updateable_key(\
                    dms.export(), private_key,\
                    version=int(time.time()*1000), store_key=True)

            handler._send_content(\
                pages.dmail_addr_settings_edit_success_content[0]\
                    .format(addr_enc, addr_enc[:32]).encode())
        elif req.startswith("/addr/settings/edit/"):
            addr_enc = req[20:]

            dmail_address = yield from\
                _load_dmail_address(handler, mbase32.decode(addr_enc))

            content = pages.dmail_addr_settings_edit_content[0].replace(\
                b"${DIFFICULTY}",\
                str(dmail_address.keys[0].difficulty).encode())
            content = content.replace(\
                b"${DMAIL_ADDRESS_SHORT}", addr_enc[:32].encode())
            content = content.replace(\
                b"${DMAIL_ADDRESS}", addr_enc.encode())
            content = content.replace(\
                b"${PRIVATE_KEY}",\
                base58.encode(dmail_address.site_privatekey).encode())
            content = content.replace(\
                b"${X}", base58.encode(dmail_address.keys[0].x).encode())
            content = content.replace(\
                b"${TARGET_KEY}",\
                base58.encode(dmail_address.keys[0].target_key).encode())

            handler._send_content([content, None])
        elif req.startswith("/addr/settings/"):
            addr_enc = req[15:]

            content = pages.dmail_addr_settings_content[0].replace(\
                b"${IFRAME_SRC}",\
                "edit/{}".format(addr_enc).encode())

            handler._send_content([content, None])
        elif req.startswith("/addr/"):
            addr_enc = req[6:]

            if log.isEnabledFor(logging.INFO):
                log.info("Viewing dmail address [{}].".format(addr_enc))

            content = pages.dmail_address_page_content[0].replace(\
                b"${IFRAME_SRC}", "view/{}".format(addr_enc).encode())

            handler._send_content([content, None])
        elif req.startswith("/tag/view/list/"):
            params = req[15:]

            p0 = params.index('/')
            tag = params[:p0]
            addr_enc = params[p0+1:]

            if log.isEnabledFor(logging.INFO):
                log.info("Viewing dmails with tag [{}] for address [{}]."\
                    .format(tag, addr_enc))

            start = pages.dmail_tag_view_list_start.replace(\
                b"${TAG_NAME}", tag.encode())
            #FIXME: This is getting inefficient now, maybe time for Flask or
            # something like it. Maybe we can use just it's template renderer.
            start = start.replace(b"${DMAIL_ADDRESS}", addr_enc.encode())
            start = start.replace(\
                b"${DMAIL_ADDRESS2}",\
                "{}...".format(addr_enc[:32]).encode())

            handler._send_partial_content(start, True)

            yield from\
                _list_dmails_for_tag(handler, mbase32.decode(addr_enc), tag)

            handler._send_partial_content(pages.dmail_tag_view_list_end)
            handler._end_partial_content()

        elif req.startswith("/tag/view/"):
            params = req[10:]

            content = pages.dmail_tag_view_content[0].replace(\
                b"${IFRAME_SRC}", "../list/{}".format(params).encode())

            handler._send_content(content)
        elif req.startswith("/scan/list/"):
            addr_enc = req[11:]

            if log.isEnabledFor(logging.INFO):
                log.info("Viewing inbox for dmail address [{}]."\
                    .format(addr_enc))

            start = pages.dmail_inbox_start.replace(\
                b"${DMAIL_ADDRESS}", addr_enc.encode())
            start = start.replace(\
                b"${DMAIL_ADDRESS2}", "{}...".format(addr_enc[:32]).encode())

            handler._send_partial_content(start, True)

            addr, significant_bits = mutil.decode_key(addr_enc)

            yield from _scan_new_dmails(handler, addr, significant_bits)

            handler._send_partial_content(pages.dmail_inbox_end)
            handler._end_partial_content()
        elif req.startswith("/scan/"):
            addr_enc = req[6:]

            content = pages.dmail_address_page_content[0].replace(\
                b"${IFRAME_SRC}", "list/{}".format(addr_enc).encode())

            handler._send_content([content, None])
        elif req.startswith("/fetch/view/"):
            keys = req[12:]
            p0 = keys.index('/')
            dmail_addr_enc = keys[:p0]
            dmail_key_enc = keys[p0+1:]

            dmail_addr = mbase32.decode(dmail_addr_enc)
            dmail_key = mbase32.decode(dmail_key_enc)

            dm = yield from _load_dmail(handler, dmail_key)

            if dm:
                valid_sig = dm.sender_valid
            else:
                dm, valid_sig =\
                    yield from _fetch_dmail(handler, dmail_addr, dmail_key)

            dmail_text = _format_dmail(dm, valid_sig)

            handler._send_content(\
                dmail_text.encode(), content_type="text/plain")
        elif req.startswith("/fetch/panel/mark_as_read/"):
            req_data = req[26:]

            p0 = req_data.index('/')
            dmail_key_enc = req_data[p0+1:]
            dmail_key = mbase32.decode(dmail_key_enc)

            def processor(dmail):
                dmail.read = not dmail.read
                return True

            yield from _process_dmail_message(handler, dmail_key, processor)

            handler._send_204()
        elif req.startswith("/fetch/panel/trash/"):
            req_data = req[20:]

            p0 = req_data.index('/')
            dmail_key_enc = req_data[p0+1:]
            dmail_key = mbase32.decode(dmail_key_enc)

            def processor(dmail):
                dmail.hidden = not dmail.hidden
                return True

            yield from _process_dmail_message(handler, dmail_key, processor)

            handler._send_204()
        elif req.startswith("/fetch/panel/"):
            req_data = req[13:]

            content = pages.dmail_fetch_panel_content[0].replace(\
                b"${DMAIL_IDS}", req_data.encode())

            handler._send_content([content, None])
        elif req.startswith("/fetch/wrapper/"):
            req_data = req[15:]

            content = pages.dmail_fetch_wrapper[0].replace(\
                b"${IFRAME_SRC}",\
                "../../view/{}"\
                    .format(req_data).encode())
            #FIXME: This is getting inefficient now, maybe time for Flask or
            # something like it. Maybe we can use just it's template renderer.
            content = content.replace(\
                b"${IFRAME2_SRC}",\
                "../../panel/{}"\
                    .format(req_data).encode())

            handler._send_content([content, None])
        elif req.startswith("/fetch/"):
            req_data = req[7:]

            content = pages.dmail_address_page_content[0].replace(\
                b"${IFRAME_SRC}", "../wrapper/{}".format(req_data).encode())

            handler._send_content([content, None])
        elif req == "/create_address":
            handler._send_content(pages.dmail_create_address_content)
        elif req == "/create_address/form":
            handler._send_content(pages.dmail_create_address_form_content)
        elif req.startswith("/create_address/make_it_so?"):
            query = req[27:]

            qdict = urllib.parse.parse_qs(query, keep_blank_values=True)

            prefix = qdict["prefix"][0]
            difficulty = int(qdict["difficulty"][0])

            log.info("prefix=[{}].".format(prefix))
            privkey, dmail_key, dms =\
                yield from _create_dmail_address(handler, prefix, difficulty)

            dmail_key_enc = mbase32.encode(dmail_key)

            handler._send_partial_content(pages.dmail_frame_start, True)
            handler._send_partial_content(b"SUCCESS<br/>")
            handler._send_partial_content(\
                """<p>New dmail address: <a href="../addr/{}">{}</a></p>"""\
                    .format(dmail_key_enc, dmail_key_enc).encode())
            handler._send_partial_content(pages.dmail_frame_end)
            handler._end_partial_content()
        else:
            handler._handle_error()
예제 #32
0
 def asbytes(self):
     m = bytearray()
     m += sshtype.encodeString("ssh-rsa")
     m += sshtype.encodeMpint(self.e)
     m += sshtype.encodeMpint(self.n)
     return m
예제 #33
0
파일: mcc.py 프로젝트: fps/morphis-mirror
def __main():
    global loop

    log.info("mcc running.")

    parser = argparse.ArgumentParser()
    parser.add_argument(\
        "--address",\
        help="The address of the Morphis node to connect to.",\
        default="127.0.0.1:4250")
    parser.add_argument(\
        "--create-dmail",\
        help="Generate and upload a new dmail site.",\
        action="store_true")
    parser.add_argument(\
        "--dburl",\
        help="Specify the database url to use.")
    parser.add_argument(\
        "--fetch-dmail",
        help="Fetch dmail for specified key_id.")
    parser.add_argument(\
        "-i",\
        help="Read file as stdin.")
    parser.add_argument("--nn", type=int,\
        help="Node instance number.")
    parser.add_argument(\
        "--prefix",\
        help="Specify the prefix for various things (currently --create-dmail"\
            ").")
    parser.add_argument(\
        "--scan-dmail",\
        help="Scan the network for available dmails.")
    parser.add_argument(\
        "--send-dmail",\
        help="Send stdin as a dmail with the specified subject. The"\
            " sender and recipients may be specified at the beginning of the"\
            " data as with email headers: 'from: ' and 'to: '.")
    parser.add_argument(\
        "--stat",\
        help="Report node status.",\
        action="store_true")
    parser.add_argument("-l", dest="logconf",\
        help="Specify alternate logging.ini [IF SPECIFIED, THIS MUST BE THE"\
            " FIRST PARAMETER!].")
    parser.add_argument(\
        "--dmail-target",\
        help="Specify the dmail target to validate dmail against.")
    parser.add_argument(\
        "-x",\
        help="Specify the x (Diffie-Hellman private secret) to use.")

    args = parser.parse_args()

    # Load or generate client mcc key.
    key_filename = "data/mcc_key-rsa.mnk"
    if os.path.exists(key_filename):
        log.info("mcc private key file found, loading.")
        client_key = rsakey.RsaKey(filename=key_filename)
    else:
        log.info("mcc private key file missing, generating.")
        client_key = rsakey.RsaKey.generate(bits=4096)
        client_key.write_private_key_file(key_filename)

    # Connect a Morphis Client (lightweight Node) instance.
    mc = client.Client(loop, client_key=client_key, address=args.address)
    r = yield from mc.connect()

    if not r:
        log.warning("Connection failed; exiting.")
        loop.stop()
        return

    dbase = init_db(args)
    de = dmail.DmailEngine(mc, dbase)

    log.info("Processing command requests...")

    if args.stat:
        r = yield from mc.send_command("stat")
        print(r.decode("UTF-8"), end='')

    if args.create_dmail:
        log.info("Creating and uploading dmail site.")

        privkey, data_key, dms =\
            yield from de.generate_dmail_address(args.prefix)

        print("privkey: {}".format(base58.encode(privkey._encode_key())))
        print("x: {}".format(base58.encode(sshtype.encodeMpint(dms.dh.x))))
        print("dmail address: {}".format(mbase32.encode(data_key)))

    if args.send_dmail:
        log.info("Sending dmail.")

        if args.i:
            with open(args.i, "rb") as fh:
                dmail_data = fh.read().decode()
        else:
            dmail_data = stdin.read()

        if log.isEnabledFor(logging.DEBUG):
            log.debug("dmail_data=[{}].".format(dmail_data))

        yield from de.send_dmail_text(args.send_dmail, dmail_data)

    if args.scan_dmail:
        log.info("Scanning dmail address.")

        addr, sig_bits = mutil.decode_key(args.scan_dmail)

        def key_callback(key):
            print("dmail key: [{}].".format(mbase32.encode(key)))

        yield from de.scan_dmail_address(\
            addr, sig_bits, key_callback=key_callback)

    if args.fetch_dmail:
        log.info("Fetching dmail for key=[{}].".format(args.fetch_dmail))

        key = mbase32.decode(args.fetch_dmail)

        if args.x:
            l, x_int = sshtype.parseMpint(base58.decode(args.x))
        else:
            x_int = None

        dmail_target = args.dmail_target

        dm, valid_sig = yield from de.fetch_dmail(key, x_int, dmail_target)

        if not dm:
            raise Exception("No dmail found.")

        if not x_int:
            print("Encrypted dmail data=[\n{}].".format(mutil.hex_dump(dm)))
        else:
            print("Subject: {}\n".format(dm.subject))

            if dm.sender_pubkey:
                print("From: {}"\
                    .format(mbase32.encode(enc.generate_ID(dm.sender_pubkey))))

            i = 0
            for part in dm.parts:
                print("DmailPart[{}]:\n    mime-type=[{}]\n    data=[{}]\n"\
                    .format(i, part.mime_type, part.data))
                i += 1

    log.info("Disconnecting.")

    yield from mc.disconnect()

    loop.stop()
예제 #34
0
def __main():
    global loop

    log.info("mcc running.")

    parser = argparse.ArgumentParser()
    parser.add_argument(\
        "--address",\
        help="The address of the Morphis node to connect to.",\
        default="127.0.0.1:4250")
    parser.add_argument(\
        "--create-dmail",\
        help="Generate and upload a new dmail site.",\
        action="store_true")
    parser.add_argument(\
        "--dburl",\
        help="Specify the database url to use.")
    parser.add_argument(\
        "--fetch-dmail",
        help="Fetch dmail for specified key_id.")
    parser.add_argument(\
        "-i",\
        help="Read file as stdin.")
    parser.add_argument("--nn", type=int,\
        help="Node instance number.")
    parser.add_argument(\
        "--prefix",\
        help="Specify the prefix for various things (currently --create-dmail"\
            ").")
    parser.add_argument(\
        "--scan-dmail",\
        help="Scan the network for available dmails.")
    parser.add_argument(\
        "--send-dmail",\
        help="Send stdin as a dmail with the specified subject. The"\
            " sender and recipients may be specified at the beginning of the"\
            " data as with email headers: 'from: ' and 'to: '.")
    parser.add_argument(\
        "--stat",\
        help="Report node status.",\
        action="store_true")
    parser.add_argument("-l", dest="logconf",\
        help="Specify alternate logging.ini [IF SPECIFIED, THIS MUST BE THE"\
            " FIRST PARAMETER!].")
    parser.add_argument(\
        "--dmail-target",\
        help="Specify the dmail target to validate dmail against.")
    parser.add_argument(\
        "-x",\
        help="Specify the x (Diffie-Hellman private secret) to use.")

    args = parser.parse_args()

    # Load or generate client mcc key.
    key_filename = "data/mcc_key-rsa.mnk"
    if os.path.exists(key_filename):
        log.info("mcc private key file found, loading.")
        client_key = rsakey.RsaKey(filename=key_filename)
    else:
        log.info("mcc private key file missing, generating.")
        client_key = rsakey.RsaKey.generate(bits=4096)
        client_key.write_private_key_file(key_filename)

    # Connect a Morphis Client (lightweight Node) instance.
    mc = client.Client(loop, client_key=client_key, address=args.address)
    r = yield from mc.connect()

    if not r:
        log.warning("Connection failed; exiting.")
        loop.stop()
        return

    dbase = init_db(args)
    de = dmail.DmailEngine(mc, dbase)

    log.info("Processing command requests...")

    if args.stat:
        r = yield from mc.send_command("stat")
        print(r.decode("UTF-8"), end='')

    if args.create_dmail:
        log.info("Creating and uploading dmail site.")

        privkey, data_key, dms, storing_nodes =\
            yield from de.generate_dmail_address(args.prefix)

        print("privkey: {}".format(base58.encode(privkey._encode_key())))
        print("x: {}".format(base58.encode(sshtype.encodeMpint(dms.dh.x))))
        print("dmail address: {}".format(mbase32.encode(data_key)))
        print("storing_nodes=[{}]."\
            .format(base58.encode(privkey._encode_key())))

    if args.send_dmail:
        log.info("Sending dmail.")

        if args.i:
            with open(args.i, "rb") as fh:
                dmail_data = fh.read().decode()
        else:
            dmail_data = stdin.read()

        if log.isEnabledFor(logging.DEBUG):
            log.debug("dmail_data=[{}].".format(dmail_data))

        yield from de.send_dmail_text(args.send_dmail, dmail_data)

    if args.scan_dmail:
        log.info("Scanning dmail address.")

        addr, sig_bits = mutil.decode_key(args.scan_dmail)

        def key_callback(key):
            print("dmail key: [{}].".format(mbase32.encode(key)))

        yield from de.scan_dmail_address(\
            addr, sig_bits, key_callback=key_callback)

    if args.fetch_dmail:
        log.info("Fetching dmail for key=[{}].".format(args.fetch_dmail))

        key = mbase32.decode(args.fetch_dmail)

        if args.x:
            l, x_int = sshtype.parseMpint(base58.decode(args.x))
        else:
            x_int = None

        dmail_target = args.dmail_target

        dm, valid_sig = yield from de.fetch_dmail(key, x_int, dmail_target)

        if not dm:
            raise Exception("No dmail found.")

        if not x_int:
            print("Encrypted dmail data=[\n{}].".format(mutil.hex_dump(dm)))
        else:
            print("Subject: {}\n".format(dm.subject))

            if dm.sender_pubkey:
                print("From: {}"\
                    .format(mbase32.encode(enc.generate_ID(dm.sender_pubkey))))

            i = 0
            for part in dm.parts:
                print("DmailPart[{}]:\n    mime-type=[{}]\n    data=[{}]\n"\
                    .format(i, part.mime_type, part.data))
                i += 1

    log.info("Disconnecting.")

    yield from mc.disconnect()

    loop.stop()