1

好吧,在我真正进入这篇文章之前,我将不得不警告你,这可能不是一个简单的解决方案。看过并能回复这篇文章的人一定懂很多c/c++,至少懂一些python才能回答我上面的问题。

基本上,我有一个来自 Mumble(VOIP 客户端)的连接方法,它连接到服务器并向其发送 SSL 证书以进行身份​​验证。我还有一个 Python 脚本可以连接到同一个 Mumble VOIP 服务器,但我没有发送证书。

我需要修改现有代码以发送证书,就像当前 Mumble 客户端所做的那样。

--

这是似乎发送证书的 C++ 代码:

    ServerHandler::ServerHandler() {
         MumbleSSL::addSystemCA();

          {
           QList<QSslCipher> pref;
           foreach(QSslCipher c, QSslSocket::defaultCiphers()) {
           if (c.usedBits() < 128)
             continue;
            pref << c;
           }
           if (pref.isEmpty())
            qFatal("No ciphers of at least 128 bit found");
           QSslSocket::setDefaultCiphers(pref);
          }

    void ServerHandler::run() {
          qbaDigest = QByteArray();
          QSslSocket *qtsSock = new QSslSocket(this);

           qtsSock->setPrivateKey(g.s.kpCertificate.second);
           qtsSock->setLocalCertificate(g.s.kpCertificate.first.at(0));
           QList<QSslCertificate> certs = qtsSock->caCertificates();
           certs << g.s.kpCertificate.first;
           qtsSock->setCaCertificates(certs);

          cConnection = ConnectionPtr(new Connection(this, qtsSock));

          qtsSock->setProtocol(QSsl::TlsV1);
          qtsSock->connectToHostEncrypted(qsHostName, usPort);

     void ServerHandler::serverConnectionConnected() {
          tConnectionTimeoutTimer->stop();

          qscCert = cConnection->peerCertificateChain();
          qscCipher = cConnection->sessionCipher();

          if (! qscCert.isEmpty()) {
           const QSslCertificate &qsc = qscCert.last();
           qbaDigest = sha1(qsc.publicKey().toDer());
           bUdp = Database::getUdp(qbaDigest);
                  } else {
           bUdp = true;
          }

          QStringList tokens = Database::getTokens(qbaDigest);
          foreach(const QString &qs, tokens)
           mpa.add_tokens(u8(qs));

          QMap<int, CELTCodec *>::const_iterator i;
          for (i=g.qmCodecs.constBegin(); i != g.qmCodecs.constEnd(); ++i)
                mpa.add_celt_versions(i.key());

          sendMessage(mpa);

--

唉,这就是我现在要做的连接它(在python中):

    try:
        self.socket.connect(self.host)
    except:
        print self.threadName,"Couldn't connect to server"
        return
    self.socket.setblocking(0)
    print self.threadName,"connected to server"

--

Soo...我需要对我的 Python 源做更多的工作才能连接到需要证书的服务器?因为我的源目前可以很好地连接到任何将 requirecert 设置为 false 的 mumble 服务器。我需要它在所有服务器上工作,因为这将在我自己的服务器上使用(具有讽刺意味的是,它有 requirecerts 。)

我可以将证书预生成为 .p12 或 w/e 类型文件,因此我不需要程序来生成证书。我只需要它按照服务器的需要发送证书(就像我发布的 c++ 中所做的那样)。

请尽快帮助我!如果您需要更多信息,请再次给我发消息。 剥离了所有不相关的代码,现在它只是处理 ssl 的代码。

4

1 回答 1

0

From the C++ code it looks like you simply need to have ssl support and negotiate with the correct certification file and encrypt the payload with the correct private key. Those certifications and privates keys are most likely stored in your original program somewhere. If there are non-standard Authorities that the C++ might be loading up you'll need to find out where to put those root authorities in your python installation, or make sure python simply ignores those issues, which is less secure.

In python you can create a socket, like above, except with urllib. This library has support for HTTPs and providing the certification and private keys. URLOpener

Example Usage:

opener = urllib.URLopener(key_file = 'mykey.key', cert_file = 'mycert.cer')
self.socket = opener.open(url)

You'll probably need to make it more robust with the appropriate error checking and such, but hopefully this info will help you out.

于 2010-11-21T19:59:35.513 回答