Twisted Python TLS server: передать информацию о сертификате клиента в ресурс / конечную точку - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь реализовать сервер XML-RPC с клиентским сертификатом TLS в Twisted python.Кроме того, конечной целью является предоставление доступа к некоторым методам только определенному списку пользователей (т. Е. Списку сертификатов).

Пока я заканчиваю первую часть, у меня возникают трудности при передаче информации о сертификате внизк XMLRPC.render_POST, где я планирую применить фильтр.

Я нашел этот ответ , который описывает, как отображать общее имя, но у меня все еще есть две проблемы:

  1. Вызов XML-RPC от клиента не возвращается после получения ответа, что, как я предполагаю, означает, что запрос не завершен должным образом
  2. Я не знаю, как передать эту информацию дальше доресурс XMLRPC

Вот что у меня пока есть:

    import sys
    import OpenSSL
    from twisted.python.filepath import FilePath
    from twisted.internet import endpoints
    from twisted.internet import ssl
    from twisted.python import log
    from twisted.web import xmlrpc, server
    from twisted.internet.ssl import Certificate
    from twisted.internet.protocol import Protocol

    class ReportWhichClient(Protocol):
        # adapted from https://stackoverflow.com/a/28682511
        def dataReceived(self, data):
            peerCertificate = Certificate.peerFromTransport(self.transport)
            print(peerCertificate.getSubject().commonName.decode('utf-8'))


    class Example(xmlrpc.XMLRPC):
        """
        An example object to be published.
        """

        def xmlrpc_echo(self, x):
            """
            Return all passed args.
            """
            return x


    def main():
        log.startLogging(sys.stdout)

        from twisted.internet import reactor

        key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.key").getContent())
        cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,FilePath("my.crt").getContent())
        ca = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, FilePath("ca.crt").getContent())
        contextFactory = ssl.CertificateOptions(privateKey=key, certificate=cert, verify=True, caCerts=[ca] , requireCertificate=True)

        root = Example()


        endpoint = endpoints.SSL4ServerEndpoint(reactor, 8083,contextFactory)
        mySite = server.Site(root)
        mySite.protocol = ReportWhichClient
        endpoint.listen(mySite)

        reactor.run()


    if __name__ == '__main__':
        main()

Это правильный подход?Что я должен сделать, чтобы получить необходимую информацию на уровне ресурсов?

Любой ответ был бы великолепен, в этот момент я ломал голову, пытаясь найти множество решений без какого-либо результата.

Спасибо

1 Ответ

0 голосов
/ 27 ноября 2018

Хорошо, так что решение было передо мной все это время.

После перечитывания исходного кода, кажется, что transport присутствует в запросе.Все, что мне нужно было сделать, это добавить декоратор @withRequest и получить оттуда всю информацию:

class Example(xmlrpc.XMLRPC):

    @withRequest
    def xmlrpc_echo(self, request, x):
        peerCertificate = Certificate.peerFromTransport(request.transport)
        key = peerCertificate.getPublicKey().original
        # display the client public key in PEM format
        print(OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, key))
        return x
...