예제 #1
0
파일: ssl.c 프로젝트: rolfrm/UDP-Client
ssl_server_client * ssl_server_listen(ssl_server * serv){

  BIO * bio = BIO_new_dgram(serv->fd, BIO_NOCLOSE);
  {
    struct timeval timeout;
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;
    BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
  }
  SSL * ssl = SSL_new(serv->ctx);
  SSL_set_bio(ssl, bio, bio);
  SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);

  struct sockaddr_storage client_addr;
  while (DTLSv1_listen(ssl, &client_addr) <= 0){
    SSL_free(ssl);
    return NULL;
  }
  ssl_server_client * con = alloc0(sizeof(ssl_server_client));
  con->ssl = ssl;
  con->addr = client_addr;
  con->bio = bio;
  return con;
  
}
예제 #2
0
int main(void)
{
    SSL_CTX *ctx = NULL;
    SSL *ssl = NULL;
    BIO *outbio = NULL;
    BIO *inbio = NULL;
    BIO_ADDR *peer = BIO_ADDR_new();
    char *data;
    long datalen;
    int ret, success = 0;
    size_t i;

    ctx = SSL_CTX_new(DTLS_server_method());
    if (ctx == NULL || peer == NULL)
        goto err;

    SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
    SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);

    /* Create an SSL object for the connection */
    ssl = SSL_new(ctx);
    if (ssl == NULL)
        goto err;

    outbio = BIO_new(BIO_s_mem());
    if (outbio == NULL)
        goto err;
    SSL_set_wbio(ssl, outbio);

    success = 1;
    for (i = 0; i < OSSL_NELEM(testpackets) && success; i++) {
        inbio = BIO_new_mem_buf((char *)testpackets[i].in,
                                testpackets[i].inlen);
        if (inbio == NULL) {
            success = 0;
            goto err;
        }
        /* Set Non-blocking IO behaviour */
        BIO_set_mem_eof_return(inbio, -1);

        SSL_set_rbio(ssl, inbio);

        /* Process the incoming packet */
        ret = DTLSv1_listen(ssl, peer);
        if (ret < 0) {
            success = 0;
            goto err;
        }

        datalen = BIO_get_mem_data(outbio, &data);

        if (testpackets[i].outtype == VERIFY) {
            if (ret == 0) {
                if (datalen != sizeof(verify)
                        || (memcmp(data, verify, sizeof(verify)) != 0)) {
                    printf("Test %ld failure: incorrect HelloVerifyRequest\n", i);
                    success = 0;
                } else {
                    printf("Test %ld success\n", i);
                }
            } else {
                printf ("Test %ld failure: should not have succeeded\n", i);
                success = 0;
            }
        } else if (datalen == 0) {
            if ((ret == 0 && testpackets[i].outtype == DROP)
                    || (ret == 1 && testpackets[i].outtype == GOOD)) {
                printf("Test %ld success\n", i);
            } else {
                printf("Test %ld failure: wrong return value\n", i);
                success = 0;
            }
        } else {
            printf("Test %ld failure: Unexpected data output\n", i);
            success = 0;
        }
        (void)BIO_reset(outbio);
        inbio = NULL;
        /* Frees up inbio */
        SSL_set_rbio(ssl, NULL);
    }

 err:
    if (!success)
        ERR_print_errors_fp(stderr);
    /* Also frees up outbio */
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    BIO_free(inbio);
    OPENSSL_free(peer);
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    CRYPTO_mem_leaks_fp(stderr);
#endif
    return success ? 0 : 1;
}
예제 #3
0
void DataPlaneServer::readyRead(int) {
    memset(&client_addr, 0, sizeof(struct sockaddr_storage));

    /* Create BIO */
    bio = BIO_new_dgram(fd, BIO_NOCLOSE);

    /* Set and activate timeouts */
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);

    ssl = SSL_new(ctx);

    SSL_set_bio(ssl, bio, bio);
    SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);

    int dtlsRet;
    errno = 0;
    while ((dtlsRet = DTLSv1_listen(ssl, &client_addr)) <= 0) {
        if (errno != EAGAIN) {
            qWarning() << "DTLSv1_listen error";
            qWarning() << SSL_get_error(ssl, dtlsRet);
            qWarning() << "Errno is" << errno;
            if (errno == EINVAL) {
                qWarning() << "!!!!!!!!!!! Your openssl library does not support DTLSv1_listen !!!!!!!!!!!";
                qWarning() << "Cannot accept new connection";
                SSL_shutdown(ssl);
                close(fd);
                SSL_free(ssl);
                ERR_remove_state(0);
                return;
            }
        }
    }

    QThread* workerThread = new QThread();
    threads.append(workerThread);

    addrUnion infServer_addr;
    addrUnion infClient_addr;
    memcpy(&infServer_addr, &server_addr, sizeof(struct sockaddr_storage));
    memcpy(&infClient_addr, &client_addr, sizeof(struct sockaddr_storage));

    // get UID from friend using his IP to create worker thread
    // if IP is not in DB we close the connection
    char friendIp[INET6_ADDRSTRLEN];
    inet_ntop(AF_INET6, &infClient_addr.s6.sin6_addr, friendIp, INET6_ADDRSTRLEN);

    ConnectionInitiator* init = ConnectionInitiator::getInstance();

    QString friendUid = qSql->getUidFromIP(QHostAddress(QString(friendIp)));
    ControlPlaneConnection* cp = init->getConnection(friendUid);
    if (friendUid.isEmpty() || cp->getMode() == Closed) {
        qDebug() << "friendUId NOT in DB or no control plane connection!";
        SSL_shutdown(ssl);

        close(fd);
        //free(info);
        SSL_free(ssl);
        ERR_remove_state(0);
        qDebug("done, connection closed.");
        fflush(stdout);
        return;
    }
    // associate with dataplaneconnection
    DataPlaneConnection* dpc = init->getDpConnection(friendUid);

    ServerWorker* worker = new ServerWorker(infServer_addr, infClient_addr, ssl, dpc);
    worker->moveToThread(workerThread);
    connect(workerThread, SIGNAL(started()), worker, SLOT(connection_handle()));
    connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
    //connect(worker, SIGNAL(bufferReady(const char*, int)), dpc, SLOT(readBuffer(const char*, int)));
    UnixSignalHandler* u = UnixSignalHandler::getInstance();
    connect(u, SIGNAL(exiting()), workerThread, SLOT(quit()));
    workerThread->start();
}