Exemple #1
0
static void handle_ctcp_request(irc_session_t *session, irc_parser_result_t *result) {
    char ctcp_buf[LIBIRC_BUFFER_SIZE];
    char **params = result->params;
    size_t msglen = strlen(result->params[1]);

    msglen -= 2;
    if (msglen > sizeof (ctcp_buf) - 1)
        msglen = sizeof (ctcp_buf) - 1;

    memcpy(ctcp_buf, params[1] + 1, msglen);
    ctcp_buf[msglen] = '\0';
    DBG_OK("ctcp req recvd! %s", ctcp_buf);

    if (is_dcc_request(ctcp_buf)) {
        libirc_dcc_request(session, result, ctcp_buf);
    }
    else if (is_action_message(ctcp_buf) && session->callbacks.event_ctcp_action) {
        // this removes "ACTION" in front of the message
        char *buf = calloc(strlen(ctcp_buf)+1, sizeof(char));
        memcpy(buf, ctcp_buf+7, strlen(ctcp_buf)-7);
        params[1] = buf; 
        result->num_params = 2;

        (*session->callbacks.event_ctcp_action) (session, "ACTION", result);
    }
    else {
        char *buf = calloc(strlen(ctcp_buf)+1, sizeof(char));
        memcpy(buf, ctcp_buf, strlen(ctcp_buf));
        params[0] = buf;
        result->num_params = 1;

        if (session->callbacks.event_ctcp_req)
            (*session->callbacks.event_ctcp_req) (session, "CTCP", result);
    }
}
Exemple #2
0
static void send_current_file_offset_to_sender (irc_session_t *session, irc_dcc_session_t *dcc) {
    int sentBytes, err = 0;

    // we convert out irc_dcc_size_t to uint32_t, because it's defined like that in dcc...
    uint32_t confirmSizeNetworkOrder = htobe32(dcc->file_confirm_offset);
    size_t offset = sizeof(confirmSizeNetworkOrder);

#ifdef ENABLE_SSL
    if (dcc->ssl == 0)
        sentBytes = socket_send(&dcc->sock, &confirmSizeNetworkOrder, offset);
    else {
        int sslError = 0;
        sentBytes = ssl_write_wrapper(session, dcc, &confirmSizeNetworkOrder, offset, &sslError);

        if (sslError == SSL_ERROR_WANT_READ) {
            dcc->state = LIBIRC_STATE_CONNECTED;
            return;
        }
        else if (sslError == SSL_ERROR_WANT_WRITE) {
            return;
        }
    }
#else
    sentBytes = socket_send(&dcc->sock, &confirmSizeNetworkOrder, offset);
#endif
    if (unlikely(sentBytes < 0)) {
        DBG_WARN("err send length < 0");
        DBG_WARN("error msg: %s\n", strerror(errno));
        err = LIBIRC_ERR_WRITE;
    } else if (unlikely(sentBytes == 0)) {
        err = LIBIRC_ERR_CLOSED;
    } else {
        if (unlikely(dcc->received_file_size == dcc->file_confirm_offset)) {
            DBG_OK("dcc->received_file_size == dcc->file_confirm_offset");
            libirc_mutex_unlock(&session->mutex_dcc);
            (*dcc->cb)(session, dcc->id, 0, dcc->ctx, 0, 0);
			libirc_mutex_lock(&session->mutex_dcc);
            libirc_dcc_destroy_nolock(session, dcc->id);
        } else {
            /* Continue to receive the file */
            dcc->state = LIBIRC_STATE_CONNECTED;
        }
    }

    /*
     * If error arises somewhere above, we inform the caller 
     * of failure, and destroy this session.
     */
    if (unlikely(err)) {
        libirc_mutex_unlock(&session->mutex_dcc);
        (*dcc->cb)(session, dcc->id, err, dcc->ctx, 0, 0);
        libirc_mutex_lock(&session->mutex_dcc);

        //libirc_dcc_destroy_nolock (ircsession, dcc->id);
    }
}
Exemple #3
0
static void optimizeSocketBufferSize(const irc_dcc_session_t *dcc) {
    int bufferSize = 0;
    socklen_t bufSizeLen = sizeof(int);

    getsockopt(dcc->sock, SOL_SOCKET, SO_RCVBUF, &bufferSize, &bufSizeLen);
    bufferSize *= 2;
    bufferSize *= 16;

    DBG_OK("got buffer size of %d!", bufferSize);

    setsockopt(dcc->sock, SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
}
Exemple #4
0
static void accept_dcc_send(irc_session_t * session, const char * nick, const char * req, char *filename, unsigned long ip, irc_dcc_size_t size, unsigned short port, int ssl) {
    DBG_OK("---- got dcc send req: %s ---", req);
    if (session->callbacks.event_dcc_send_req) {
        irc_dcc_session_t * dcc;
        
        int err = libirc_new_dcc_session(session, ip, port, 0, &dcc, ssl);
        if (err) {
            session->lasterror = err;
            return;
        }

        (*session->callbacks.event_dcc_send_req) (session,
                nick,
                inet_ntoa(dcc->remote_addr.sin_addr),
                filename,
                size,
                dcc->id);

        dcc->received_file_size = size;
    }
}
Exemple #5
0
int init_syn_psam(int slot, int baud, u_short adfid, u_char *keyid)
{
	DBG("Init terminal PSAM ...");
	if (init_psam(&pc, slot, baud))
	{
		DBG_NT(" failed to alloc mem!\n");
		return -1;
	}

	int ret = 0;
	if (ret = init_sam_card(pc))
	{
		DBG_NT(" failed, init SAM card!\n");
	}
	else if (init_descrypt_psam(pc, adfid, keyid))
	{
		DBG_NT(" failed, check key!\n");
	}

	if (ret)
	{
		if (pc)
		{
			delete_psam_cos(pc);
			pc = NULL;
		}
		return -1;
	}

	if (check_terminal_type(pc))
	{
		DBG_NT(" failed, terminal type!\n");
		return -1;
	}
	DBG_OK();
	return 0;
}
Exemple #6
0
int irc_dcc_resume(irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback, const char *nick, irc_dcc_size_t filePosition) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }
    dcc->cb = callback;
    dcc->ctx = ctx;

    // ctcp msg to bot
    char buf[512];
    snprintf(buf, sizeof(buf), "DCC RESUME file.ext %hu %" IRC_DCC_SIZE_T_FORMAT "", ntohs(dcc->remote_addr.sin_port), filePosition);
    DBG_OK("%s", buf);
    irc_cmd_ctcp_request(session, nick, buf);
    dcc->state = LIBIRC_STATE_WAITING_FOR_RESUME_ACK;
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;

}
Exemple #7
0
/*
 * adf: YKT app id
 * tsn: terminal code
 */
int init_pbocsam_card(int slot, int baud, char *adf, u_char *tsn)
{
	DBG("Init pboc PSAM...");

	if (NULL == adf || NULL == tsn)
	{
		DBG_NT(" null of AID or Terminal Code!\n");
		return -1;
	}

	if (!pboc)
	{
		if (init_psam(&pboc, slot, baud))
		{
			DBG_NT(" failed to alloc mem!\n");
			goto err;
		}

		if (init_sam_card(pboc))
		{
			DBG_NT(" failed to init SAM card!\n");
			goto free_err;
		}
	}
	else if (reset_psam_card(pboc))
	{
		DBG_NT(" failed to reset SAM card!\n");
		goto err;
	}

	if (psam_factory(pboc) == -1)
	{
		DBG_NT("Unknow PBOC SAM card!\n");
		goto free_err;
	}

	/* Check terminal serial that saved in PSAM */
	int ret;
	if (-1 == (ret = psam_read_binary(pboc, &resp, PBOC_TERM_FID, 0, 
		PBOC_TERM_FLEN)))
	{
		DBG_NT(" Read terminal info file error!\n");
		return -1;
	}
	/* DBG_MEM("PSAM PBOC tsn:", resp, ret); */

	if (memcmp(tsn, resp, PBOC_TERM_FLEN))
	{
		/* DBG_MEM("Update terminal serial to PSAM. New tsn:", tsn, 6); */

		if (-1 == psam_update_binary(pboc, &resp, tsn, PBOC_TERM_FID, 0,
			PBOC_TERM_FLEN))
		{
			DBG("Update terminal serial failed!\n");
			return -1;
		}
	}

#ifdef __PBOC_TEST
	adf = "SZDXCARD0000001";
#endif

	/* Select PBOC ADF */
	/* DBG("Select PBOC APP using %s\n", adf); */
	if (-1 == psam_select_name(pboc, &resp, adf))
	{
		DBG("Select PBOC app in PSAM error!\n");
		return -1;
	}
	memset(pboc_adf, 0, sizeof(pboc_adf));
	strncpy(pboc_adf, adf, sizeof(pboc_adf) - 1);
	DBG_OK();

	return 0;

free_err:
	delete_psam_cos(pboc);
	pboc = NULL;
err:
	return -1;	
}
Exemple #8
0
int irc_dcc_accept(irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dcc_callback_t callback) {
    irc_dcc_session_t * dcc = libirc_find_dcc_session(session, dccid, 1);

    if (!dcc)
        return 1;

    if (dcc->state != LIBIRC_STATE_INIT) {
        session->lasterror = LIBIRC_ERR_STATE;
        libirc_mutex_unlock(&session->mutex_dcc);
        return 1;
    }

    dcc->cb = callback;
    dcc->ctx = ctx;

    DBG_OK("going to socket_connect!");

    // Initiate the connect

    if (socket_connect(&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof (dcc->remote_addr))) {
        libirc_dcc_destroy_nolock(session, dccid);
        libirc_mutex_unlock(&session->mutex_dcc);
        session->lasterror = LIBIRC_ERR_CONNECT;
        return 1;
    }
    
#ifdef ENABLE_SSL
    if (dcc->ssl == 1) {
        DBG_OK("using ssl!");

        while (1) {
            int err = SSL_connect(dcc->ssl_ctx);
            if (err <= 0) {
                int ssl_err = SSL_get_error(dcc->ssl_ctx, err);
                if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) {
                    continue;
                } else {
                    print_ssl_error_stack();
                    session->lasterror = LIBIRC_ERR_CONNECT;
                    return 1;
                }
            }
            DBG_OK("ssl_connect succeded!");
            break;
        }
        
        const char *ciphers_used = "None";
        ciphers_used = SSL_get_cipher_name(dcc->ssl_ctx);
        logprintf(LOG_INFO, "using cipher suite: %s for dcc connection", ciphers_used);
    }
#endif

    DBG_OK("connect succeded2!");

    dcc->state = LIBIRC_STATE_CONNECTING;
#ifdef ENABLE_SSL
    if (dcc->ssl) {
        dcc->state = LIBIRC_STATE_CONNECTED;
    }
#endif
    libirc_mutex_unlock(&session->mutex_dcc);
    return 0;
}
Exemple #9
0
static void libirc_dcc_request(irc_session_t * session, irc_parser_result_t *result, const char * req) {
    char filenamebuf[LIBIRC_BUFFER_SIZE+1];
    unsigned long ip;
    unsigned long token;
    irc_dcc_size_t size;
    unsigned short port;

    filenamebuf[LIBIRC_BUFFER_SIZE] = (char) 0;
    DBG_OK("---- got dcc req: %s ---", req);

    if (!isValidRequestFromNick(result->nick)) {
        DBG_WARN("received unknown dcc req from nick %s. ignoring that request!", result->nick);
        return;
    }

    if (sscanf(req, "DCC SEND %"LIBIRC_BUFFER_SIZE_STR"s %lu 0 %" IRC_DCC_SIZE_T_FORMAT" %lu", filenamebuf, &ip, &size,
      &token) == 4) {
        accept_reverse_dcc_send(session, result->nick, req, filenamebuf, ip, size, token, NO_SSL);
        return;
    }
    if (sscanf(req, "DCC SEND %"LIBIRC_BUFFER_SIZE_STR"s %lu %hu %" IRC_DCC_SIZE_T_FORMAT, filenamebuf, &ip, &port, &size) == 4) {
        accept_dcc_send(session, result->nick, req, filenamebuf, ip, size, port, NO_SSL);
        return;
    }
        /*this matches file names that contain spaces and are are delimited by quotes,
                 so for example "This is a really long file name with spaces" would match*/
    else if (sscanf(req, "DCC SEND \"%"LIBIRC_BUFFER_SIZE_STR"[^\"]\" %lu %hu %" IRC_DCC_SIZE_T_FORMAT, filenamebuf, &ip, &port, &size) == 4) {
         accept_dcc_send(session, result->nick, req, filenamebuf, ip, size, port, NO_SSL);
        return;
    } else if (sscanf(req, "DCC SEND %"LIBIRC_BUFFER_SIZE_STR"s %lu %hu", filenamebuf, &ip, &port) == 3) {
        size = 0;
        accept_dcc_send(session, result->nick, req, filenamebuf, ip, size, port, NO_SSL);
        return;
    }
#if defined (ENABLE_SSL)
    else if (sscanf(req, "DCC SSEND %"LIBIRC_BUFFER_SIZE_STR"s %lu %hu %" IRC_DCC_SIZE_T_FORMAT, filenamebuf, &ip, &port, &size) == 4) {
        accept_dcc_send(session, result->nick, req, filenamebuf, ip, size, port, USE_SSL);
        return;
    }
#endif
    else if (sscanf(req, "DCC ACCEPT file.ext %hu %" IRC_DCC_SIZE_T_FORMAT, &port, &size) == 2) {
        DBG_OK("---- got dcc accept req: %hu %" IRC_DCC_SIZE_T_FORMAT " ---", port, size);
        irc_dcc_session_t * dcc;
        dcc = libirc_find_dcc_session_by_port(session, port, 1);
        if (dcc == NULL) {
            DBG_WARN("cant find open dcc session with port = %hu!", port);
            return;
        }

        if (dcc->state != LIBIRC_STATE_WAITING_FOR_RESUME_ACK) {
            DBG_WARN("dcc->state != LIBIRC_STATE_WAITING_FOR_RESUME_ACK");
            return;
        }

        dcc->state = LIBIRC_STATE_INIT;

        dcc->file_confirm_offset = size;

        libirc_mutex_unlock(&session->mutex_dcc);

        (*dcc->cb) (session, dcc->id, 1, dcc->ctx, NULL, size);

        return;

    }

    DBG_ERR("BUG: Unhandled DCC message: %s", req);
}
Exemple #10
0
static int libirc_new_dcc_session(irc_session_t * session, unsigned long ip, unsigned short port, void * ctx, irc_dcc_session_t ** pdcc, int ssl) {
    irc_dcc_session_t * dcc = malloc(sizeof (irc_dcc_session_t));

    if (!dcc)
        return LIBIRC_ERR_NOMEM;

    // setup
    memset(dcc, 0, sizeof (irc_dcc_session_t));

    dcc->dccsend_file_fp = 0;

    if (libirc_mutex_init(&dcc->mutex_outbuf))
        goto cleanup_exit_error;

    if (socket_create(PF_INET, SOCK_STREAM, &dcc->sock))
        goto cleanup_exit_error;

	// make socket non-blocking, so connect() call won't block
    if (socket_make_nonblocking(&dcc->sock))
        goto cleanup_exit_error;

    //optimizeSocketBufferSize(dcc);
 
#if defined (ENABLE_SSL)
    dcc->ssl = 0;
    if (ssl) {
        dcc->ssl = 1;
        if (!isSslIntitialized()) {
            DBG_OK("need to init ssl context!");
            int ret = initSslContext(session);
            if (ret != 0) {
                DBG_ERR("ssl context cant be inited!");
                exit(-1);
            }

        }
        dcc->ssl_ctx = SSL_new(ssl_context);
        SSL_set_fd(dcc->ssl_ctx, dcc->sock);
        if (session->verify_callback != NULL)
            SSL_set_verify(dcc->ssl_ctx, SSL_VERIFY_PEER, session->verify_callback);
        else
            SSL_set_verify(dcc->ssl_ctx, SSL_VERIFY_NONE, NULL);
        // Since we're connecting on our own, tell openssl about it
        SSL_set_connect_state(dcc->ssl_ctx);
    }
#endif

    memset(&dcc->remote_addr, 0, sizeof (dcc->remote_addr));
    dcc->remote_addr.sin_family = AF_INET;
    dcc->remote_addr.sin_addr.s_addr = htonl(ip); // what idiot came up with idea to send IP address in host-byteorder?
    dcc->remote_addr.sin_port = htons(port);

    dcc->state = LIBIRC_STATE_INIT;

    dcc->ctx = ctx;
    time(&dcc->timeout);

    // and store it
    libirc_mutex_lock(&session->mutex_dcc);

    dcc->id = session->dcc_last_id++;
    dcc->next = session->dcc_sessions;
    session->dcc_sessions = dcc;

    libirc_mutex_unlock(&session->mutex_dcc);

    *pdcc = dcc;
    return 0;

cleanup_exit_error:
    if (dcc->sock >= 0)
        socket_close(&dcc->sock);

    free(dcc);
    return LIBIRC_ERR_SOCKET;
}