Exemple #1
0
int conn_tls_start(xmpp_conn_t * const conn)
{
    int rc;

    if (conn->tls_disabled) {
        conn->tls = NULL;
        rc = -ENOSYS;
    } else {
        conn->tls = tls_new(conn->ctx, conn->sock);
        rc = conn->tls == NULL ? -ENOMEM : 0;
    }

    if (conn->tls != NULL) {
        if (tls_start(conn->tls)) {
            conn->secured = 1;
            conn_prepare_reset(conn, auth_handle_open);
        } else {
            rc = tls_error(conn->tls);
            conn->error = rc;
            tls_free(conn->tls);
            conn->tls = NULL;
            conn->tls_failed = 1;
        }
    }
    if (rc != 0)
        xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! error %d", rc);

    return rc;
}
Exemple #2
0
static int _handle_proceedtls_default(xmpp_conn_t * const conn,
			      xmpp_stanza_t * const stanza,
			      void * const userdata)
{
    char *name;
    name = xmpp_stanza_get_name(stanza);
    xmpp_debug(conn->ctx, "xmpp",
	"handle proceedtls called for %s", name);

    if (strcmp(name, "proceed") == 0) {
        xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS");

	conn->tls = tls_new(conn->ctx, conn->sock);

	if (!tls_start(conn->tls))
	{
	    xmpp_debug(conn->ctx, "xmpp", "Couldn't start TLS! error %d", tls_error(conn->tls));
	    tls_free(conn->tls);
	    conn->tls = NULL;
	    conn->tls_failed = 1;

	    /* failed tls spoils the connection, so disconnect */
	    xmpp_disconnect(conn);
	}
	else
	{
            conn->secured = 1;
            conn_prepare_reset(conn, auth_handle_open);

	    conn_open_stream(conn);
	}
    }

    return 0;
}
Exemple #3
0
int conn_tls_start(xmpp_conn_t * const conn)
{
    int rc;

    if (conn->tls_disabled) {
        conn->tls = NULL;
        rc = XMPP_EINVOP;
    } else {
        conn->tls = tls_new(conn);
        rc = conn->tls == NULL ? XMPP_EMEM : 0;
    }

    if (conn->tls != NULL) {
        if (tls_start(conn->tls)) {
            conn->secured = 1;
        } else {
            rc = XMPP_EINT;
            conn->error = tls_error(conn->tls);
            tls_free(conn->tls);
            conn->tls = NULL;
            conn->tls_failed = 1;
        }
    }
    if (rc != 0) {
        xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! "
                   "error %d tls_error %d", rc, conn->error);
    }
    return rc;
}
Exemple #4
0
Fichier : ji.c Projet : placek/ji
static int
start_tls(void *user)
{
  if (!in_tls && use_tls) {
    memset(&tls, 0, sizeof(tls));
    tls.recv = tcp_recv;
    tls.send = tcp_send;
    if (tls_start(&tls))
      return -1;
    in_tls = 1;
  }
  return 0;
}
Exemple #5
0
static int
start_tls(void *user)
{
    struct xmpp *xmpp = (struct xmpp *)user;
    if (!in_tls) {
        memset(&tls, 0, sizeof(tls));
        tls.user = xmpp->io_context;
        tls.recv = tcp_recv;
        tls.send = tcp_send;
        if (tls_start(&tls)) {
            fprintf(stderr, "err: TLS start failure\n");
            return -1;
        }
        in_tls = 1;
    }
    return 0;
}
Exemple #6
0
int tls_read(tls_t *tls, void * const buff, const size_t len)
{
    int bytes;

    /* first, if we've got some ready data, put that in the buffer */
    if (tls->readybufferpos < tls->readybufferlen)
    {
	if (len < tls->readybufferlen - tls->readybufferpos) {
	    bytes = len;
	} else {
	    bytes = tls->readybufferlen - tls->readybufferpos;
	}

	memcpy(buff, tls->readybuffer + tls->readybufferpos, bytes);

	if (len < tls->readybufferlen - tls->readybufferpos) {
	    tls->readybufferpos += bytes;
	    return bytes;
	} else {
	    unsigned char *newbuff = buff;
	    int read;
	    tls->readybufferpos += bytes;
	    newbuff += bytes;
	    read = tls_read(tls, newbuff, len - bytes);

	    if (read == -1) {
	        if (tls_is_recoverable(tls->lasterror)) {
		    return bytes;
		}

		return -1;
	    }

	    return bytes + read;
	}
    }

    /* next, top up our recv buffer */
    bytes = sock_read(tls->sock, tls->recvbuffer + tls->recvbufferpos,
		      tls->recvbuffermaxlen - tls->recvbufferpos);

    if (bytes == 0) {
        tls->lasterror = WSAECONNRESET;
        return -1;
    }

    if (bytes == -1) {
	if (!tls_is_recoverable(sock_error())) {
	    tls->lasterror = sock_error();
	    return -1;
	}
    }

    if (bytes > 0) {
	tls->recvbufferpos += bytes;
    }

    /* next, try to decrypt the recv buffer */
    if (tls->recvbufferpos > 0) {
	SecBufferDesc sbddec;
	SecBuffer sbdec[4];
	int ret;

	memset(&sbddec, 0, sizeof(sbddec));
	sbddec.ulVersion = SECBUFFER_VERSION;
	sbddec.cBuffers = 4;
	sbddec.pBuffers = sbdec;

	memset(&(sbdec[0]), 0, sizeof(sbdec[0]));
	sbdec[0].BufferType = SECBUFFER_DATA;
	sbdec[0].pvBuffer = tls->recvbuffer;
	sbdec[0].cbBuffer = tls->recvbufferpos;

	memset(&(sbdec[1]), 0, sizeof(sbdec[1]));
	sbdec[1].BufferType = SECBUFFER_EMPTY;

	memset(&(sbdec[2]), 0, sizeof(sbdec[2]));
	sbdec[2].BufferType = SECBUFFER_EMPTY;

	memset(&(sbdec[3]), 0, sizeof(sbdec[3]));
	sbdec[3].BufferType = SECBUFFER_EMPTY;

	ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL);

	if (ret == SEC_E_OK) {
	    memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
	    tls->readybufferpos = 0;
	    tls->readybufferlen = sbdec[1].cbBuffer;
	    /* have we got some data left over?  If so, copy it to the start
	     * of the recv buffer */
	    if (sbdec[3].BufferType == SECBUFFER_EXTRA) {
		memcpy(tls->recvbuffer, sbdec[3].pvBuffer, sbdec[3].cbBuffer);
		tls->recvbufferpos = sbdec[3].cbBuffer;
	    } else {
		tls->recvbufferpos = 0;
	    }

	    return tls_read(tls, buff, len);
	} else if (ret == SEC_E_INCOMPLETE_MESSAGE) {
	    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
	    return -1;
	} else if (ret == SEC_I_RENEGOTIATE) {
	    ret = tls_start(tls);
	    if (!ret)
	    {
		return -1;
	    }

	    /* fake an incomplete message so we're called again */
	    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
	    return -1;
	}

	/* something bad happened, so we bail */
	tls->lasterror = ret;

	return -1;
    }

    tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;

    return -1;
}