Example #1
0
Octstr *conn_read_line(Connection *conn)
{
    Octstr *result = NULL;
    long pos;

    lock_in(conn);
    /* 10 is the code for linefeed.  We don't rely on \n because that
     * might be a different value on some (strange) systems, and
     * we are reading from a network connection. */
    pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
    if (pos < 0) {
        unlocked_read(conn);
        pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
        if (pos < 0) {
            unlock_in(conn);
            return NULL;
        }
    }

    result = unlocked_get(conn, pos - conn->inbufpos);
    gw_claim_area(result);

    /* Skip the LF, which we left in the buffer */
    conn->inbufpos++;

    /* If the line was terminated with CR LF, we have to remove
     * the CR from the result. */
    if (octstr_len(result) > 0 &&
        octstr_get_char(result, octstr_len(result) - 1) == 13)
        octstr_delete(result, octstr_len(result) - 1, 1);

    unlock_in(conn);
    return result;
}
Example #2
0
int read_from_bearerbox_real(Connection *conn, Msg **msg, double seconds)
{
    int ret;
    Octstr *pack;

    pack = NULL;
    *msg = NULL;
    while (program_status != shutting_down) {
        pack = conn_read_withlen(conn);
        gw_claim_area(pack);
        if (pack != NULL)
            break;

        if (conn_error(conn)) {
            error(0, "Error reading from bearerbox, disconnecting.");
            return -1;
        }
        if (conn_eof(conn)) {
            error(0, "Connection closed by the bearerbox.");
            return -1;
        }

        ret = conn_wait(conn, seconds);
        if (ret < 0) {
            error(0, "Connection to bearerbox broke.");
            return -1;
        }
        else if (ret == 1) {
            /* debug("gwlib.gwlib", 0, "Connection to bearerbox timed out after %.2f seconds.", seconds); */
            return 1;
        }
    }

    if (pack == NULL)
        return -1;

    *msg = msg_unpack(pack);
    octstr_destroy(pack);

    if (*msg == NULL) {
        error(0, "Failed to unpack data!");
        return -1;
    }

    return 0;
}
Example #3
0
Octstr *conn_read_everything(Connection *conn)
{
    Octstr *result = NULL;

    lock_in(conn);
    if (unlocked_inbuf_len(conn) == 0) {
        unlocked_read(conn);
        if (unlocked_inbuf_len(conn) == 0) {
            unlock_in(conn);
            return NULL;
        }
    }

    result = unlocked_get(conn, unlocked_inbuf_len(conn));
    gw_claim_area(result);
    unlock_in(conn);

    return result;
}
Example #4
0
static Msg *read_from_box(Boxc *boxconn)
{
    int ret;
    Octstr *pack;
    Msg *msg;

    pack = NULL;
    while (bb_status != BB_DEAD && boxconn->alive) {
            /* XXX: if box doesn't send (just keep conn open) we block here while shutdown */
	    pack = conn_read_withlen(boxconn->conn);
	    gw_claim_area(pack);
	    if (pack != NULL)
	        break;
	    if (conn_error(boxconn->conn)) {
	        info(0, "Read error when reading from box <%s>, disconnecting",
		         octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }
	    if (conn_eof(boxconn->conn)) {
	        info(0, "Connection closed by the box <%s>",
		         octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }

	    ret = conn_wait(boxconn->conn, -1.0);
	    if (ret < 0) {
	        error(0, "Connection to box <%s> broke.",
		          octstr_get_cstr(boxconn->client_ip));
	        return NULL;
	    }
    }

    if (pack == NULL)
    	return NULL;

    msg = msg_unpack(pack);
    octstr_destroy(pack);

    if (msg == NULL)
	    error(0, "Failed to unpack data!");
    return msg;
}
Example #5
0
Octstr *conn_read_fixed(Connection *conn, long length)
{
    Octstr *result = NULL;

    if (length < 1)
        return NULL;

    /* See if the data is already available.  If not, try a read(),
     * then see if we have enough data after that.  If not, give up. */
    lock_in(conn);
    if (unlocked_inbuf_len(conn) < length) {
        unlocked_read(conn);
        if (unlocked_inbuf_len(conn) < length) {
            unlock_in(conn);
            return NULL;
        }
    }
    result = unlocked_get(conn, length);
    gw_claim_area(result);
    unlock_in(conn);

    return result;
}
Example #6
0
Octstr *conn_read_withlen(Connection *conn)
{
    Octstr *result = NULL;
    unsigned char lengthbuf[4];
    long length = 0; /* for compiler please */
    int try, retry;

    lock_in(conn);

    for (try = 1; try <= 2; try++) {
        if (try > 1)
            unlocked_read(conn);

        do {
            retry = 0;
            /* First get the length. */
            if (unlocked_inbuf_len(conn) < 4)
                continue;

            octstr_get_many_chars(lengthbuf, conn->inbuf, conn->inbufpos, 4);
            length = decode_network_long(lengthbuf);

            if (length < 0) {
                warning(0, "conn_read_withlen: got negative length, skipping");
                conn->inbufpos += 4;
                retry = 1;
             }
        } while(retry == 1);

        /* Then get the data. */
        if (unlocked_inbuf_len(conn) - 4 < length)
            continue;

        conn->inbufpos += 4;
        result = unlocked_get(conn, length);
        gw_claim_area(result);
        break;
    }

    unlock_in(conn);
    return result;
}

Octstr *conn_read_packet(Connection *conn, int startmark, int endmark)
{
    int startpos, endpos;
    Octstr *result = NULL;
    int try;

    lock_in(conn);

    for (try = 1; try <= 2; try++) {
        if (try > 1)
            unlocked_read(conn);

        /* Find startmark, and discard everything up to it */
        if (startmark >= 0) {
            startpos = octstr_search_char(conn->inbuf, startmark, conn->inbufpos);
            if (startpos < 0) {
                conn->inbufpos = octstr_len(conn->inbuf);
                continue;
            } else {
                conn->inbufpos = startpos;
            }
        } else {
           startpos = conn->inbufpos;
        }

        /* Find first endmark after startmark */
        endpos = octstr_search_char(conn->inbuf, endmark, conn->inbufpos);
        if (endpos < 0)
            continue;

        result = unlocked_get(conn, endpos - startpos + 1);
        gw_claim_area(result);
        break;
    }

    unlock_in(conn);
    return result;
}

#ifdef HAVE_LIBSSL
X509 *conn_get_peer_certificate(Connection *conn) 
{
    /* Don't know if it needed to be locked , but better safe as crash */
    lock_out(conn);
    lock_in(conn);
    if (conn->peer_certificate == NULL && conn->ssl != NULL)
        conn->peer_certificate = SSL_get_peer_certificate(conn->ssl);
    unlock_in(conn);
    unlock_out(conn);
    
    return conn->peer_certificate;
}

/*
 * XXX Alex decalred the RSA callback routine static and now we're getting 
 * warning messages for our automatic compilation tests. So we are commenting
 * the function out to avoid the warnings.
 *

static RSA *tmp_rsa_callback(SSL *ssl, int export, int key_len)
{
    static RSA *rsa = NULL;
    debug("gwlib.http", 0, "SSL: Generating new RSA key (export=%d, keylen=%d)", export, key_len);
    if (export) {
	   rsa = RSA_generate_key(key_len, RSA_F4, NULL, NULL);
    } else {
	   debug("gwlib.http", 0, "SSL: Export not set");
    }
    return rsa;
}
*/

static Mutex **ssl_static_locks = NULL;

/* the call-back function for the openssl crypto thread locking */
static void openssl_locking_function(int mode, int n, const char *file, int line)
{
    if (mode & CRYPTO_LOCK)
        mutex_lock(ssl_static_locks[n-1]);
    else
        mutex_unlock(ssl_static_locks[n-1]);
}

void openssl_init_locks(void)
{
    int c, maxlocks = CRYPTO_num_locks();

    gw_assert(ssl_static_locks == NULL);

    ssl_static_locks = gw_malloc(sizeof(Mutex *) * maxlocks);
    for (c = 0; c < maxlocks; c++)
        ssl_static_locks[c] = mutex_create();

    /* after the mutexes have been created, apply the call-back to it */
    CRYPTO_set_locking_callback(openssl_locking_function);
    CRYPTO_set_id_callback((CRYPTO_CALLBACK_PTR)gwthread_self);
}