Beispiel #1
0
/**
 * Callback function to handle the ssi read event. We get the response
 * string from the ssi server here.
 */
static gboolean
ssi_auth_cb(HybridSslConnection *ssl, gpointer user_data)
{
    gchar           buf[BUF_LENGTH];
    gchar          *pos;
    gchar          *pos1;
    gint            ret;
    gint            code;
    fetion_account *ac = (fetion_account*)user_data;

    ret = hybrid_ssl_read(ssl, buf, sizeof(buf));

    if (ret == -1 || ret == 0) {
        hybrid_debug_error("ssi", "ssi server response error");
        return FALSE;
    }

    buf[ret] = '\0';

    hybrid_ssl_connection_destory(ssl);

    hybrid_debug_info("fetion", "recv:\n%s", buf);

    code = hybrid_get_http_code(buf);

    if (421 == code || 420 == code) {            /* confirm code needed. */
        if (HYBRID_ERROR == parse_ssi_fail_resp(ac, buf)) {
            goto ssi_auth_err;
        }

        verify_data.ssl     = ssl;
        verify_data.type = VERIFY_TYPE_SSI;

        hybrid_proxy_connect(NAV_SERVER, 80, pic_download_cb, ac);

        return FALSE;
    }

    if (200 != code) {
        goto ssi_auth_err;
    }

    if (!(pos = strstr(buf, "ssic="))) {
        goto ssi_auth_err;
    }

    pos += 5;

    for (pos1 = pos; *pos1 && *pos1 != ';'; pos1 ++);

    ac->ssic = g_strndup(pos, pos1 - pos);

    if (!(pos = g_strrstr(buf, "\r\n\r\n"))) {
        goto ssi_auth_err;
    }

    pos += 4;

    if (strlen(pos) != hybrid_get_http_length(buf)) {
        goto ssi_auth_err;
    }

    if (parse_ssi_response(ac, pos) != HYBRID_OK) {
        goto ssi_auth_err;
    }

    /*
     * First of all, we load the account's version information from the disk,
     * so that we can use it for authenticating, if the server find the versions
     * are up-to-date, it would return a brief response message in stead of the
     * full version, so that we can use the information store locally. This method
     * makes account logining more faster.
     */
    fetion_config_load_account(ac);

    /* now we will download the configuration */
    hybrid_proxy_connect(NAV_SERVER, 80, cfg_connect_cb, ac);

    return FALSE;

ssi_auth_err:

    hybrid_account_error_reason(ac->account, _("ssi authentication failed"));

    return FALSE;
}
Beispiel #2
0
/**
 * Callback function to handle the cfg read event.
 */
static gboolean
cfg_read_cb(gint sk, gpointer user_data)
{
    gchar           buf[BUF_LENGTH];
    gint            n;
    gint            length = 0;
    gchar          *pos;
    fetion_account *ac     = (fetion_account*)user_data;

    if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) {
        hybrid_account_error_reason(ac->account, _("read cfg failed"));
        return FALSE;
    }

    buf[n] = '\0';

    if (n != 0) {

        /* larger the recv buffer, and copy the new
         * received bytes to the buffer */
        length = ac->buffer ? strlen(ac->buffer) : 0;
        ac->buffer = g_realloc(ac->buffer, length + n + 1);
        memcpy(ac->buffer + length, buf, n + 1);

        return TRUE;

    } else { /* receive complete, start process */

        if (hybrid_get_http_code(ac->buffer) != 200) {
            goto error;
        }

        hybrid_debug_info("fetion", "cfg recv:\n%s", ac->buffer);

        if (!(pos = g_strrstr(ac->buffer, "\r\n\r\n"))) {
            goto error;
        }

        pos += 4;

        if (strlen(pos) != hybrid_get_http_length(ac->buffer)) {
            goto error;
        }

        if (parse_configuration(ac, pos) != HYBRID_OK) {
            g_free(ac->buffer);
            ac->buffer = NULL;
            goto error;
        }

        g_free(ac->buffer);
        ac->buffer = NULL;

        /* now we start sipc register */

        hybrid_proxy_connect(ac->sipc_proxy_ip, ac->sipc_proxy_port,
                sipc_reg_action, ac);
    }

    return FALSE;
error:
    hybrid_account_error_reason(ac->account, _("read cfg failed"));
    return FALSE;
}
Beispiel #3
0
static gboolean
pic_read_cb(gint sk, gpointer user_data)
{
    gint     n, len;
    gchar    sipmsg[BUF_LENGTH];
    gchar   *code, *pos;
    guchar  *pic;
    gint     piclen;
    xmlnode *root;
    xmlnode *node;

    fetion_account *ac = (fetion_account*)user_data;

    len    = ac->buffer ? strlen(ac->buffer) : 0;

    if((n = recv(sk, sipmsg, strlen(sipmsg), 0)) == -1) {
        return -1;
    }

    sipmsg[n] = 0;

    if(n == 0) {
           g_source_remove(ac->source);
        ac->source = 0;
        close(sk);

        if(! ac->buffer) {
            return 0;
        }

        hybrid_debug_info("fetion", "read message resp:\n%s", ac->buffer);

        if (200 != hybrid_get_http_code(ac->buffer)) {
            goto read_pic_err;
        }

        if(!(pos = strstr(ac->buffer, "\r\n\r\n"))) {
            goto read_pic_err;
        }

        pos += 4;

        if (!(root = xmlnode_root(pos, strlen(pos)))) {
            goto read_pic_err;
        }

        if (!(node = xmlnode_find(root, "pic-certificate"))) {
            xmlnode_free(root);
            goto read_pic_err;
        }

        if (!xmlnode_has_prop(node, "id") || !xmlnode_has_prop(node, "pic")) {
            xmlnode_free(root);
            goto read_pic_err;
        }

        ac->verification->guid = xmlnode_prop(node, "id");
        code                   = xmlnode_prop(node, "pic");

        pic = hybrid_base64_decode(code, &piclen);

        hybrid_confirm_window_create(ac->account, pic, piclen,
                                     pic_code_ok_cb, pic_code_cancel_cb, ac);

        g_free(code);
        g_free(pic);
        xmlnode_free(root);
        g_free(ac->buffer);
        ac->buffer = (gchar*)0;

        return FALSE;
    }

    ac->buffer = (gchar*)realloc(ac->buffer, len + n + 1);
    memcpy(ac->buffer + len, sipmsg, n + 1);

    return TRUE;

 read_pic_err:
    hybrid_debug_error("fetion", "read pic code error.");

    g_free(ac->buffer);
    ac->buffer = (gchar *)0;

    hybrid_account_error_reason(ac->account, _("read pic code error."));
    return FALSE;
}
Beispiel #4
0
/**
 * Callback function to handle the portrait receive event.
 */
static gboolean
portrait_recv_cb(gint sk, gpointer user_data)
{
	gchar buf[BUF_LENGTH];
	gint n;
	gchar *pos;
	HybridBuddy *imbuddy;
	portrait_trans *trans = (portrait_trans*)user_data;

	if ((n = recv(sk, buf, sizeof(buf), 0)) == -1) {
		hybrid_debug_error("fetion", "get portrait for \'%s\':%s",
				trans->buddy ? trans->buddy->sid : trans->ac->sid, 
				strerror(errno));
		return FALSE;
	}

	buf[n] = '\0';

	if (n == 0) {

		if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) {
			imbuddy = hybrid_blist_find_buddy(trans->ac->account,
					trans->buddy->userid);
		}

		if (hybrid_get_http_code(trans->data) != 200) {
			/* 
			 * Note that we got no portrait, but we still need
			 * to set buddy icon, just for the portrait checksum, we 
			 * set it default to "0" instead of leaving it NULL,
			 * so that in the next login, we just check the changes
			 * of the buddy's checksum to determine whether to fetch a 
			 * portrait from the server. 
			 */
			if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) {
				hybrid_blist_set_buddy_icon(imbuddy, NULL, 0,
						trans->buddy->portrait_crc);

			} else {
				hybrid_account_set_icon(trans->ac->account, NULL,
						0, trans->ac->portrait_crc);
			}

			goto pt_fin;
		}

		trans->data_len = hybrid_get_http_length(trans->data);

		if (!(pos = strstr(trans->data, "\r\n\r\n"))) {
			goto pt_fin;
		}

		pos += 4;

		if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) { /**< buddy portrait */
			hybrid_blist_set_buddy_icon(imbuddy, (guchar*)pos,
					trans->data_len, trans->buddy->portrait_crc);

		} else {
			hybrid_account_set_icon(trans->ac->account, (guchar*)pos,
					trans->data_len, trans->ac->portrait_crc);
		}

		goto pt_fin;

	} else {
		trans->data = realloc(trans->data, trans->data_size + n);
		memcpy(trans->data + trans->data_size, buf, n);
		trans->data_size += n;
	}

	return TRUE;

pt_fin:
	g_free(trans->data);
	g_free(trans);

	return FALSE;
}