On Tue, 20 Apr 2010, Ondrej Jombik wrote:

Tommorow, I will post here a simple snipet of code, as others may find
it also useful, somewhere in the future.

Here is simple code snippet for binding local address to socket and
passing it to SSL. Save it into file ssltest.c and compile with:

    gcc -pedantic -Wall -o ssltest ssltest.c -lssl

Thank you for your help!

CODE follows:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define REMOTE_ADDRESS "85.248.229.194"
#define LOCAL_ADDRESS "" /* put your address here */
#define BUFSIZE 512

int main(void) /* {{{ */
{
        register int ret, sockfd;
        char buffer[BUFSIZE];
        struct sockaddr_in cliaddr, servaddr;
        SSL_CTX *ctx;
        SSL *ssl;
        BIO *sbio;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
                perror("socket() error");
                return 1;
        }

        if (LOCAL_ADDRESS != NULL && strlen(LOCAL_ADDRESS) > 0) {
                memset(&cliaddr, 0, sizeof(cliaddr));
                cliaddr.sin_family = AF_INET;
                inet_pton(AF_INET, LOCAL_ADDRESS, &cliaddr.sin_addr);
                cliaddr.sin_port = htons(0); /* any outgoing port */

                if (bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) 
< 0) {
                        perror("bind() error");
                        return 2;
                }
        }

        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        inet_pton(AF_INET, REMOTE_ADDRESS, &servaddr.sin_addr);
        servaddr.sin_port = htons(443); /* HTTPS */

        if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 
0) {
                perror("connect() error");
                return 4;
        }

        /* SSL initialization */
        ERR_load_crypto_strings();
        ERR_load_SSL_strings();
        OpenSSL_add_all_algorithms();
        SSL_library_init();

        ctx = SSL_CTX_new(SSLv23_client_method());

        if ((ssl = SSL_new(ctx)) == NULL) {
                fprintf(stderr, "SSL_new() error\n");
                return 8;
        }

        SSL_set_connect_state(ssl);
        SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
        SSL_set_read_ahead(ssl, 1);

        if (SSL_set_fd(ssl, sockfd) != 1) {
                fprintf(stderr, "SSL_set_fd() error\n");
                return 16;
        }

        if (SSL_connect(ssl) != 1) {
                fprintf(stderr, "SSL_connect() error\n");
                return 32;
        }

        sbio = BIO_new(BIO_f_ssl());
        BIO_set_ssl(sbio, ssl, BIO_NOCLOSE);
    BIO_set_nbio(sbio, 1);

        BIO_puts(sbio, "GET /getip.php HTTP/1.1\n");
        BIO_puts(sbio, "Host: wolcano.platon.sk\n\n");

        /* This is for non-blocking I/O
         * It is similar to BIO_set_nbio(sbio, 1)
         */
        fcntl(sockfd, F_SETFL, O_NONBLOCK);

        while (1) {
                ret = BIO_read(sbio, buffer, BUFSIZE - 1);
                fprintf(stderr, "ret=%d\n", ret);
                if (ret > 0) {
                        buffer[ret] = '\0';
                        puts(buffer);
                }
                sleep(1);
        }

        return 0;
} /* }}} */

--
Ondrej JOMBIK
Platon Technologies Ltd., Hlavna 3, Sala SK-92701
+421 903 PLATON - i...@platon.org - http://platon.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to