void process_incoming_refer(struct sipe_core_private *sipe_private,
			    struct sipmsg *msg)
{
	gchar *self = sip_uri_self(sipe_private);
	const gchar *callid = sipmsg_find_header(msg, "Call-ID");
	gchar *from = parse_from(sipmsg_find_header(msg, "From"));
	gchar *refer_to = parse_from(sipmsg_find_header(msg, "Refer-to"));
	gchar *referred_by = g_strdup(sipmsg_find_header(msg, "Referred-By"));
	struct sip_session *session;
	struct sip_dialog *dialog;

	session = sipe_session_find_chat_by_callid(sipe_private, callid);
	dialog = sipe_dialog_find(session, from);

	if (!session || !dialog || !session->chat_session ||
	    (session->chat_session->type != SIPE_CHAT_TYPE_MULTIPARTY) ||
	    !session->chat_session->id ||
	    !sipe_strcase_equal(session->chat_session->id, self)) {
		sip_transport_response(sipe_private, msg, 500, "Server Internal Error", NULL);
	} else {
		sip_transport_response(sipe_private, msg, 202, "Accepted", NULL);

		sipe_im_invite(sipe_private, session, refer_to, NULL, NULL, referred_by, FALSE);
	}

	g_free(self);
	g_free(from);
	g_free(refer_to);
	g_free(referred_by);
}
예제 #2
0
gchar *sipmsg_find_auth_header(struct sipmsg *msg, const gchar *name) {
	GSList *tmp;
	struct sipnameval *elem;
	int name_len = strlen(name);
	tmp = msg->headers;
	while(tmp) {
		elem = tmp->data;
		/* SIPE_DEBUG_INFO("Current header: %s", elem->value); */
		if (elem && elem->name &&
		    (sipe_strcase_equal(elem->name,"WWW-Authenticate") ||
		     sipe_strcase_equal(elem->name,"Authentication-Info")) ) {
			if (!g_strncasecmp((gchar *)elem->value, name, name_len)) {
				/* SIPE_DEBUG_INFO("elem->value: %s", elem->value); */
				return elem->value;
			}
		}
		/* SIPE_DEBUG_INFO_NOFORMAT("moving to next header"); */
		tmp = g_slist_next(tmp);
	}
	SIPE_DEBUG_INFO("auth header '%s' not found.", name);
	return NULL;
}
예제 #3
0
void sipmsg_remove_header_now(struct sipmsg *msg, const gchar *name) {
	struct sipnameval *elem;
	GSList *tmp = msg->headers;
	while(tmp) {
		elem = tmp->data;
		// OCS2005 can send the same header in either all caps or mixed case
		if (sipe_strcase_equal(elem->name, name)) {
			msg->headers = g_slist_remove(msg->headers, elem);
			g_free(elem->name);
			g_free(elem->value);
			g_free(elem);
			return;
		}
		tmp = g_slist_next(tmp);
	}
	return;
}
예제 #4
0
void sipe_core_ft_outgoing_start(struct sipe_file_transfer *ft,
				 gsize total_size)
{
	static const guchar VER[] = "VER MSN_SECURE_FTP\r\n";
	const gsize BUFFER_SIZE  = 50;

	struct sipe_file_transfer_private *ft_private = SIPE_FILE_TRANSFER_PRIVATE;
	guchar buf[BUFFER_SIZE];
	gchar **parts;
	unsigned auth_cookie_received;
	gboolean users_match;

	if (!read_line(ft_private, buf, BUFFER_SIZE)) {
		raise_ft_socket_read_error_and_cancel(ft_private);
		return;
	}

	if (!sipe_strequal((gchar *)buf, (gchar *)VER)) {
		raise_ft_error_and_cancel(ft_private,
					  _("File transfer initialization failed."));
		SIPE_DEBUG_INFO("File transfer VER string incorrect, received: %s expected: %s",
				buf, VER);
		return;
	}

	if (!write_exact(ft_private, VER, sizeof(VER) - 1)) {
		raise_ft_socket_write_error_and_cancel(ft_private);
		return;
	}

	if (!read_line(ft_private, buf, BUFFER_SIZE)) {
		raise_ft_socket_read_error_and_cancel(ft_private);
		return;
	}

	parts = g_strsplit((gchar *)buf, " ", 3);
	auth_cookie_received = g_ascii_strtoull(parts[2], NULL, 10);
	/* dialog->with has 'sip:' prefix, skip these four characters */
	users_match = sipe_strcase_equal(parts[1],
					 (ft_private->dialog->with + 4));
	g_strfreev(parts);

	SIPE_DEBUG_INFO("File transfer authentication: %s Expected: USR %s %u",
			buf,
			ft_private->dialog->with + 4,
			ft_private->auth_cookie);

	if (!users_match ||
	    (ft_private->auth_cookie != auth_cookie_received)) {
		raise_ft_error_and_cancel(ft_private,
					  _("File transfer authentication failed."));
		return;
	}

	g_sprintf((gchar *)buf, "FIL %" G_GSIZE_FORMAT "\r\n", total_size);
	if (!write_exact(ft_private, buf, strlen((gchar *)buf))) {
		raise_ft_socket_write_error_and_cancel(ft_private);
		return;
	}

	/* TFR */
	if (!read_line(ft_private ,buf, BUFFER_SIZE)) {
		raise_ft_socket_read_error_and_cancel(ft_private);
		return;
	}

	ft_private->bytes_remaining_chunk = 0;
	ft_private->cipher_context = sipe_cipher_context_init(ft_private->encryption_key);
	ft_private->hmac_context   = sipe_hmac_context_init(ft_private->hash_key);
}
예제 #5
0
void sipe_ocs2005_apply_calendar_status(struct sipe_core_private *sipe_private,
                                        struct sipe_buddy *sbuddy,
                                        const char *status_id)
{
    time_t cal_avail_since;
    int cal_status = sipe_cal_get_status(sbuddy, time(NULL), &cal_avail_since);
    int avail;
    gchar *self_uri;

    if (!sbuddy) return;

    if (cal_status < SIPE_CAL_NO_DATA) {
        SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_status      : %d for %s", cal_status, sbuddy->name);
        SIPE_DEBUG_INFO("sipe_apply_calendar_status: cal_avail_since : %s", asctime(localtime(&cal_avail_since)));
    }

    /* scheduled Cal update call */
    if (!status_id) {
        status_id = sbuddy->last_non_cal_status_id;
        g_free(sbuddy->activity);
        sbuddy->activity = g_strdup(sbuddy->last_non_cal_activity);
    }

    if (!status_id) {
        SIPE_DEBUG_INFO("sipe_apply_calendar_status: status_id is NULL for %s, exiting.",
                        sbuddy->name ? sbuddy->name : "" );
        return;
    }

    /* adjust to calendar status */
    if (cal_status != SIPE_CAL_NO_DATA) {
        SIPE_DEBUG_INFO("sipe_apply_calendar_status: user_avail_since: %s", asctime(localtime(&sbuddy->user_avail_since)));

        if ((cal_status == SIPE_CAL_BUSY) &&
                (cal_avail_since > sbuddy->user_avail_since) &&
                sipe_ocs2007_status_is_busy(status_id)) {
            status_id = sipe_status_activity_to_token(SIPE_ACTIVITY_BUSY);
            g_free(sbuddy->activity);
            sbuddy->activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_IN_MEETING));
        }
        avail = sipe_ocs2007_availability_from_status(status_id, NULL);

        SIPE_DEBUG_INFO("sipe_apply_calendar_status: activity_since  : %s", asctime(localtime(&sbuddy->activity_since)));
        if (cal_avail_since > sbuddy->activity_since) {
            if ((cal_status == SIPE_CAL_OOF) &&
                    sipe_ocs2007_availability_is_away(avail)) {
                g_free(sbuddy->activity);
                sbuddy->activity = g_strdup(sipe_core_activity_description(SIPE_ACTIVITY_OOF));
            }
        }
    }

    /* then set status_id actually */
    SIPE_DEBUG_INFO("sipe_apply_calendar_status: to %s for %s", status_id, sbuddy->name ? sbuddy->name : "" );
    sipe_backend_buddy_set_status(SIPE_CORE_PUBLIC, sbuddy->name,
                                  sipe_status_token_to_activity(status_id));

    /* set our account state to the one in roaming (including calendar info) */
    self_uri = sip_uri_self(sipe_private);
    if (SIPE_CORE_PRIVATE_FLAG_IS(INITIAL_PUBLISH) &&
            sipe_strcase_equal(sbuddy->name, self_uri)) {
        if (sipe_strequal(status_id, sipe_status_activity_to_token(SIPE_ACTIVITY_OFFLINE))) {
            /* do not let offline status switch us off */
            status_id = sipe_status_activity_to_token(SIPE_ACTIVITY_INVISIBLE);
        }

        sipe_status_and_note(sipe_private, status_id);
    }
    g_free(self_uri);
}