Пример #1
0
int32_t CSSLClientAsync::SendBufferAsync()
{
    int32_t nErrorCode = SOCKET_IO_RESULT_OK;
    m_sendqueuemutex.Lock();
    if (m_sendqueue.size() == 0)
    {
        SOCKET_IO_DEBUG("ssl send queue is empty.");
        //待发送队列中为空,则删除写事件的注册,改成读事件
        m_pio->Remove_WriteEvent(this);
        m_sendqueuemutex.Unlock();
        if (_GetWaitForCloseStatus() == TRUE)
        {
            //待发送内容发送完毕,则关闭链接
            _Close();
        }
        return nErrorCode;
    }
    CSimpleBuffer* pBufferLoop = m_sendqueue.front();
    m_sendqueuemutex.Unlock();
    int32_t nRet = SSL_write(GetSSL(), (void*)pBufferLoop->GetBuffer(), pBufferLoop->GetWriteOffset());
    if ( nRet < 0)
    {
        int32_t nError = SSL_get_error(GetSSL(), nRet);
        if (SSL_ERROR_WANT_WRITE == nError || SSL_ERROR_WANT_READ == nError)
        {
            SOCKET_IO_INFO("send ssl data, buffer is blocking, errno: %d.", nError);
        }
        else
        {
            _ClearSendBuffer();
            SOCKET_IO_ERROR("send ssl data error, errno: %d.", nError);
            DoException(GetSocketID(), SOCKET_IO_SSL_SEND_FAILED);
        }
    }
    else if (nRet == 0)
    {
        int32_t nError = SSL_get_error(GetSSL(), nRet);
        if (SSL_ERROR_ZERO_RETURN == nError)
        {
            SOCKET_IO_WARN("send ssl data error, peer closed.");
        }
        else
        {
            SOCKET_IO_ERROR("send ssl data error, errno: %d.", nError);
        }
        _ClearSendBuffer();
        DoException(GetSocketID(), SOCKET_IO_SSL_SEND_FAILED);
    }
    else if (nRet != pBufferLoop->GetWriteOffset())
    {
        //将未成功的数据重新放置buffer loop中,待下次发送
        //对于ssl来说,应该不会出现此种情况
        int32_t nSize = 0;
        pBufferLoop->Read(NULL, nRet);
        SOCKET_IO_WARN("send ssl data, send size: %d, less than %d.", nRet, pBufferLoop->GetWriteOffset());
    }
    else
    {
        SOCKET_IO_INFO("send ssl data from buffer successed.");
        m_sendqueuemutex.Lock();
        delete pBufferLoop;
        pBufferLoop = NULL;
        m_sendqueue.pop();
        m_sendqueuemutex.Unlock();
    }
    return nErrorCode;
}
Пример #2
0
int
s_time_main(int argc, char **argv)
{
	double totalTime = 0.0;
	int nConn = 0;
	SSL *scon = NULL;
	long finishtime = 0;
	int ret = 1, i;
	char buf[1024 * 8];
	int ver;

	s_time_init();

	s_time_meth = SSLv23_client_method();

	/* parse the command line arguments */
	if (parseArgs(argc, argv) < 0)
		goto end;

	if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
		return (1);

	SSL_CTX_set_quiet_shutdown(tm_ctx, 1);

	if (st_bugs)
		SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
	SSL_CTX_set_cipher_list(tm_ctx, tm_cipher);
	if (!set_cert_stuff(tm_ctx, t_cert_file, t_key_file))
		goto end;

	if ((!SSL_CTX_load_verify_locations(tm_ctx, CAfile, CApath)) ||
	    (!SSL_CTX_set_default_verify_paths(tm_ctx))) {
		/*
		 * BIO_printf(bio_err,"error setting default verify
		 * locations\n");
		 */
		ERR_print_errors(bio_err);
		/* goto end; */
	}
	if (tm_cipher == NULL)
		tm_cipher = getenv("SSL_CIPHER");

	if (tm_cipher == NULL) {
		fprintf(stderr, "No CIPHER specified\n");
	}
	if (!(perform & 1))
		goto next;
	printf("Collecting connection statistics for %d seconds\n", maxTime);

	/* Loop and time how long it takes to make connections */

	bytes_read = 0;
	finishtime = (long) time(NULL) + maxTime;
	tm_Time_F(START);
	for (;;) {
		if (finishtime < (long) time(NULL))
			break;
		if ((scon = doConnection(NULL)) == NULL)
			goto end;

		if (s_www_path != NULL) {
			int retval = snprintf(buf, sizeof buf,
			    "GET %s HTTP/1.0\r\n\r\n", s_www_path);
			if ((size_t)retval >= sizeof buf) {
				fprintf(stderr, "URL too long\n");
				goto end;
			}
			SSL_write(scon, buf, strlen(buf));
			while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
				bytes_read += i;
		}
#ifdef NO_SHUTDOWN
		SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
		SSL_shutdown(scon);
#endif
		shutdown(SSL_get_fd(scon), SHUT_RDWR);
		close(SSL_get_fd(scon));

		nConn += 1;
		if (SSL_session_reused(scon))
			ver = 'r';
		else {
			ver = SSL_version(scon);
			if (ver == TLS1_VERSION)
				ver = 't';
			else if (ver == SSL3_VERSION)
				ver = '3';
			else if (ver == SSL2_VERSION)
				ver = '2';
			else
				ver = '*';
		}
		fputc(ver, stdout);
		fflush(stdout);

		SSL_free(scon);
		scon = NULL;
	}
	totalTime += tm_Time_F(STOP);	/* Add the time for this iteration */

	i = (int) ((long) time(NULL) - finishtime + maxTime);
	printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
	printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + maxTime, bytes_read / nConn);

	/*
	 * Now loop and time connections using the same session id over and
	 * over
	 */

next:
	if (!(perform & 2))
		goto end;
	printf("\n\nNow timing with session id reuse.\n");

	/* Get an SSL object so we can reuse the session id */
	if ((scon = doConnection(NULL)) == NULL) {
		fprintf(stderr, "Unable to get connection\n");
		goto end;
	}
	if (s_www_path != NULL) {
		int retval = snprintf(buf, sizeof buf,
		    "GET %s HTTP/1.0\r\n\r\n", s_www_path);
		if ((size_t)retval >= sizeof buf) {
			fprintf(stderr, "URL too long\n");
			goto end;
		}
		SSL_write(scon, buf, strlen(buf));
		while (SSL_read(scon, buf, sizeof(buf)) > 0);
	}
#ifdef NO_SHUTDOWN
	SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
	SSL_shutdown(scon);
#endif
	shutdown(SSL_get_fd(scon), SHUT_RDWR);
	close(SSL_get_fd(scon));

	nConn = 0;
	totalTime = 0.0;

	finishtime = (long) time(NULL) + maxTime;

	printf("starting\n");
	bytes_read = 0;
	tm_Time_F(START);

	for (;;) {
		if (finishtime < (long) time(NULL))
			break;
		if ((doConnection(scon)) == NULL)
			goto end;

		if (s_www_path) {
			int retval = snprintf(buf, sizeof buf,
			    "GET %s HTTP/1.0\r\n\r\n", s_www_path);
			if ((size_t)retval >= sizeof buf) {
				fprintf(stderr, "URL too long\n");
				goto end;
			}
			SSL_write(scon, buf, strlen(buf));
			while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
				bytes_read += i;
		}
#ifdef NO_SHUTDOWN
		SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
		SSL_shutdown(scon);
#endif
		shutdown(SSL_get_fd(scon), SHUT_RDWR);
		close(SSL_get_fd(scon));

		nConn += 1;
		if (SSL_session_reused(scon))
			ver = 'r';
		else {
			ver = SSL_version(scon);
			if (ver == TLS1_VERSION)
				ver = 't';
			else if (ver == SSL3_VERSION)
				ver = '3';
			else if (ver == SSL2_VERSION)
				ver = '2';
			else
				ver = '*';
		}
		fputc(ver, stdout);
		fflush(stdout);
	}
	totalTime += tm_Time_F(STOP);	/* Add the time for this iteration */


	printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double) nConn / totalTime), bytes_read);
	printf("%d connections in %ld real seconds, %ld bytes read per connection\n", nConn, (long) time(NULL) - finishtime + maxTime, bytes_read / nConn);

	ret = 0;
end:
	if (scon != NULL)
		SSL_free(scon);

	if (tm_ctx != NULL) {
		SSL_CTX_free(tm_ctx);
		tm_ctx = NULL;
	}

	return (ret);
}
Пример #3
0
static int
ssl_write(tcpcon_t *tc, const void *data, size_t len)
{
  return SSL_write(tc->ssl, data, len) != len ? ECONNRESET : 0;
}
Пример #4
0
/*
 * The implementation of spdylay_send_callback type. Here we write
 * |data| with size |length| to the network and return the number of
 * bytes actually written. See the documentation of
 * spdylay_send_callback for the details.
 */
static ssize_t send_callback(spdylay_session *session _U_,
                             const uint8_t *data, size_t length, int flags _U_,
                             void *user_data)
{
  struct Connection *connection;
  ssize_t rv;
  connection = (struct Connection*)user_data;
  connection->want_io = IO_NONE;
  ERR_clear_error();
  rv = SSL_write(connection->ssl, data, (int)length);
  if(rv < 0) {
    int err = SSL_get_error(connection->ssl, (int)rv);
    if(err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
      connection->want_io = (err == SSL_ERROR_WANT_READ ?
                             WANT_READ : WANT_WRITE);
      rv = SPDYLAY_ERR_WOULDBLOCK;
    } else {
      rv = SPDYLAY_ERR_CALLBACK_FAILURE;
    }
  }
  return rv;
}

/*
 * The implementation of spdylay_recv_callback type. Here we read data
Пример #5
0
int s_time_main(int argc, char **argv)
{
    char buf[1024 * 8];
    SSL *scon = NULL;
    SSL_CTX *ctx = NULL;
    const SSL_METHOD *meth = NULL;
    char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *www_path = NULL;
    char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
    double totalTime = 0.0;
    int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs =
        0, ver;
    long bytes_read = 0, finishtime = 0;
    OPTION_CHOICE o;
#ifdef OPENSSL_SYS_WIN32
    int exitNow = 0;            /* Set when it's time to exit main */
#endif

    meth = SSLv23_client_method();
    verify_depth = 0;
    verify_error = X509_V_OK;

    prog = opt_init(argc, argv, s_time_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(s_time_options);
            ret = 0;
            goto end;
        case OPT_CONNECT:
            host = opt_arg();
            break;
        case OPT_REUSE:
            perform = 2;
            break;
        case OPT_NEW:
            perform = 1;
            break;
        case OPT_VERIFY:
            if (!opt_int(opt_arg(), &verify_depth))
                goto opthelp;
            BIO_printf(bio_err, "%s: verify depth is %d\n",
                       prog, verify_depth);
            break;
        case OPT_CERT:
            certfile = opt_arg();
            break;
        case OPT_KEY:
            keyfile = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_CIPHER:
            cipher = opt_arg();
            break;
        case OPT_BUGS:
            st_bugs = 1;
            break;
        case OPT_TIME:
            if (!opt_int(opt_arg(), &maxtime))
                goto opthelp;
            break;
        case OPT_WWW:
            www_path = opt_arg();
            if (strlen(www_path) > MYBUFSIZ - 100) {
                BIO_printf(bio_err, "%s: -www option too long\n", prog);
                goto end;
            }
            break;
#ifndef OPENSSL_NO_SSL3
        case OPT_SSL3:
            meth = SSLv3_client_method();
            break;
#endif
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (cipher == NULL)
        cipher = getenv("SSL_CIPHER");
    if (cipher == NULL) {
        fprintf(stderr, "No CIPHER specified\n");
        goto end;
    }

    if ((ctx = SSL_CTX_new(meth)) == NULL)
        goto end;

    SSL_CTX_set_quiet_shutdown(ctx, 1);

    if (st_bugs)
        SSL_CTX_set_options(ctx, SSL_OP_ALL);
    if (!SSL_CTX_set_cipher_list(ctx, cipher))
        goto end;
    if (!set_cert_stuff(ctx, certfile, keyfile))
        goto end;

    if (!ctx_set_verify_locations(ctx, CAfile, CApath)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    if (!(perform & 1))
        goto next;
    printf("Collecting connection statistics for %d seconds\n", maxtime);

    /* Loop and time how long it takes to make connections */

    bytes_read = 0;
    finishtime = (long)time(NULL) + maxtime;
    tm_Time_F(START);
    for (;;) {
        if (finishtime < (long)time(NULL))
            break;
#ifdef WIN32_STUFF

        if (flushWinMsgs(0) == -1)
            goto end;

        if (waitingToDie || exitNow) /* we're dead */
            goto end;
#endif

        if ((scon = doConnection(NULL, host, ctx)) == NULL)
            goto end;

        if (www_path != NULL) {
            BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
                         www_path);
            if (SSL_write(scon, buf, strlen(buf)) <= 0)
                goto end;
            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                bytes_read += i;
        }
#ifdef NO_SHUTDOWN
        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
        SSL_shutdown(scon);
#endif
        SHUTDOWN2(SSL_get_fd(scon));

        nConn += 1;
        if (SSL_session_reused(scon))
            ver = 'r';
        else {
            ver = SSL_version(scon);
            if (ver == TLS1_VERSION)
                ver = 't';
            else if (ver == SSL3_VERSION)
                ver = '3';
            else
                ver = '*';
        }
        fputc(ver, stdout);
        fflush(stdout);

        SSL_free(scon);
        scon = NULL;
    }
    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */

    i = (int)((long)time(NULL) - finishtime + maxtime);
    printf
        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
    printf
        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);

    /*
     * Now loop and time connections using the same session id over and over
     */

 next:
    if (!(perform & 2))
        goto end;
    printf("\n\nNow timing with session id reuse.\n");

    /* Get an SSL object so we can reuse the session id */
    if ((scon = doConnection(NULL, host, ctx)) == NULL) {
        fprintf(stderr, "Unable to get connection\n");
        goto end;
    }

    if (www_path != NULL) {
        BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n", www_path);
        if (SSL_write(scon, buf, strlen(buf)) <= 0)
            goto end;
        while (SSL_read(scon, buf, sizeof(buf)) > 0)
            continue;
    }
#ifdef NO_SHUTDOWN
    SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
    SSL_shutdown(scon);
#endif
    SHUTDOWN2(SSL_get_fd(scon));

    nConn = 0;
    totalTime = 0.0;

    finishtime = (long)time(NULL) + maxtime;

    printf("starting\n");
    bytes_read = 0;
    tm_Time_F(START);

    for (;;) {
        if (finishtime < (long)time(NULL))
            break;

#ifdef WIN32_STUFF
        if (flushWinMsgs(0) == -1)
            goto end;

        if (waitingToDie || exitNow) /* we're dead */
            goto end;
#endif

        if ((doConnection(scon, host, ctx)) == NULL)
            goto end;

        if (www_path) {
            BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
                         www_path);
            if (SSL_write(scon, buf, strlen(buf)) <= 0)
                goto end;
            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                bytes_read += i;
        }
#ifdef NO_SHUTDOWN
        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
        SSL_shutdown(scon);
#endif
        SHUTDOWN2(SSL_get_fd(scon));

        nConn += 1;
        if (SSL_session_reused(scon))
            ver = 'r';
        else {
            ver = SSL_version(scon);
            if (ver == TLS1_VERSION)
                ver = 't';
            else if (ver == SSL3_VERSION)
                ver = '3';
            else
                ver = '*';
        }
        fputc(ver, stdout);
        fflush(stdout);
    }
    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */

    printf
        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
    printf
        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);

    ret = 0;

 end:
    SSL_free(scon);
    SSL_CTX_free(ctx);
    return (ret);
}
Пример #6
0
int np_net_ssl_write(const void *buf, int num) {
	return SSL_write(s, buf, num);
}
Пример #7
0
static int
netsnmp_dtlsudp_send(netsnmp_transport *t, void *buf, int size,
		 void **opaque, int *olength)
{
    int rc = -1;
    netsnmp_addr_pair *addr_pair = NULL;
    struct sockaddr *to = NULL;
    bio_cache *cachep = NULL;
    netsnmp_tmStateReference *tmStateRef = NULL;
    u_char outbuf[65535];
    
    if (opaque != NULL && *opaque != NULL &&
        *olength == sizeof(netsnmp_tmStateReference)) {
        tmStateRef = (netsnmp_tmStateReference *) *opaque;

        if (tmStateRef->have_addresses)
            addr_pair = &(tmStateRef->addresses);
        else if (t != NULL && t->data != NULL &&
                 t->data_length == sizeof(netsnmp_addr_pair))
            addr_pair = (netsnmp_addr_pair *) (t->data);
    } else if (t != NULL && t->data != NULL &&
               t->data_length == sizeof(netsnmp_addr_pair)) {
        addr_pair = (netsnmp_addr_pair *) (t->data);
    }

    if (NULL == addr_pair) {
        snmp_log(LOG_ERR, "dtlsudp_send: can't get address to send to\n");
        return -1;
    }

    to = (struct sockaddr *) &(addr_pair->remote_addr);

    if (NULL == to || NULL == t || t->sock <= 0) {
        snmp_log(LOG_ERR, "invalid netsnmp_dtlsudp_send usage\n");
        return -1;
    }

    /* we're always a client if we're sending to something unknown yet */
    if (NULL ==
        (cachep = find_or_create_bio_cache(t->sock, &addr_pair->remote_addr,
                                           WE_ARE_CLIENT)))
        return -1;

    if (!cachep->securityName && tmStateRef && tmStateRef->securityNameLen > 0)
        cachep->securityName = strdup(tmStateRef->securityName);
        
        
    {
        char *str = netsnmp_udp_fmtaddr(NULL, (void *) addr_pair,
                                        sizeof(netsnmp_addr_pair));
        DEBUGMSGTL(("dtlsudp", "send %d bytes from %p to %s on fd %d\n",
                    size, buf, str, t->sock));
        free(str);
    }
    rc = SSL_write(cachep->con, buf, size);
    if (rc < 0) {
        _openssl_log_error(rc, cachep->con, "SSL_write");
    }

    /* for memory bios, we now read from openssl's write buffer (ie,
       the packet to go out) and send it out the udp port manually */
    rc = BIO_read(cachep->write_bio, outbuf, sizeof(outbuf));
    if (rc <= 0) {
        /* in theory an ok thing */
        return 0;
    }
#if defined(FIXME) && defined(linux) && defined(IP_PKTINFO)
    /* XXX: before this can work, we need to remember address we
       received it from (addr_pair) */
    rc = netsnmp_udp_sendto(cachep->sock, &cachep->sockaddr  remote  addr_pair ? &(addr_pair->local_addr) : NULL, to, outbuf, rc);
#else
    rc = sendto(t->sock, outbuf, rc, 0, &cachep->sockaddr, sizeof(struct sockaddr));
#endif /* linux && IP_PKTINFO */

    return rc;
}
int send_payload(const char *deviceTokenHex, const char *payloadBuff, size_t payloadLength)
{
    int rtn = 0;

    SSL_Connection *sslcon = ssl_connect(globalApns->host, globalApns->port, globalApns->rsa_cert, globalApns->rsa_key, NULL);
    if(sslcon == NULL)
    {
        syslog (LOG_CRIT, "[APNS Process] APNS SSL Connection failed, check connexion and configuration" );
        return -1;
    }

    if (sslcon && deviceTokenHex && payloadBuff && payloadLength)
    {
        uint8_t command = 0; /* command number */
        char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) + DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];

        /* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
        char *binaryMessagePt = binaryMessageBuff;
        uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
        uint16_t networkOrderPayloadLength = htons(payloadLength);
 
        /* command */
        *binaryMessagePt++ = command;
 
        /* token length network order */
        memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
        binaryMessagePt += sizeof(uint16_t);

        /* Convert the Device Token */
        int i = 0;
        int j = 0;
        int tmpi;
        char tmp[3];
        char deviceTokenBinary[DEVICE_BINARY_SIZE];
        while(i < strlen(deviceTokenHex))
        {
            if(deviceTokenHex[i] == ' ')
            {
                i++;
            }
            else
            {
                tmp[0] = deviceTokenHex[i];
                tmp[1] = deviceTokenHex[i + 1];
                tmp[2] = '\0';

                sscanf(tmp, "%x", &tmpi);
                deviceTokenBinary[j] = tmpi;

                i += 2;
                j++;
            }
        }

        /* device token */
        memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
        binaryMessagePt += DEVICE_BINARY_SIZE;

        /* payload length network order */
        memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
        binaryMessagePt += sizeof(uint16_t);
 
        /* payload */
        memcpy(binaryMessagePt, payloadBuff, payloadLength);
        binaryMessagePt += payloadLength;
        if (SSL_write(sslcon->ssl, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
            rtn = 1;
    }

    ssl_disconnect(sslcon);

    return rtn;
}
Пример #9
0
Файл: ssl.c Проект: N0NB/aprx
int ssl_write(struct worker_t *self, struct client_t *c)
{
	int n;
	int sslerr;
	int err;
	int to_write;
	
	to_write = c->obuf_end - c->obuf_start;
	
	//hlog(LOG_DEBUG, "ssl_write fd %d of %d bytes", c->fd, to_write);
	ssl_clear_error();
	
	n = SSL_write(c->ssl_con->connection, c->obuf + c->obuf_start, to_write);
	
	//hlog(LOG_DEBUG, "SSL_write fd %d returned %d", c->fd, n);
	
	if (n > 0) {
		/* ok, we wrote some */
		c->obuf_start += n;
		c->obuf_wtime = tick;
		
		/* All done ? */
		if (c->obuf_start >= c->obuf_end) {
			//hlog(LOG_DEBUG, "ssl_write fd %d (%s) obuf empty", c->fd, c->addr_rem);
			c->obuf_start = 0;
			c->obuf_end   = 0;
			
			/* tell the poller that we have no outgoing data */
			xpoll_outgoing(&self->xp, c->xfd, 0);
			return n;
		}
		
		xpoll_outgoing(&self->xp, c->xfd, 1);
		
		return n;
	}
	
	sslerr = SSL_get_error(c->ssl_con->connection, n);
	err = (sslerr == SSL_ERROR_SYSCALL) ? errno : 0;
	
	if (sslerr == SSL_ERROR_WANT_WRITE) {
		hlog(LOG_INFO, "ssl_write fd %d: SSL_write wants to write again, marking socket for write events", c->fd);
		
		/* tell the poller that we have outgoing data */
		xpoll_outgoing(&self->xp, c->xfd, 1);
		
		return 0;
	}
	
	if (sslerr == SSL_ERROR_WANT_READ) {
		hlog(LOG_INFO, "ssl_write fd %d: SSL_write wants to read, returning 0", c->fd);
		
		/* tell the poller that we won't be writing now, until we've read... */
		xpoll_outgoing(&self->xp, c->xfd, 0);
		
		return 0;
	}
	
	if (err) {
		hlog(LOG_DEBUG, "ssl_write fd %d: I/O syscall error: %s", c->fd, strerror(err));
	} else {
		char ebuf[255];
		
		ERR_error_string_n(sslerr, ebuf, sizeof(ebuf));
		hlog(LOG_INFO, "ssl_write fd %d failed with ret %d sslerr %u errno %d: %s (%s)",
			c->fd, n, sslerr, err, ebuf, ERR_reason_error_string(sslerr));
	}
	
	c->ssl_con->no_wait_shutdown = 1;
	c->ssl_con->no_send_shutdown = 1;
	
	hlog(LOG_DEBUG, "ssl_write fd %d: SSL_write() failed", c->fd);
	client_close(self, c, err);
	
	return -13;
}
Пример #10
0
int main_tls_client() {
  SSL_CTX *ctx;
  SSL *ssl;
  int server = 0;
  int ret;

  if ( (ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
    printf("Unable to create a new SSL context structure.\n");

  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
  // Force gcm(aes) mode
  SSL_CTX_set_cipher_list(ctx, "ECDH-ECDSA-AES128-GCM-SHA256");

  ssl = SSL_new(ctx);

  server = create_socket();

  SSL_set_fd(ssl, server);

  if ( SSL_connect(ssl) != 1 ) {
    printf("Error: Could not build a SSL session\n");
    exit(-1);
  }

// Start tests

  clock_t start, end;
  double cpu_time_used;

  int filefd;
  int bytes;
  int totalbytes = 0;
  bytes_recv = 0;
  char buf[16384];

  int res = 0;
  int total_recv = 0;

  start = clock();

  filefd = open(test_data, O_RDONLY);
  totalbytes = 0;

  do {
    bytes = read(filefd, buf, sizeof(buf));
    totalbytes += bytes;
    if (bytes > 0)
      SSL_write(ssl, buf, bytes);
  } while(bytes > 0);

  close(filefd);


    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

    printf("OpenSSL receive time: %.02f\n", cpu_time_used);

  res = 0;
  total_recv = 0;

  res = SSL_read(ssl, buf, 1);

  total_recv += res;
  if (res < 0) {
    printf("SSL Read error: %i\n", res);
  }
  printf("Received openssl test data: %i %i\n", res, total_recv);

/* Kernel TLS tests */
  int tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
  if (tfmfd == -1) {
    perror("socket error:");
    exit(-1);
  }

  struct sockaddr_alg sa = {
    .salg_family = AF_ALG,
    .salg_type = "tls", /* this selects the hash logic in the kernel */
    .salg_name = "rfc5288(gcm(aes))" /* this is the cipher name */
  };

  if (bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
    perror("AF_ALG: bind failed");
    close(tfmfd);
    exit(-1);
  }

  int opfd = accept(tfmfd, NULL, 0);
  if (opfd == -1) {
    perror("accept:");
    close(tfmfd);
    exit(-1);
  }

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 16)) {
    perror("AF_ALG: set authsize failed\n");
    exit(-1);
  }

  EVP_CIPHER_CTX * writeCtx = ssl->enc_write_ctx;
  EVP_CIPHER_CTX * readCtx = ssl->enc_read_ctx;

  EVP_AES_GCM_CTX* gcmWrite = (EVP_AES_GCM_CTX*)(writeCtx->cipher_data);
  EVP_AES_GCM_CTX* gcmRead = (EVP_AES_GCM_CTX*)(readCtx->cipher_data);

  unsigned char* writeKey = (unsigned char*)(gcmWrite->gcm.key);
  unsigned char* readKey = (unsigned char*)(gcmRead->gcm.key);

  unsigned char* writeIV = gcmWrite->iv;
  unsigned char* readIV = gcmRead->iv;

  char keyiv[20];
  memcpy(keyiv, writeKey, 16);
  memcpy(keyiv + 16, writeIV, 4);

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) {
    perror("AF_ALG: set write key failed\n");
    exit(-1);
  }

  memcpy(keyiv, readKey, 16);
  memcpy(keyiv + 16, readIV, 4);

  if (setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, keyiv, 20)) {
    perror("AF_ALG: set read key failed\n");
    exit(-1);
  }

  // Load up the cmsg data
  struct cmsghdr *header = NULL;
  uint32_t *type = NULL;
  struct msghdr msg;

  /* IV data */
  struct af_alg_iv *alg_iv = NULL;
  int ivsize = 12;
  uint32_t iv_msg_size = CMSG_SPACE(sizeof(*alg_iv) + ivsize);

  /* AEAD data */
  uint32_t *assoclen = NULL;
  uint32_t assoc_msg_size = CMSG_SPACE(sizeof(*assoclen));

  uint32_t bufferlen =
    CMSG_SPACE(sizeof(*type)) + /* Encryption / Decryption */
    iv_msg_size +/* IV */
    assoc_msg_size;/* AEAD associated data size */

  memset(&msg, 0, sizeof(msg));

  char* buffer = calloc(1, bufferlen);
  if (!buffer)
    return -ENOMEM;

  msg.msg_control = buffer;
  msg.msg_controllen = bufferlen;
  msg.msg_iov = NULL;
  msg.msg_iovlen = 0;

  /* encrypt/decrypt operation */
  header = CMSG_FIRSTHDR(&msg);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_OP;
  header->cmsg_len = CMSG_LEN(sizeof(*type));
  type = (void*)CMSG_DATA(header);
  *type = server;


  /* set IV */
  header = CMSG_NXTHDR(&msg, header);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_IV;
  header->cmsg_len = iv_msg_size;
  alg_iv = (void*)CMSG_DATA(header);
  alg_iv->ivlen = 8;
  uint64_t writeSeq;
  unsigned char* writeSeqNum = ssl->s3->write_sequence;
  memcpy(&writeSeq, writeSeqNum, sizeof(writeSeq));

  memcpy(alg_iv->iv, &writeSeq, 8);


  /* set AEAD information */
  /* Set associated data length */
  header = CMSG_NXTHDR(&msg, header);
  header->cmsg_level = SOL_ALG;
  header->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
  header->cmsg_len = CMSG_LEN(sizeof(*assoclen));
  assoclen = (void*)CMSG_DATA(header);
  *assoclen = 13 + 8;

  ret = sendmsg(opfd, &msg, MSG_MORE);
  if (ret < 0) {
    perror("sendmsg");
    exit(-1);
  }

  header = CMSG_FIRSTHDR(&msg);
  header = CMSG_NXTHDR(&msg, header);
  alg_iv = (void*)CMSG_DATA(header);
  uint64_t readSeq;
  unsigned char* readSeqNum = ssl->s3->read_sequence;
  memcpy(&readSeq, readSeqNum, sizeof(readSeq));
  memcpy(alg_iv->iv, &readSeq, 8);

  ret = sendmsg(opfd, &msg, MSG_MORE);
  if (ret < 0) {
    perror("sendmsg recv");
    exit(-1);
  }

  // Try some simple writes

  send(opfd, buf, 10, 0);
  send(opfd, buf, 100, 0);
  send(opfd, buf, 16000, 0);
  printf("Successful send\n");

  res = 0;
  total_recv = 0;

  res = recv(opfd, &buf, 1, 0);

  total_recv += res;
  if (res < 0) {
    printf("Ktls recv error: %i\n", res);
  }
  printf("Recvd ktls test data: %i %i\n", res, total_recv);

  start = clock();
  off_t offset = 0;


  filefd = open(test_data, O_RDONLY);

  res = sendfile(opfd, filefd, &offset, totalbytes);

  close(filefd);

  end = clock();
  cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

  printf("ktls receive time: %.02f\n", cpu_time_used);

  SSL_free(ssl);
  close(server);
  SSL_CTX_free(ctx);
  return(0);
}

int OpenListener(int port)
{   int sd;
  struct sockaddr_in6 addr;

  sd = socket(PF_INET6, SOCK_STREAM, 0);
  bzero(&addr, sizeof(addr));
  addr.sin6_family = AF_INET6;
  addr.sin6_port = htons(port);
  memcpy(addr.sin6_addr.s6_addr, &in6addr_any, sizeof(in6addr_any));

  if ( bind(sd, (const struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
      perror("can't bind port");
      abort();
    }
  if ( listen(sd, 10) != 0 )
    {
      perror("Can't configure listening port");
      abort();
    }
  return sd;
}
Пример #11
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;

    while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'p' :
                port = atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName) {
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                                          XSTRLEN(sniHostName)))
            err_sys("UseSNI failed");
        else
            CyaSSL_CTX_SNI_SetOptions(ctx, CYASSL_SNI_HOST_NAME,
                                                  CYASSL_SNI_ABORT_ON_MISMATCH);
    }
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");
    CyaSSL_set_quiet_shutdown(ssl, 1) ;
#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
        osDelay(5000) ;
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0) {
        #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_CERTS)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }
        osDelay(5000) ;
#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[80];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);
        osDelay(5000) ;
    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_CYASSL_MEMORY */

    return 0;
}
Пример #12
0
bool sslLoop(SSL *ssl, int fd, bool isserver, bool verify, bool waitforpeer)
{
    char inbuffer[NBYTES+1]; // Want to null terminate
    char netbuffer[NBYTES];

    size_t insize = 0, instart = 0;
    bool read_wantwrite = false; // set if last read return want_write
    bool write_wantread = false; // set if last write returned want_read
    bool closed = false; // stdin has closed
    terminated = false;  // global flag set by signal handler
    while (!terminated || SSL_renegotiate_pending(ssl)) {
        bool write_pending = insize > 0;
        fd_set rfds, wfds;
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        // Suppress ingest of data if we are renegotiating & we are the server
        if (!closed && !write_pending && (!isserver || !SSL_renegotiate_pending(ssl))) {
            FD_SET(0, &rfds);
        }
        if (!write_pending) {
            if (!read_wantwrite) {
                FD_SET(fd, &rfds);
            } else {
                FD_SET(fd, &wfds);
            }
        }
        if (write_pending) {
            if (write_wantread) {
                FD_SET(fd, &rfds);
            } else {
                FD_SET(fd, &wfds);
            }
        }
        {
            int ret = select(fd+1,&rfds,&wfds,NULL,NULL);
            if (ret < 0 && errno == EINTR) continue; // Recheck loop condition
            select_count++;
            CHECK(ret >= 0);
        }
        if (FD_ISSET(0, &rfds)) {
            size_t ret = read(0, inbuffer,NBYTES);
            if (debuglevel > 4) fprintf(stderr,"Read %zd bytes from 0\n", ret);
            CHECK(ret >= 0);
            if (ret <= 0) {
                closed = true;
                if (!waitforpeer) return true;
            } else {
                inbuffer[ret] = 0;
                if (strcmp(inbuffer, "r\n") == 0) {
                    if (!renegotiatefull(ssl,isserver)) return false;
                } else {
                    insize = ret;
                    instart = 0;
                }
            }
        }
        bool gotsslevent = FD_ISSET(fd, &rfds) || FD_ISSET(fd, &wfds);
        // If we aren't waiting to complete a write we must be waiting to read.
        // If we are waiting to complete a write, we mustn't read as the
        // OpenSSL state machine cannae take it.
        if (!write_pending && gotsslevent) {
            while (true) {
                int ret = SSL_read(ssl, netbuffer, NBYTES);
                int err = SSL_get_error(ssl,ret);
                if (ret == 0) {
                    return err == SSL_ERROR_ZERO_RETURN;
                } else if (ret > 0) {
                    CHECK(err == SSL_ERROR_NONE);
                    if (debuglevel > 4) fprintf(stderr,"Read %d bytes from SSL\n", ret);
                    read_ok_count++;
                    nread += ret;
                    if (!noecho) CHECK(write(1,netbuffer,ret) > 0);
                    if (verify) {
                        // On first read from client, do client verification
                        assert(isserver);
                        verify = false;
                        if (debuglevel > 2) fprintf(stderr,"Verifying client\n");
                        SSL_set_verify(ssl,
                                       SSL_VERIFY_PEER |
                                       //SSL_VERIFY_CLIENT_ONCE |
                                       SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                                       verifyCallback);
                        if (!renegotiatefull(ssl,isserver)) return false;
                        if (debuglevel > 2) fprintf(stderr,"Client verified\n");
                    }
                } else {
                    if (err == SSL_ERROR_WANT_READ) {
                        read_wantread_count++;
                        read_wantwrite = false;
                    } else if (err == SSL_ERROR_WANT_WRITE) {
                        read_wantwrite_count++;
                        read_wantwrite = true;
                    } else {
                        fprintf(stderr, "SSL_read: err %d\n", err);
                        CHECK(0);
                    }
                    break; // On error return
                }
            }
        }
        // We might have done some reads or writes to the socket in
        // the calls to SSL_read, so it's not clear that the various
        // flags are still valid at this point. So just
        // call SSL_write unconditionally & keep the logic simple (if we
        // didn't do a read, then we must have got the flags for write, if
        // we did, then the state might have changed), and if we didn't get
        // signalled on the SSL fd at all, we must have got something in
        // from stdin.
        // However, if write_pending is true, then we won't have tried
        // to read & it's only worth trying a write if we really got an
        // event on the SSL socket. I think.
        if (insize > 0 && !(write_pending && !gotsslevent)) {
            int ret = SSL_write(ssl, inbuffer+instart, insize);
            if (ret == 0) {
                return true;
            } else if (ret > 0) {
                if (debuglevel > 4) fprintf(stderr,"Write %d bytes to SSL\n", ret);
                // Allow for partial writes
                insize -= ret;
                instart += ret;
                nwritten += ret;
                write_wantread = false;
                write_ok_count++;
            } else {
                int err = SSL_get_error(ssl,ret);
                if (err == SSL_ERROR_WANT_READ) {
                    write_wantread = true;
                    write_wantread_count++;
                } else if (err == SSL_ERROR_WANT_WRITE) {
                    write_wantread = false;
                    write_wantwrite_count++;
                } else {
                    fprintf(stderr,"SSL_write: err %d\n", err);
                    CHECK(0);
                }
            }
        }
        // Now maybe start a random renegotiation
        if (!verify && insize == 0 && rfactor > 0 && rand()%rfactor == 0) {
            renegotiate_count++;
            if (!renegotiate(ssl,isserver)) return false;
        }
    }
    return true;
}
Пример #13
0
int main(int argc, char *argv[])
{
    /* deletes existeng ecents */
    remove("ecents.txt");
    SSL_CTX *ctx;
    int type, server, localport, proxyport, bankport;
    int i = 0;
    SSL *ssl;
    char buf[1024];
	char buf2[33000];
    int bytes;
    char *proxyhost;
    char *bankhost;
    
    if ( argc <6 )
    {
        printf("usage: type localport proxyhost proxyport bankhost bankport \n");
        exit(0);
    }
    /* initialises SSL library and copies line arguments */
    SSL_library_init();
    type = atoi(argv[1]);
    localport=atoi(argv[2]);
    proxyhost=argv[3];
    proxyport = atoi(argv[4]);
    bankhost = argv[5];
    bankport = atoi(argv[6]);
    registrationrequest(type, localport, proxyhost, proxyport);
    int requestedecents = 1000;
    
    
    while(1){
        char msg[1024];
        bzero(msg,1024);
        ctx = InitCTX();
        if(i == 0){
            printf("\nrequested number of eCents: \n");
	    wait(3);
	    printf("\t%i\n", requestedecents);
	    wait(3);
            sprintf(msg,"%c%i",'0',requestedecents);
	        server = OpenConnection(bankhost, localport, bankport);
        }
        else{
            printf("\ninput:\n");
            strcpy(msg, geteCent());
            if(strlen(msg) != 32){
                printf("no eCents\n");
            }
            else {
                strcat(msg, getData());
                server = OpenConnection(proxyhost, localport, proxyport);
            }
        }
	/* creates ssl context and sets socket to it*/
        ssl = SSL_new(ctx);      
        SSL_set_fd(ssl, server);   
        if ( SSL_connect(ssl) == -1 ){  
            ERR_print_errors_fp(stderr);
	    printf("connection error\n");
	}
        else
        {
            printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
            printf("sending: %s\n", msg);
            ShowCerts(ssl);  
		/* Write to Bank to verify ecent */  
            SSL_write(ssl, msg, sizeof(msg));  
            
            if(i == 0){
		bzero(buf2, 33000);
		/* Read from Bank, confirm verification*/
		bytes = SSL_read(ssl, buf2, sizeof(buf2)); 
		if(bytes < 1) 
		{
			printf("Exit read error from Bank\n");
			exit(1);
		}
            	buf2[bytes] = '\0';
                printf("eCents received: %s\n", buf2);
                puteCents(buf2);
            }
            else{
		/* Reads from Collector*/
		bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
            	buf[bytes] = '\0';
		if(bytes < 1) 
		{
			printf("Exit: read error from Analyst\n");
			exit(1);
		}
                if(strcmp(buf, "invalid eCent") == 0)
                    printf("\n%s\n", buf);
                else
                    printf("\naverage: %s\n", buf);
            }
            SSL_free(ssl);        
        }
        sleep(1);
        close(server);         
        SSL_CTX_free(ctx);       
        i++;
    }
    return 0;
}
Пример #14
0
/* sock stream/TCP handler */
void ev_handler(int fd, short ev_flags, void *arg)
{
    int n = 0;
    if(ev_flags & E_READ)
    {
        if(is_use_ssl)
        {
#ifdef USE_SSL
            n = SSL_read(conns[fd].ssl, conns[fd].response, EV_BUF_SIZE - 1);
#else
            n = read(fd, conns[fd].response, EV_BUF_SIZE - 1);
#endif
        }
        else
        {
            n = read(fd, conns[fd].response, EV_BUF_SIZE - 1);
        }
        if(n > 0 )
        {
            SHOW_LOG("Read %d bytes from %d", n, fd);
            conns[fd].response[n] = 0;
            SHOW_LOG("Updating event[%p] on %d ", &conns[fd].event, fd);
            event_add(&conns[fd].event, E_WRITE);	
        }		
        else
        {
            if(n < 0 )
                FATAL_LOG("Reading from %d failed, %s", fd, strerror(errno));
            goto err;
        }
    }
    if(ev_flags & E_WRITE)
    {
        if(is_use_ssl)
        {
#ifdef USE_SSL
            n = SSL_write(conns[fd].ssl, conns[fd].request, strlen(conns[fd].request));
#else
            n = write(fd, conns[fd].request, strlen(conns[fd].request));
#endif
        }
        else
        {
            n = write(fd, conns[fd].request, strlen(conns[fd].request));
        }

        if(n > 0 )
        {
            SHOW_LOG("Wrote %d bytes via %d", n, fd);
        }
        else
        {
            if(n < 0)
                FATAL_LOG("Wrote data via %d failed, %s", fd, strerror(errno));	
            goto err;
        }
        event_del(&conns[fd].event, E_WRITE);
    }
    return ;
err:
    {
        event_destroy(&conns[fd].event);
        shutdown(fd, SHUT_RDWR);
        close(fd);
#ifdef USE_SSL
        if(conns[fd].ssl)
        {
            SSL_shutdown(conns[fd].ssl);
            SSL_free(conns[fd].ssl);
            conns[fd].ssl = NULL;
        }
#endif

        SHOW_LOG("Connection %d closed", fd);
    }
}
Пример #15
0
int sendData_SSL(SSL* ssl, char *buf)
{
	int offset = 0,res,nLeft = strlen(buf);
	fd_set fdwrite;
	fd_set fdread;
	timeval time;

	int write_blocked_on_read = 0;

	time.tv_sec = SEND_RECIEVE_TO; 
	time.tv_usec = 0;


	if(buf == NULL)
		return SENDBUF_IS_EMPTY;

	while(nLeft > 0)
	{
		FD_ZERO(&fdwrite);
		FD_ZERO(&fdread);

		FD_SET(smtp_socket,&fdwrite);

		if(write_blocked_on_read)
		{
			FD_SET(smtp_socket, &fdread);
		}

		if((res = select(smtp_socket+1,&fdread,&fdwrite,NULL,&time)) == SOCKET_ERROR)
		{
			FD_ZERO(&fdwrite);
			FD_ZERO(&fdread);
			return WSA_SELECT;
		}

		if(!res)
		{
			//timeout
			FD_ZERO(&fdwrite);
			FD_ZERO(&fdread);
			return SERVER_NOT_RESPONDING;
		}

		if(FD_ISSET(smtp_socket,&fdwrite) || (write_blocked_on_read && FD_ISSET(smtp_socket, &fdread)) )
		{
			write_blocked_on_read=0;

			/* Try to write */
			res = SSL_write(ssl, buf+offset, nLeft);
	          
			switch(SSL_get_error(ssl,res))
			{
			  /* We wrote something*/
			  case SSL_ERROR_NONE:
				nLeft -= res;
				offset += res;
				break;
	              
				/* We would have blocked */
			  case SSL_ERROR_WANT_WRITE:
				break;

				/* We get a WANT_READ if we're
				   trying to rehandshake and we block on
				   write during the current connection.
	               
				   We need to wait on the socket to be readable
				   but reinitiate our write when it is */
			  case SSL_ERROR_WANT_READ:
				write_blocked_on_read=1;
				break;
	              
				  /* Some other error */
			  default:	      
				FD_ZERO(&fdread);
				FD_ZERO(&fdwrite);
				return SSL_PROBLEM;
			}

		}
	}

	OutputDebugStringA(buf);
	FD_ZERO(&fdwrite);
	FD_ZERO(&fdread);

	return CSMTP_NO_ERROR;
}
Пример #16
0
void SslClient:: CSend(const void *buf_, size_t length_, long timeout_)
{
    int retval;
    fd_set write_fds;
    fd_set read_fds;
    size_t sent_bytes = 0;
    struct timeval timeout;
    struct timeval* ptimeout;

    do
    {
        FD_ZERO(&write_fds);
        FD_ZERO(&read_fds);

        bool need_io;

        do
        {
            int bytes;
            need_io = false;

            bytes = SSL_write(this->ssl_m, (char *)buf_ + sent_bytes, length_ - sent_bytes);

            if(bytes > 0)
            {
                sent_bytes += bytes;
                continue;
            }

            // 测试错误
            switch(SSL_get_error(ssl_m, bytes))
            {
            case SSL_ERROR_NONE:
                break;

            case SSL_ERROR_ZERO_RETURN:
                Throw("socket closed by client", 0);
                break;

            case SSL_ERROR_WANT_READ:
#ifdef SslClient_DEBUG
                printf("SSL_ERROR_WANT_READ\n");
#endif
                FD_SET(this->sock_fd, &read_fds);

                need_io = true;
                break;

            case SSL_ERROR_WANT_WRITE:
#ifdef SslClient_DEBUG
                printf("SSL_ERROR_WANT_WRITE\n");
#endif
                FD_SET(this->sock_fd, &write_fds);

                need_io = true;
                break;

            case SSL_ERROR_SYSCALL:
                Throw("ssl I/O error occurred", MException::ME_RUNTIME);
                break;

            default:
                Throw("SSL_read() failed", MException::ME_RUNTIME);

            }

        } while(need_io == false && sent_bytes != length_);

        if( sent_bytes == length_ )
        {
            break;
        }

        ptimeout= TranslateTime(timeout_, &timeout);

        // 等待数据到来
        while((retval = select(FD_SETSIZE, &read_fds, &write_fds, NULL, ptimeout)) == -1
                && errno == EINTR);

        if( retval > 0 )
        {
            continue;
        }
        else if( retval == 0 )
        {
            Throw("Socket time out", 0);
        }
        else
        {
            Throw("Select failed", errno);
        }

    } while(sent_bytes != length_);

    return;
}
Пример #17
0
gint
hybrid_ssl_write(HybridSslConnection *ssl, const gchar *buf, gint len)
{
    gint l;
    /*
    for (i = 0; len > 0; i ++) {
        while (1) {
            l = SSL_write(ssl->ssl, buf + i * 4096, len > 4096 ? 4096 : len);

            switch (SSL_get_error(ssl->ssl, l)) {
                case SSL_ERROR_NONE:
                    len -= 4096;
                    goto ssl_write_ok;
                case SSL_ERROR_WANT_WRITE:
                    g_usleep(100);
                    continue;
                default:
                    return -1;
            }
        }
ssl_write_ok:;
    }
    */

rewrite:
    l = SSL_write(ssl->ssl, buf, len);

    switch (SSL_get_error(ssl->ssl, l)) {
    case SSL_ERROR_NONE:
        if (l != len) {
            hybrid_debug_error("ssl",
                               "ssl write %d bytes but only %d byte succeed.",
                               len, l);
            return -1;
        }
        return l;
    case SSL_ERROR_WANT_WRITE:
        hybrid_debug_error("ssl",
                           "ssl write with SSL_ERROR_WANT_WRITE.");
        usleep(100);
        goto rewrite;
    case SSL_ERROR_SYSCALL:
        hybrid_debug_error("ssl",
                           "ssl write with io error.");
        return -1;
    case SSL_ERROR_WANT_X509_LOOKUP:
        hybrid_debug_error("ssl",
                           "ssl write with SSL_ERROR_WANT_X509_LOOKUP.");
        return -1;
    case SSL_ERROR_ZERO_RETURN:
        hybrid_debug_error("ssl",
                           "ssl connection permaturely closed.");
        return 0;
    case SSL_ERROR_SSL:
    default:
        ERR_print_errors_fp(stderr);
        hybrid_debug_error("ssl",
                           "ssl write with other error.");
        return -1;
    }

    return len;
}
Пример #18
0
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin   = stdin  ;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char msg[1024];
    char reply[1024+1];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int doDTLS = 0;
    int doPSK = 0;
    int sendSz;
    int argc    = 0;
    char** argv = 0;
    int port = yasslPort;

    ((func_args*)args)->return_code = -1; /* error state */
    
#ifndef CYASSL_MDK_SHELL
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;
#endif

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

#ifdef CYASSL_DTLS
    doDTLS  = 1;
#endif

#ifdef CYASSL_LEANPSK 
    doPSK = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    doPSK = 1;
#endif

#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_SHELL)
    port = ((func_args*)args)->signal->port;
#endif

#if defined(CYASSL_DTLS)
    method  = DTLSv1_client_method();
#elif  !defined(NO_TLS)
    method = CyaSSLv23_client_method();
#else
    method = SSLv3_client_method();
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    #ifndef NO_RSA
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
#elif !defined(NO_CERTS)
    if (!doPSK)
        load_buffer(ctx, caCert, CYASSL_CA);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
#endif
    if (doPSK) {
#ifndef NO_PSK
        const char *defaultCipherList;

        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        #ifdef HAVE_NULL_CIPHER
            defaultCipherList = "PSK-NULL-SHA256";
        #else
            defaultCipherList = "PSK-AES128-CBC-SHA256";
        #endif
        if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=SSL_SUCCESS)
            err_sys("client can't set cipher list 2");
#endif
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    #if defined(CYASSL_MDK_ARM)
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif

    ssl = SSL_new(ctx);
        

    if (doDTLS) {
        SOCKADDR_IN_T addr;
        build_addr(&addr, yasslIP, port, 1);
        CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
        tcp_socket(&sockfd, 1);
    }
    else {
        tcp_connect(&sockfd, yasslIP, port, 0);
    }
        
    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif

    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(msg, sizeof(msg), fin) != 0) {
     
        sendSz = (int)strlen(msg);

        if (SSL_write(ssl, msg, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(msg, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(msg, "break", 5) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        #ifndef CYASSL_MDK_SHELL
        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
            else
                break;
        }
        #else
        {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply)-1)) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                fflush(fout) ;
                sendSz -= got;
            }
        }
        #endif
    }


#ifdef CYASSL_DTLS
    strncpy(msg, "break", 6);
    sendSz = (int)strlen(msg);
    /* try to tell server done */
    SSL_write(ssl, msg, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
Пример #19
0
/* handles a client connection */
void handle_connection(int sock){
        u_int32_t calculated_crc32;
	command *temp_command;
	packet receive_packet;
	packet send_packet;
	int bytes_to_send;
	int bytes_to_recv;
	char buffer[MAX_INPUT_BUFFER];
	char raw_command[MAX_INPUT_BUFFER];
	char processed_command[MAX_INPUT_BUFFER];
	int result=STATE_OK;
	int early_timeout=FALSE;
	int rc;
	int x;
#ifdef DEBUG
	FILE *errfp;
#endif
#ifdef HAVE_SSL
	SSL *ssl=NULL;
#endif


	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Handling the connection...");

#ifdef OLDSTUFF
	/* socket should be non-blocking */
	fcntl(sock,F_SETFL,O_NONBLOCK);
#endif

	/* set connection handler */
	signal(SIGALRM,my_connection_sighandler);
	alarm(connection_timeout);

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_set_fd(ssl,sock);

			/* keep attempting the request if needed */
                        while(((rc=SSL_accept(ssl))!=1) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));

			if(rc!=1){
				syslog(LOG_ERR,"Error: Could not complete SSL handshake. %d\n",SSL_get_error(ssl,rc));
#ifdef DEBUG
				errfp=fopen("/tmp/err.log","w");
				ERR_print_errors_fp(errfp);
				fclose(errfp);
#endif
				return;
			        }
		        }
		else{
			syslog(LOG_ERR,"Error: Could not create SSL connection structure.\n");
#ifdef DEBUG
			errfp=fopen("/tmp/err.log","w");
			ERR_print_errors_fp(errfp);
			fclose(errfp);
#endif
			return;
		        }
	        }
#endif

	bytes_to_recv=sizeof(receive_packet);
	if(use_ssl==FALSE)
		rc=recvall(sock,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
	else{
                while(((rc=SSL_read(ssl,&receive_packet,bytes_to_recv))<=0) && (SSL_get_error(ssl,rc)==SSL_ERROR_WANT_READ));
		}
#endif

	/* recv() error or client disconnect */
	if(rc<=0){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Could not read request from client, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			complete_SSL_shutdown( ssl);
			SSL_free(ssl);
			syslog(LOG_INFO,"INFO: SSL Socket Shutdown.\n");
			}
#endif

		return;
                }

	/* we couldn't read the correct amount of data, so bail out */
	else if(bytes_to_recv!=sizeof(receive_packet)){

		/* log error to syslog facility */
		syslog(LOG_ERR,"Data packet from client was too short, bailing out...");

#ifdef HAVE_SSL
		if(ssl){
			complete_SSL_shutdown( ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

#ifdef DEBUG
	fp=fopen("/tmp/packet","w");
	if(fp){
		fwrite(&receive_packet,1,sizeof(receive_packet),fp);
		fclose(fp);
	        }
#endif

	/* make sure the request is valid */
	if(validate_request(&receive_packet)==ERROR){

		/* log an error */
		syslog(LOG_ERR,"Client request was invalid, bailing out...");

		/* free memory */
		free(command_name);
		command_name=NULL;
		for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
			free(macro_argv[x]);
			macro_argv[x]=NULL;
	                }

#ifdef HAVE_SSL
		if(ssl){
			complete_SSL_shutdown( ssl);
			SSL_free(ssl);
			}
#endif

		return;
	        }

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Host is asking for command '%s' to be run...",receive_packet.buffer);

	/* disable connection alarm - a new alarm will be setup during my_system */
	alarm(0);

	/* if this is the version check command, just spew it out */
	if(!strcmp(command_name,NRPE_HELLO_COMMAND)){

		snprintf(buffer,sizeof(buffer),"NRPE v%s",PROGRAM_VERSION);
		buffer[sizeof(buffer)-1]='\x0';

		/* log info to syslog facility */
		if(debug==TRUE)
			syslog(LOG_DEBUG,"Response: %s",buffer);

		result=STATE_OK;
	        }

	/* find the command we're supposed to run */
	else{
		temp_command=find_command(command_name);
		if(temp_command==NULL){

			snprintf(buffer,sizeof(buffer),"NRPE: Command '%s' not defined",command_name);
			buffer[sizeof(buffer)-1]='\x0';

			/* log error to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"%s",buffer);

			result=STATE_CRITICAL;
	                }

		else{

			/* process command line */
			if(command_prefix==NULL)
				strncpy(raw_command,temp_command->command_line,sizeof(raw_command)-1);
			else
				snprintf(raw_command,sizeof(raw_command)-1,"%s %s",command_prefix,temp_command->command_line);
			raw_command[sizeof(raw_command)-1]='\x0';
			process_macros(raw_command,processed_command,sizeof(processed_command));

			/* log info to syslog facility */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Running command: %s",processed_command);

			/* run the command */
			strcpy(buffer,"");
			result=my_system(processed_command,command_timeout,&early_timeout,buffer,sizeof(buffer));

			/* log debug info */
			if(debug==TRUE)
				syslog(LOG_DEBUG,"Command completed with return code %d and output: %s",result,buffer);

			/* see if the command timed out */
			if(early_timeout==TRUE)
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Command timed out after %d seconds\n",command_timeout);
			else if(!strcmp(buffer,""))
				snprintf(buffer,sizeof(buffer)-1,"NRPE: Unable to read output\n");

			buffer[sizeof(buffer)-1]='\x0';

			/* check return code bounds */
			if((result<0) || (result>3)){

				/* log error to syslog facility */
				syslog(LOG_ERR,"Bad return code for [%s]: %d", buffer,result);

				result=STATE_UNKNOWN;
			        }
		        }
	        }

	/* free memory */
	free(command_name);
	command_name=NULL;
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++){
		free(macro_argv[x]);
		macro_argv[x]=NULL;
	        }

	/* strip newline character from end of output buffer */
	if(buffer[strlen(buffer)-1]=='\n')
		buffer[strlen(buffer)-1]='\x0';

	/* clear the response packet buffer */
	bzero(&send_packet,sizeof(send_packet));

	/* fill the packet with semi-random data */
	randomize_buffer((char *)&send_packet,sizeof(send_packet));

	/* initialize response packet data */
	send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
	send_packet.packet_type=(int16_t)htons(RESPONSE_PACKET);
	send_packet.result_code=(int16_t)htons(result);
	strncpy(&send_packet.buffer[0],buffer,MAX_PACKETBUFFER_LENGTH);
	send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';
	
	/* calculate the crc 32 value of the packet */
	send_packet.crc32_value=(u_int32_t)0L;
	calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet));
	send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32);


	/***** ENCRYPT RESPONSE *****/


	/* send the response back to the client */
	bytes_to_send=sizeof(send_packet);
	if(use_ssl==FALSE)
		sendall(sock,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
	else
		SSL_write(ssl,&send_packet,bytes_to_send);
#endif

#ifdef HAVE_SSL
	if(ssl){
		complete_SSL_shutdown( ssl);
		SSL_free(ssl);
		}
#endif

	/* log info to syslog facility */
	if(debug==TRUE)
		syslog(LOG_DEBUG,"Return Code: %d, Output: %s",result,buffer);

	return;
        }
Пример #20
0
/*
 * Fetches the resource denoted by |uri|.
 */
static void fetch_uri(const struct URI *uri)
{
  nghttp2_session_callbacks callbacks;
  int fd;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  struct Request req;
  struct Connection connection;
  int rv;
  nfds_t npollfds = 1;
  struct pollfd pollfds[1];

  request_init(&req, uri);

  setup_nghttp2_callbacks(&callbacks);

  /* Establish connection and setup SSL */
  fd = connect_to(req.host, req.port);
  if(fd == -1) {
    die("Could not open file descriptor");
  }
  ssl_ctx = SSL_CTX_new(SSLv23_client_method());
  if(ssl_ctx == NULL) {
    dief("SSL_CTX_new", ERR_error_string(ERR_get_error(), NULL));
  }
  init_ssl_ctx(ssl_ctx);
  ssl = SSL_new(ssl_ctx);
  if(ssl == NULL) {
    dief("SSL_new", ERR_error_string(ERR_get_error(), NULL));
  }
  /* To simplify the program, we perform SSL/TLS handshake in blocking
     I/O. */
  ssl_handshake(ssl, fd);

  connection.ssl = ssl;
  connection.want_io = IO_NONE;

  /* Send connection header in blocking I/O mode */
  SSL_write(ssl, NGHTTP2_CLIENT_CONNECTION_PREFACE,
            NGHTTP2_CLIENT_CONNECTION_PREFACE_LEN);

  /* Here make file descriptor non-block */
  make_non_block(fd);
  set_tcp_nodelay(fd);

  printf("[INFO] SSL/TLS handshake completed\n");
  rv = nghttp2_session_client_new(&connection.session, &callbacks,
                                  &connection);
  if(rv != 0) {
    diec("nghttp2_session_client_new", rv);
  }

  /* Submit the HTTP request to the outbound queue. */
  submit_request(&connection, &req);

  pollfds[0].fd = fd;
  ctl_poll(pollfds, &connection);

  /* Event loop */
  while(nghttp2_session_want_read(connection.session) ||
        nghttp2_session_want_write(connection.session)) {
    int nfds = poll(pollfds, npollfds, -1);
    if(nfds == -1) {
      dief("poll", strerror(errno));
    }
    if(pollfds[0].revents & (POLLIN | POLLOUT)) {
      exec_io(&connection);
    }
    if((pollfds[0].revents & POLLHUP) || (pollfds[0].revents & POLLERR)) {
      die("Connection error");
    }
    ctl_poll(pollfds, &connection);
  }

  /* Resource cleanup */
  nghttp2_session_del(connection.session);
  SSL_shutdown(ssl);
  SSL_free(ssl);
  SSL_CTX_free(ssl_ctx);
  shutdown(fd, SHUT_WR);
  close(fd);
  request_free(&req);
}
Пример #21
0
/* No SSL_writev() provided by OpenSSL. Boo. */  
int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees)
{
	int rc = 0;
	int i;
	char *ptr;
	iobuf iovec;
	int sslerror;

	FUNC_ENTRY;
	iovec.iov_len = buf0len;
	for (i = 0; i < count; i++)
		iovec.iov_len += buflens[i];

	ptr = iovec.iov_base = (char *)malloc(iovec.iov_len);  
	memcpy(ptr, buf0, buf0len);
	ptr += buf0len;
	for (i = 0; i < count; i++)
	{
		memcpy(ptr, buffers[i], buflens[i]);
		ptr += buflens[i];
	}

	SSL_lock_mutex(&sslCoreMutex);
	if ((rc = SSL_write(ssl, iovec.iov_base, iovec.iov_len)) == iovec.iov_len)
		rc = TCPSOCKET_COMPLETE;
	else 
	{ 
		sslerror = SSLSocket_error("SSL_write", ssl, socket, rc);
		
		if (sslerror == SSL_ERROR_WANT_WRITE)
		{
			int* sockmem = (int*)malloc(sizeof(int));
			int free = 1;

			Log(TRACE_MIN, -1, "Partial write: incomplete write of %d bytes on SSL socket %d",
				iovec.iov_len, socket);
			SocketBuffer_pendingWrite(socket, ssl, 1, &iovec, &free, iovec.iov_len, 0);
			*sockmem = socket;
			ListAppend(s.write_pending, sockmem, sizeof(int));
			FD_SET(socket, &(s.pending_wset));
			rc = TCPSOCKET_INTERRUPTED;
		}
		else 
			rc = SOCKET_ERROR;
	}
	SSL_unlock_mutex(&sslCoreMutex);

	if (rc != TCPSOCKET_INTERRUPTED)
		free(iovec.iov_base);
	else
	{
		int i;
		free(buf0);
		for (i = 0; i < count; ++i)
		{
			if (frees[i])
				free(buffers[i]);
		}	
	}
	FUNC_EXIT_RC(rc); 
	return rc;
}
Пример #22
0
void child_cycle(int channel)
{
    int message = 0;
    int result = 0;
    int local_socket = 0;
    int remote_socket = 0;
    struct sockaddr_in my_addr, peer_addr;
    socklen_t peer_addr_size = 0;

    memset(&my_addr, 0, sizeof(struct sockaddr_in));
    memset(&peer_addr, 0, sizeof(struct sockaddr_in));
    /*
     * Do the TLS initialization dance.
     */
    result = ssl_server_init();
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Create a unix socket
     */
    local_socket = socket(AF_INET, SOCK_STREAM, 0);
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = INADDR_ANY;
    my_addr.sin_port = htons(8035);
    /* Avoid spurious failures when rerunning the test due to socket not yet
     * being released. */
    int opt = 1;
    setsockopt(local_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    /*
     * Bind it
     */
    result = bind(local_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Start listening for connections
     */
    result = listen(local_socket, 5);
    if (result < 0)
    {
        message = -1;
        result = write(channel, &message, sizeof(int));
        exit(0);
    }
    /*
     * Signal the parent that we are ok.
     */
    result = write(channel, &message, sizeof(int));
    /*
     * If this did not work, then we abort.
     */
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Send the name of the public key file.
     */
    result = write(channel, server_name_template_public, strlen(server_name_template_public));
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Send the name of the certificate file.
     */
    result = write(channel, server_certificate_template_public, strlen(server_certificate_template_public));
    if (result < 0)
    {
        exit(0);
    }
    /*
     * Now wait until somebody calls.
     */
    peer_addr_size = sizeof(struct sockaddr_in);
    while (true)
    {
        remote_socket = accept(local_socket, (struct sockaddr *)&peer_addr, &peer_addr_size);
        if (remote_socket < 0)
        {
            Log (LOG_LEVEL_CRIT, "Could not accept connection");
            continue;
        }
        /*
         * We are not testing the server, we are testing the functions to send and receive data
         * over TLS. We do not need a full fletched server for that, we just need to send and
         * receive data and try the error conditions.
         */
        SSL *ssl = SSL_new(SSLSERVERCONTEXT);
        if (!ssl)
        {
            Log(LOG_LEVEL_CRIT, "Could not create SSL structure on the server side");
            SSL_free(ssl);
            close (remote_socket);
            remote_socket = -1;
            continue;
        }
        SSL_set_fd(ssl, remote_socket);
        result = SSL_accept(ssl);
        if (result < 0)
        {
            Log(LOG_LEVEL_CRIT, "Could not accept a TLS connection");
            close (remote_socket);
            remote_socket = -1;
            continue;
        }
        /*
         * Our mission is pretty simple, receive data and send it back.
         */
        int received = 0;
        int sent = 0;
        char buffer[4096];
        do {
            received = SSL_read(ssl, buffer, 4096);
            if (received < 0)
            {
                Log(LOG_LEVEL_CRIT, "Failure while receiving data over TLS");
                break;
            }
            sent = SSL_write(ssl, buffer, received);
            if (sent < 0)
            {
                Log(LOG_LEVEL_CRIT, "Failure while sending data over TLS");
                break;
            }
        } while (received > 0);
        /*
         * Mission completed, start again.
         */
        SSL_shutdown(ssl);
        SSL_free(ssl);
        remote_socket = -1;
    }
    exit(0);
}
Пример #23
0
void handle_write_result(struct npool *ms, struct nevent *nse, enum nse_status status) {
  int bytesleft;
  char *str;
  int res;
  int err;
  struct niod *iod = nse->iod;

  if (status == NSE_STATUS_TIMEOUT || status == NSE_STATUS_CANCELLED) {
    nse->event_done = 1;
    nse->status = status;
  } else if (status == NSE_STATUS_SUCCESS) {
    str = fs_str(&nse->iobuf) + nse->writeinfo.written_so_far;
    bytesleft = fs_length(&nse->iobuf) - nse->writeinfo.written_so_far;
    if (nse->writeinfo.written_so_far > 0)
      assert(bytesleft > 0);
#if HAVE_OPENSSL
    if (iod->ssl)
      res = SSL_write(iod->ssl, str, bytesleft);
    else
#endif
      if (nse->writeinfo.dest.ss_family == AF_UNSPEC)
        res = send(nse->iod->sd, str, bytesleft, 0);
      else
        res = sendto(nse->iod->sd, str, bytesleft, 0, (struct sockaddr *)&nse->writeinfo.dest, (int)nse->writeinfo.destlen);
    if (res == bytesleft) {
      nse->event_done = 1;
      nse->status = NSE_STATUS_SUCCESS;
    } else if (res >= 0) {
      nse->writeinfo.written_so_far += res;
    } else {
      assert(res == -1);
      if (iod->ssl) {
#if HAVE_OPENSSL
        err = SSL_get_error(iod->ssl, res);
        if (err == SSL_ERROR_WANT_READ) {
          int evclr;

          evclr = socket_count_dec_ssl_desire(nse);
          socket_count_read_inc(iod);
          update_events(iod, ms, EV_READ, evclr);
          nse->sslinfo.ssl_desire = err;
        } else if (err == SSL_ERROR_WANT_WRITE) {
          int evclr;

          evclr = socket_count_dec_ssl_desire(nse);
          socket_count_write_inc(iod);
          update_events(iod, ms, EV_WRITE, evclr);
          nse->sslinfo.ssl_desire = err;
        } else {
          /* Unexpected error */
          nse->event_done = 1;
          nse->status = NSE_STATUS_ERROR;
          nse->errnum = EIO;
        }
#endif
      } else {
        err = socket_errno();
        if (errcode_is_failure(err)) {
          nse->event_done = 1;
          nse->status = NSE_STATUS_ERROR;
          nse->errnum = err;
        }
      }
    }

    if (res >= 0)
      nse->iod->write_count += res;
  }

  if (nse->event_done && nse->iod->sd != -1) {
    int ev = EV_NONE;

#if HAVE_OPENSSL
    if (nse->iod->ssl != NULL)
      ev |= socket_count_dec_ssl_desire(nse);
    else
#endif
      ev |= socket_count_write_dec(nse->iod);
    update_events(nse->iod, ms, EV_NONE, ev);
  }
}
Пример #24
0
int main(int argc, char *argv[])
{
	if(argc != 2)
	{
		printf("usage : %s <ipaddress>\n", argv[0]);
		return -1;
	}
	strcpy(server_address, argv[1]);
	sleep_us(500000);

	/*
	 * configure the client.
	 */
	if(client_configure(master_port, transmit_port, ssl_certificate, ssl_key) < 0)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "client configured");
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", "client configured");
	sleep_us(500000);

	/* 
	 * initialize the SSL
	 */
	ctx_server = ssl_server_init(ssl_certificate, ssl_key);
	if(ctx_server == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL server initialize");
		return -1;
	}
	ctx_client = ssl_client_init();
	if(ctx_client == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "SSL client initialize");
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", "SSL initialize");
	sleep_us(500000);

	/*
	 * connect to the master server.
	 */
	char temp[MAXLINE];
	snprintf(temp, MAXLINE, "connect to master server: %s", argv[1]);
	int masterfd = client_connect(argv[1], master_port);
	if(masterfd == -1)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", temp);
		return -1;
	}
	sockaddr_in clientaddr;
	socklen_t len = sizeof(clientaddr);
	memset(&clientaddr, 0, len);
	getsockname(masterfd, (sockaddr*)&clientaddr, &len);
	inet_ntop(AF_INET, (void *)&clientaddr.sin_addr, ip_address, MAXLINE);

	printf("%-60s[\033[;32mOK\033[0m]\n", temp);
	sleep_us(500000);
	SSL *ssl = ssl_client(ctx_client, masterfd);
	if(ssl == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "ssl_client\n");
		return -1;
	}

	/*
	 * verify the executable client to judge if it's a fake one.
	 */
	char *ver_buf = file_verify(argv[0]);
	if(ver_buf == NULL)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client");
		return -1;
	}
	int k = SSL_write(ssl, ver_buf, strlen(ver_buf));
	if( k != (int)strlen(ver_buf))
	{
		printf("SSL_write error\n");
		return -1;
	}
	k = SSL_read(ssl, temp, MAXLINE);
	if(k < 0)
	{
		printf("SSL_read error");
		return -1;
	}
	temp[k] = '\0';

	if(strcmp(temp, "verify client unsuccessfully") == 0)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", "verify client");
		return -1;
	}
	free(ver_buf);

	sleep_us(500000);
	
	/*
	 * Listen to the transmit port to upload/download files
	 */
	
	snprintf(temp, MAXLINE, "listen to transmit port: %s", transmit_port);
	int listenfd = server_listen(transmit_port);
	if(listenfd == -1)
	{
		printf("%-60s[\033[;31mFAILED\033[0m]\n", temp);
		return -1;
	}
	printf("%-60s[\033[;32mOK\033[0m]\n", temp);
	sleep_us(500000);
	
	/*
	 * create transmit_thread to handle upload/download files request 
	 * from the slave server.
	 */
	
	pthread_t thread;
	int ret = pthread_create(&thread, NULL, transmit_thread, static_cast<void*>(new int(listenfd)));
	if(ret == 0)
	     printf("%-60s[\033[;32mOK\033[0m]\n", "transmit_thread create");
	else
	{
		printf("%-60s[\033[;31FAILED\033[0m]\n", "transmit_thread create");
		return -1;
	}
	
	/*
	 * initialize the download/upload mutex.
	 */
	pthread_mutex_init(&download_mutex, NULL);
	pthread_mutex_init(&upload_mutex, NULL);
	char command_line[MAXLINE];
	snprintf(cmd_line, MAXLINE,"%s:%s> ", argv[1], master_port);
	while(!stop)
	{
		printf(cmd_line);
		fflush(stdin);
		//read the command inputed by the user.
		fgets(command_line, MAXLINE, stdin);
		int len = strlen(command_line);
		if(command_line[len-1] == '\n')
			command_line[len-1] = '\0';
		command_parse(ssl, command_line);
	}
	
	SSL_shutdown(ssl); // send SSL/TLS close_notify */
	close(masterfd);

	SSL_free(ssl);
	SSL_CTX_free(ctx_server);
	SSL_CTX_free(ctx_client);
	return 0;
}
Пример #25
0
int main(int argc, char **argv)
{
    int c;
    int sock = 0, portnum, ret = 0;
    char *host = NULL, *port = "443";
    SSL_CTX *ctx;
    SSL *ssl;
    SSL_METHOD *sslmeth;
    BIO *sbio;
    BIO *bio_err = 0;

    while ((c = getopt(argc, argv, "h:p:")) != -1) {
        switch (c) {
            case 'h':
                host = optarg;
                break;
            case 'p':
                portnum = atoi(optarg);
                if (portnum <= 0 || portnum >= 65536) {
                    exit(1);
                }
                port = optarg;
                break;
            default:
                exit(1);
                break;
        }
    }

    if (!bio_err) {
        SSL_library_init();
        SSL_load_error_strings();
        OpenSSL_add_all_algorithms();
        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
    }

    sslmeth = SSLv23_method();
    ctx = SSL_CTX_new(sslmeth);
    if (!ctx) {
        printf("CTX ERROR\n");
        exit(1);
    }

    if (!host) {
        printf("ERROR - host not set.\n");
        exit(1);
    }

    /* Connect via TCP */
    sock = OS_ConnectTCP(port, host);
    if (sock <= 0) {
        printf("connect error\n");
        exit(1);
    }

    /* Connect the SSL socket */
    ssl = SSL_new(ctx);
    sbio = BIO_new_socket(sock, BIO_NOCLOSE);
    SSL_set_bio(ssl, sbio, sbio);
    ret = SSL_connect(ssl);
    if (ret <= 0) {
        printf("SSL connect error\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    printf("Connected!\n");

    ret = SSL_write(ssl, TEST, sizeof(TEST));
    if (ret < 0) {
        printf("SSL write error\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    while (1) {
        char buf[2048];
        ret = SSL_read(ssl, buf, sizeof(buf) - 1);
        printf("ret: %d\n", ret);
        switch (SSL_get_error(ssl, ret)) {
            case SSL_ERROR_NONE:
                buf[ret] = '\0';
                printf("no error: %s\n", buf);
                break;
            case SSL_ERROR_ZERO_RETURN:
                printf("no return\n");
                exit(1);
                break;
            case SSL_ERROR_SYSCALL:
                fprintf(stderr,
                        "SSL Error: Premature close\n");
                exit(1);
                break;
            default:
                printf("default error\n");
                exit(1);
                break;
        }

    }

    exit(0);
}
Пример #26
0
// accept transmit request from the slave server.
void *transmit_thread(void *arg)
{
	int transmitfd = *static_cast<int*>(arg);
	delete static_cast<int*>(arg);
	pthread_t thread;
	// accept the download/upload request from the slave server.
	while(!stop)
	{
		int slave_fd = accept(transmitfd, NULL, NULL);
		if(slave_fd < 0)
		{
			err_ret("transmit_thread: accept error");
			continue;
		}
		SSL *ssl = ssl_server(ctx_server, slave_fd);
		if(ssl == NULL)
		{
			close(slave_fd);
			err_msg("transmit_thread: ssl_server error");
			continue;
		}
		char message[MAXLINE + 1];
		int n = SSL_read(ssl, message, MAXLINE);
		message[n] = '\0';
		char command[MAXLINE], file_name[MAXLINE];
		long long file_size;
		int k = sscanf(message,"%s%s%lld", command, file_name, &file_size);

		bool exist = false;
		if(strcmp(command, "upload") == 0)
		{
			if(k != 2)
			{
				SSL_write(ssl, "ERR", strlen("ERR"));
				SSL_shutdown(ssl);
				close(slave_fd);
				SSL_free(ssl);
				err_msg("transmit_thread: wrong command");
				continue;
			}
			// find whether the upload job exist.
			pthread_mutex_lock(&upload_mutex);
			unordered_map<string, record>::iterator iter = upload_array.find(file_name);
		    if(iter != upload_array.end())
				exist = true;
			pthread_mutex_unlock(&upload_mutex);
			if(exist)
			{
 				transmit_arg *down_arg = new transmit_arg(slave_fd, ssl, iter, file_name);
				pthread_create(&thread, NULL, upload_thread, (void *)down_arg);
			}
			else
			{
 				SSL_write(ssl, "ERR", strlen("ERR"));
				SSL_shutdown(ssl);
				close(slave_fd);
				SSL_free(ssl);
				err_msg("transmit_thread:  upload file not found.");  
			}

		}
		else if(strcmp(command, "download") == 0)
		{
			if(k != 3)
			{
  				SSL_shutdown(ssl);
				close(slave_fd);  
				SSL_free(ssl);
				err_msg("transmit_thread: wrong command");
				continue; 
			}
			// find whether the download job exist.
			pthread_mutex_lock(&download_mutex);
			unordered_map<string, record>::iterator iter = download_array.find(file_name);
			if(iter != download_array.end())
			{
				iter->second.sum =  file_size; 
  				exist = true;  
			}
			pthread_mutex_unlock(&download_mutex);
			if(exist)
			{
 				transmit_arg *up_arg = new transmit_arg(slave_fd, ssl, iter, file_name);
 				pthread_create(&thread, NULL, download_thread, (void *)up_arg);
			}
		}
		else
		{  
			// unrecoginized command.
			SSL_shutdown(ssl);
		    close(slave_fd);
			SSL_free(ssl);
			err_msg("transmit_thread: wrong command");
		}
	}
	return NULL;
}
void echoclient_test(void* args)
{
    SOCKET_T sockfd = 0;

    FILE* fin  = stdin;
    FILE* fout = stdout;

    int inCreated  = 0;
    int outCreated = 0;

    char send[1024];
    char reply[1024];

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    int doDTLS = 0;
    int sendSz;
    int argc    = 0;
    char** argv = 0;

    ((func_args*)args)->return_code = -1; /* error state */
    argc = ((func_args*)args)->argc;
    argv = ((func_args*)args)->argv;

    if (argc >= 2) {
        fin  = fopen(argv[1], "r"); 
        inCreated = 1;
    }
    if (argc >= 3) {
        fout = fopen(argv[2], "w");
        outCreated = 1;
    }

    if (!fin)  err_sys("can't open input file");
    if (!fout) err_sys("can't open output file");

#ifdef CYASSL_DTLS
    doDTLS  = 1;
#endif

    tcp_connect(&sockfd, yasslIP, yasslPort, doDTLS);

#if defined(CYASSL_DTLS)
    method  = DTLSv1_client_method();
#elif  !defined(NO_TLS)
    method = CyaSSLv23_client_method();
#else
    method = SSLv3_client_method();
#endif
    ctx    = SSL_CTX_new(method);

#ifndef NO_FILESYSTEM
    if (SSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS)
        err_sys("can't load ca file, Please run from CyaSSL home dir");
    #ifdef HAVE_ECC
        if (SSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    #endif
#else
    load_buffer(ctx, caCert, CYASSL_CA);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
#endif

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif
    ssl = SSL_new(ctx);

    SSL_set_fd(ssl, sockfd);
#if defined(USE_WINDOWS_API) && defined(CYASSL_DTLS) && defined(NO_MAIN_DRIVER)
    /* let echoserver bind first, TODO: add Windows signal like pthreads does */
    Sleep(100);
#endif
    if (SSL_connect(ssl) != SSL_SUCCESS) err_sys("SSL_connect failed");

    while (fgets(send, sizeof(send), fin)) {

        sendSz = (int)strlen(send);

        if (SSL_write(ssl, send, sendSz) != sendSz)
            err_sys("SSL_write failed");

        if (strncmp(send, "quit", 4) == 0) {
            fputs("sending server shutdown command: quit!\n", fout);
            break;
        }

        if (strncmp(send, "break", 5) == 0) {
            fputs("sending server session close: break!\n", fout);
            break;
        }

        while (sendSz) {
            int got;
            if ( (got = SSL_read(ssl, reply, sizeof(reply))) > 0) {
                reply[got] = 0;
                fputs(reply, fout);
                sendSz -= got;
            }
            else
                break;
        }
    }

#ifdef CYASSL_DTLS
    strncpy(send, "break", 6);
    sendSz = (int)strlen(send);
    /* try to tell server done */
    SSL_write(ssl, send, sendSz);
#else
    SSL_shutdown(ssl);
#endif

    SSL_free(ssl);
    SSL_CTX_free(ctx);

    fflush(fout);
    if (inCreated)  fclose(fin);
    if (outCreated) fclose(fout);

    CloseSocket(sockfd);
    ((func_args*)args)->return_code = 0; 
}
Пример #28
0
static int tls_drv_control(ErlDrvData handle,
			   unsigned int command,
			   char *buf, int len,
			   char **rbuf, int rlen)
{
   tls_data *d = (tls_data *)handle;
   int res;
   int size;
   ErlDrvBinary *b;

   switch (command)
   {
      case SET_CERTIFICATE_FILE:
	 d->ctx = SSL_CTX_new(SSLv23_server_method());
	 die_unless(d->ctx, "SSL_CTX_new failed");

	 res = SSL_CTX_use_certificate_chain_file(d->ctx, buf);
	 die_unless(res > 0, "ssl_ctx_use_certificate_chain_file failed");

	 res = SSL_CTX_use_PrivateKey_file(d->ctx, buf, SSL_FILETYPE_PEM);
	 die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed");

	 res = SSL_CTX_check_private_key(d->ctx);
	 die_unless(res > 0, "SSL_CTX_check_private_key failed");

	 d->ssl = SSL_new(d->ctx);
	 die_unless(d->ssl, "SSL_new failed");

	 d->bio_read = BIO_new(BIO_s_mem());
	 d->bio_write = BIO_new(BIO_s_mem());

	 SSL_set_bio(d->ssl, d->bio_read, d->bio_write);

	 SSL_set_accept_state(d->ssl);
	 break;
      case SET_ENCRYPTED_INPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 BIO_write(d->bio_read, buf, len);
	 break;
      case SET_DECRYPTED_OUTPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 res = SSL_write(d->ssl, buf, len);
	 break;
      case GET_ENCRYPTED_OUTPUT:
	 die_unless(d->ssl, "SSL not initialized");
	 size = BUF_SIZE + 1;
	 rlen = 1;
	 b = driver_alloc_binary(size);
	 b->orig_bytes[0] = 0;
	 while ((res = BIO_read(d->bio_write,
				b->orig_bytes + rlen, BUF_SIZE)) > 0)
	 {
	    //printf("%d bytes of encrypted data read from state machine\r\n", res);

	    rlen += res;
	    size += BUF_SIZE;
	    b = driver_realloc_binary(b, size);
	 }
	 b = driver_realloc_binary(b, rlen);
	 *rbuf = (char *)b;
	 return rlen;
      case GET_DECRYPTED_INPUT:
	 if (!SSL_is_init_finished(d->ssl))
	 {
	    //printf("Doing SSL_accept\r\n");
	    res = SSL_accept(d->ssl);
	    //if (res == 0)
	    //   printf("SSL_accept returned zero\r\n");
	    if (res < 0)
	       die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ,
			  "SSL_accept failed");
	 } else {
	    size = BUF_SIZE + 1;
	    rlen = 1;
	    b = driver_alloc_binary(size);
	    b->orig_bytes[0] = 0;

	    while ((res = SSL_read(d->ssl,
				   b->orig_bytes + rlen, BUF_SIZE)) > 0)
	    {
	       //printf("%d bytes of decrypted data read from state machine\r\n",res);
	       rlen += res;
	       size += BUF_SIZE;
	       b = driver_realloc_binary(b, size);
	    }

	    if (res < 0)
	    {
	       int err = SSL_get_error(d->ssl, res);

	       if (err == SSL_ERROR_WANT_READ)
	       {
		  //printf("SSL_read wants more data\r\n");
		  //return 0;
	       }
	       // TODO
	    }
	    b = driver_realloc_binary(b, rlen);
	    *rbuf = (char *)b;
	    return rlen;
	 }
	 break;
   }

   b = driver_alloc_binary(1);
   b->orig_bytes[0] = 0;
   *rbuf = (char *)b;
   return 1;
}
Пример #29
0
int rocksock_ssl_send(rocksock* sock, char* buf, size_t sz) {
        int ret = SSL_write(sock->ssl, buf, sz);
        if (ret < 0 && SSL_get_error(sock->ssl, ret) == SSL_ERROR_WANT_WRITE) errno = EWOULDBLOCK;
        return ret;
}
Пример #30
0
int32_t CSSLClientAsync::SendMsgAsync(const char *szBuf, int32_t nBufSize)
{
    CSimpleBuffer* pBufferLoop = new CSimpleBuffer();
    pBufferLoop->Write(szBuf, nBufSize);
    
    m_sendqueuemutex.Lock();
    if (m_sendqueue.size() != 0)
    {
        if (_GetWaitForCloseStatus() == TRUE)
        {
            SOCKET_IO_DEBUG("send ssl data error, socket will be closed.");
            delete pBufferLoop;
            pBufferLoop = NULL;
        }
        else
        {
            if (m_sendqueue.size() >= MAX_SEND_QUEUE_SIZE) {
                SOCKET_IO_WARN("send ssl data error, buffer is overload.");
                delete pBufferLoop;
                pBufferLoop = NULL;
            }
            else
            {
                SOCKET_IO_INFO("send ssl data, push data to buffer.");
                m_sendqueue.push(pBufferLoop);
                //m_pio->Add_WriteEvent(this);
            }
        }
        m_sendqueuemutex.Unlock();
        return SOCKET_IO_RESULT_OK;
    }
    m_sendqueuemutex.Unlock();
    
    int32_t nRet = SSL_write(GetSSL(), (void*)pBufferLoop->GetBuffer(), pBufferLoop->GetWriteOffset());
    if ( nRet < 0)
    {
        int32_t nError = SSL_get_error(GetSSL(), nRet);
        if (SSL_ERROR_WANT_WRITE == nError || SSL_ERROR_WANT_READ == nError)
        {
            m_sendqueuemutex.Lock();
            m_sendqueue.push(pBufferLoop);
            m_sendqueuemutex.Unlock();
            //有数据放入待发送队列,则注册为写事件
            m_pio->Add_WriteEvent(this);
            SOCKET_IO_INFO("send ssl data, buffer is blocking, errno: %d.", nError);
        }
        else
        {
            delete pBufferLoop;
            pBufferLoop = NULL;
            SOCKET_IO_ERROR("send ssl data error, errno: %d.", nError);
            DoException(GetSocketID(), SOCKET_IO_SSL_SEND_FAILED);
        }
    }
    else if (nRet == 0)
    {
        int32_t nError = SSL_get_error(GetSSL(), nRet);
        if (SSL_ERROR_ZERO_RETURN == nError)
        {
            SOCKET_IO_WARN("send ssl data error, peer closed.");
        }
        else
        {
            SOCKET_IO_ERROR("send ssl data error, errno: %d.", nError);
        }
        delete pBufferLoop;
        pBufferLoop = NULL;
        DoException(GetSocketID(), SOCKET_IO_SSL_SEND_FAILED);
    }
    else if (nRet != nBufSize)
    {
        int32_t nRest = nBufSize - nRet;
        pBufferLoop->Read(NULL, nRet);
        m_sendqueuemutex.Lock();
        m_sendqueue.push(pBufferLoop);
        m_sendqueuemutex.Unlock();
        //有数据放入待发送队列,则注册为写事件
        //对于ssl来说,应该不会出现此种情况
        m_pio->Add_WriteEvent(this);
        SOCKET_IO_WARN("send ssl data, send size: %d, less than %d.", nRet, nBufSize);
    }
    else if (nRet == nBufSize)
    {
        delete pBufferLoop;
        pBufferLoop = NULL;
        SOCKET_IO_DEBUG("send ssl data successed.");
    }
    else
    {
        delete pBufferLoop;
        pBufferLoop = NULL;
    }
    return SOCKET_IO_RESULT_OK;
}