⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsslsocket.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtNetwork module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//******************************************************************************** In addition, as a special exception, Trolltech gives permission to link** the code of its release of Qt with the OpenSSL project's "OpenSSL" library** (or modified versions of the "OpenSSL" library that use the same license** as the original version), and distribute the linked executables.**** You must comply with the GNU General Public License version 2 in all** respects for all of the code used other than the "OpenSSL" code.  If you** modify this file, you may extend this exception to your version of the file,** but you are not obligated to do so.  If you do not wish to do so, delete** this exception statement from your version of this file.******************************************************************************///#define QSSLSOCKET_DEBUG/*!    \class QSslSocket    \brief The QSslSocket class provides an SSL encrypted socket for both    clients and servers.    \since 4.3    \reentrant    \ingroup io    \module network    QSslSocket establishes a secure, encrypted TCP connection you can    use for transmitting encrypted data. It can operate in both client    and server mode, and it supports modern SSL protocols, including    SSLv3 and TLSv1. By default, QSslSocket uses SSLv3, but you can    change the SSL protocol by calling setProtocol() as long as you do    it before the handshake has started.    SSL encryption operates on top of the existing TCP stream after    the socket enters the ConnectedState. There are two simple ways to    establish a secure connection using QSslSocket: With an immediate    SSL handshake, or with a delayed SSL handshake occurring after the    connection has been established in unencrypted mode.    The most common way to use QSslSocket is to construct an object    and start a secure connection by calling connectToHostEncrypted().    This method starts an immediate SSL handshake once the connection    has been established.    \code        QSslSocket *socket = new QSslSocket(this);        connect(socket, SIGNAL(encrypted()), this, SLOT(ready()));        socket->connectToHostEncrypted("imap.example.com", 993);    \endcode    As with a plain QTcpSocket, QSslSocket enters the HostLookupState,    ConnectingState, and finally the ConnectedState, if the connection    is successful. The hand shake then starts automatically, and if it    succeeds, the encrypted() signal is emitted to indicate the socket    has entered the encrypted state and is ready for use.    Note that data can be written to the socket immediately after the    return from connectToHostEncrypted() (i.e., before the encrypted()    signal is emitted). The data is queued in QSslSocket until after    the encrypted() signal is emitted.    An example of using the delayed SSL handshake to secure an    existing connection is the case where an SSL server secures an    incoming connection. Suppose you create an SSL server class as a    subclass of QTcpServer. You would override    QTcpServer::incomingConnection() with something like the example    below, which first constructs an instance of QSslSocket and then    calls setSocketDescriptor() to set the new socket's descriptor to    the exiasting one passed in. It then initiates the SSL handshake    by calling startServerEncryption().    \code        void SslServer::incomingConnection(int socketDescriptor)        {            QSslSocket *serverSocket = new QSslSocket;            if (serverSocket->setSocketDescriptor(socketDescriptor)) {                connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));                serverSocket->startServerEncryption();            } else {                delete serverSocket;            }        }    \endcode        If an error occurs, QSslSocket emits signal sslErrors. In this    case, if no action is taken to ignore the error(s), the connection    is dropped. To continue, despite the occurrence of an error, you    can call ignoreSslErrors(), either from within this slot after the    error occurs, or anytime after construction of the QSslSocket and    before the connection is attempted. This will allow QSslSocket to    ignore the errors it encounters when establishing the identity of    the peer. Ignoring errors during an SSL handshake should be used    with caution, since a fundamental characteristic of secure    connections is that they should be established with a successful    handshake.        Once encrypted, you use QSslSocket as a regular QTcpSocket. When    readyRead() is emitted, you can call read(), canReadLine() and    readLine(), or getChar() to read decrypted data from QSslSocket's    internal buffer, and you can call write() or putChar() to write    data back to the peer. QSslSocket will automatically encrypt the    written data for you, and emit bytesWritten() once the data has    been written to the peer.    As a convenience, QSslSocket supports QTcpSocket's blocking    functions waitForConnected(), waitForReadyRead(),    waitForBytesWritten(), and waitForDisconnected(). It also provides    waitForEncrypted(), which will block the calling thread until an    encrypted connection has been established.    \code        QSslSocket socket;        socket.connectToHostEncrypted("http.example.com", 443);        if (!socket.waitForEncrypted()) {            qDebug() << socket.errorString();            return false;        }        socket.write("GET / HTTP/1.0\r\n\r\n");        while (socket.waitForReadyRead())            qDebug() << socket.readAll().data();    \endcode    QSslSocket provides an extensive, easy-to-use API for handling    cryptographic ciphers, private keys, and local, peer, and    Certification Authority (CA) certificates. It also provides an API    for handling errors that occur during the handshake phase.    Customize the socket's cryptographic cipher suite before the    handshake phase with setCiphers() and setDefaultCiphers().    Customize the socket's local certificate and private key before    the handshake phase with setLocalCertificate() and setPrivateKey.    Customize the CA certificate database with addCaCertificate(),    addCaCertificates(), setCaCertificates(), addDefaultCaCertificate(),    addDefaultCaCertificates(), and setDefaultCaCertificates(). For more    information about ciphers and certificates, refer to QSslCipher and    QSslCertificate.        This product uses software developed by the OpenSSL Project for use in the    OpenSSL Toolkit. You can download the necessary software from    http://www.openssl.org/.    \sa QSslCertificate, QSslCipher, QSslError*//*!    \enum QSslSocket::SslMode    Describes the connection modes available for QSslSocket.    \value UnencryptedMode The socket is unencrypted. Its    behavior is identical to QTcpSocket.    \value SslClientMode The socket is a client-side SSL socket.    It is either alreayd encrypted, or it is in the SSL handshake    phase (see QSslSocket::isEncrypted()).    \value SslServerMode The socket is a client-side SSL socket.    It is either already encrypted, or it is in the SSL handshake    phase (see QSslSocket::isEncrypted()).*//*!    \fn QSslSocket::encrypted()    This signal is emitted when QSslSocket enters encrypted mode. After this    signal has been emitted, QSslSocket::isEncrypted() will return true, and    all further transmissions on the socket will be encrypted.    \sa QSslSocket::connectToHostEncrypted(), QSslSocket::isEncrypted()*//*!    \fn QSslSocket::modeChanged(QSslSocket::SslMode mode)    This signal is emitted when QSslSocket changes from \l    QSslSocket::UnencryptedMode to either \l QSslSocket::SslClientMode or \l    QSslSocket::SslServerMode. \a mode is the new mode.    \sa QSslSocket::mode()*//*!    \fn void QSslSocket::sslErrors(const QList<QSslError> &errors);        QSslSocket emits this signal during the SSL handshake to indicate that an    error has occurred while establishing the identity of the peer. The error    is usually an indication that QSslSocket is unable to securely identify    the peer. Unless any action is taken, the connection will be dropped after    this signal has been emitted.    If you want to continue connecting despite the errors that have occurred,    you must call QSslSocket::ignoreErrors() from inside a slot connected to    this signal. If you need to access the error list at a later point, you    can call sslErrors() (without arguments).    \a errors contains one or more errors that prevent QSslSocket from    verifying the identity of the peer.        Note: You cannot use Qt::QueuedConnection when connecting to this signal,    or calling QSslSocket::ignoreErrors() will have no effect.*/#include "qsslcipher.h"#include "qsslsocket.h"#include "qsslsocket_openssl_p.h"#include <QtCore/qdebug.h>#include <QtCore/qdir.h>#include <QtCore/qdatetime.h>#include <QtCore/qmutex.h>#include <QtNetwork/qhostaddress.h>#include <QtNetwork/qhostinfo.h>class QSslSocketGlobalData{public:    QMutex mutex;    QList<QSslCipher> ciphers;    QList<QSslCipher> supportedCiphers;    QList<QSslCertificate> caCertificates;};Q_GLOBAL_STATIC(QSslSocketGlobalData, globalData)/*!    Constructs a QSslSocket object. \a parent is passed to QObject's    constructor. The new socket's \l {QSslCipher} {cipher} suite is    set to the one returned by the static method defaultCiphers().*/QSslSocket::QSslSocket(QObject *parent)    : QTcpSocket(*new QSslSocketBackendPrivate, parent){    Q_D(QSslSocket);#ifdef QSSLSOCKET_DEBUG    qDebug() << "QSslSocket::QSslSocket(" << parent << "), this =" << (void *)this;#endif    d->q_ptr = this;    d->init();    setCiphers(defaultCiphers());}/*!    Destroys the QSslSocket.*/QSslSocket::~QSslSocket(){    Q_D(QSslSocket);#ifdef QSSLSOCKET_DEBUG    qDebug() << "QSslSocket::~QSslSocket(), this =" << (void *)this;#endif    delete d->plainSocket;    d->plainSocket = 0;}/*!    Starts an encrypted connection to the device \a hostName on \a    port, using \a mode as the \l OpenMode. This is equivalent to    calling connectToHost() to establish the connection, followed by a    call to startClientEncryption().    QSslSocket first enters the HostLookupState. Then, after entering    either the event loop or one of the waitFor...() functions, it    enters the ConnectingState, emits connected(), and then initiates    the SSL client handshake. At each state change, QSslSocket emits    signal stateChanged().    After initiating the SSL client handshake, if the identity of the    peer can't be established, signal sslErrors() is emitted. If you    want to ignore the errors and continue connecting, you must call    ignoreSslErrors(), either from inside a slot function connected to    the sslErrors() signal, or prior to entering encrypted mode. If    ignoreSslErrors is not called, the connection is dropped, signal    disconnected() is emitted, and QSslSocket returns to the    UnconnectedState.    If the SSL handshake is successful, QSslSocket emits encrypted().    \code        QSslSocket socket;        connect(&socket, SIGNAL(encrypted()), receiver, SLOT(socketEncrypted()));        socket.connectToHostEncrypted("imap", 993);        socket->write("1 CAPABILITY\r\n");    \endcode    \bold{Note:} The example above shows that text can be written to    the socket immediately after requesting the encrypted connection,    before the encrypted() signal has been emitted. In such cases, the    text is queued in the object and written to the socket \e after    the connection is established and the encrypted() signal has been    emitted.    The default for \a mode is \l ReadWrite.    If you want to create a QSslSocket on the server side of a connection, you    should instead call startServerEncryption() upon receiving the incoming    connection through QTcpServer.    \sa connectToHost(), startClientEncryption(), waitForConnected(), waitForEncrypted()*/void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode mode){    Q_D(QSslSocket);    if (d->state == ConnectedState || d->state == ConnectingState) {        qWarning("QSslSocket::connectToHostEncrypted() called when already connecting/connected");        return;    }    connectToHost(hostName, port, mode);    d->autoStartHandshake = true;}/*!    Initializes QSslSocket with the native socket descriptor \a    socketDescriptor. Returns true if \a socketDescriptor is accepted    as a valid socket descriptor; otherwise returns false.    The socket is opened in the mode specified by \a openMode, and    enters the socket state specified by \a state.    \bold{Note:} It is not possible to initialize two sockets with the same    native socket descriptor.    \sa socketDescriptor()*/bool QSslSocket::setSocketDescriptor(int socketDescriptor, SocketState state, OpenMode openMode){    Q_D(QSslSocket);#ifdef QSSLSOCKET_DEBUG    qDebug() << "QSslSocket::setSocketDescriptor(" << socketDescriptor << ","             << state << "," << openMode << ")";#endif    if (!d->plainSocket)        d->createPlainSocket(openMode);    bool retVal = d->plainSocket->setSocketDescriptor(socketDescriptor, state, openMode);    d->cachedSocketDescriptor = d->plainSocket->socketDescriptor();    setSocketError(d->plainSocket->error());    setSocketState(state);    setOpenMode(openMode);    setLocalPort(d->plainSocket->localPort());    setLocalAddress(d->plainSocket->localAddress());    setPeerPort(d->plainSocket->peerPort());    setPeerAddress(d->plainSocket->peerAddress());    setPeerName(d->plainSocket->peerName());    return retVal;}/*!    Returns the current mode for the socket; either UnencryptedMode, where    QSslSocket behaves identially to QTcpSocket, or one of SslClientMode or    SslServerMode, where the client is either negotiating or in encrypted    mode.    When the mode changes, QSslSocket emits modeChanged()    \sa SslMode*/QSslSocket::SslMode QSslSocket::mode() const{    Q_D(const QSslSocket);    return d->mode;}/*!    Returns true if the socket is encrypted; otherwise, false is returned.    An encrypted socket encrypts all data that is written by calling write()    or putChar() before the data is written to the network, and descrypts all    incoming data as the data is received from the network, before you call    read(), readLine() or getChar().    QSslSocket emits encrypted() when it enters encrypted mode.    You can call sessionCipher() to find which cryptographic cipher is used to    encrypt and decrypt your data.    \sa mode()*/bool QSslSocket::isEncrypted() const{    Q_D(const QSslSocket);    return d->connectionEncrypted;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -