示例#1
0
static void pending_read(struct bufferevent *bev, void *pending_ptr) {
  struct evwspendingconn* pending = (struct evwspendingconn *)pending_ptr;
  struct evbuffer* input = bufferevent_get_input(pending->bev);
  struct evbuffer_ptr end = evbuffer_search(input, "\r\n\r\n", 4, NULL);
  size_t len = evbuffer_get_length(input);

  if (end.pos == -1) {
    if (len > MAX_HTTP_HEADER_SIZE) {
      remove_pending(pending);
      free_pending(pending);
    }
    return; // full request not yet found
  }

  unsigned char* data = evbuffer_pullup(input, len);
  char accept_key[29];

  struct evwsconnlistener* levws = pending->levws;
  const char* subprotocol = NULL;
  if (evaluate_websocket_handshake((char*)data, len,
      levws->supported_subprotocols, accept_key, &subprotocol)) {
    remove_pending(pending);
    free_pending(pending);
    return;
  }

  evbuffer_drain(input, len);

  bufferevent_setcb(pending->bev, NULL, NULL, NULL, pending);

  struct evbuffer* output = bufferevent_get_output(pending->bev);
  evbuffer_add_printf(output,
      "HTTP/1.1 101 Switching Protocols\r\n"
      "Upgrade: websocket\r\n"
      "Connection: Upgrade\r\n"
      "Sec-WebSocket-Accept: %s\r\n", accept_key);

  if (subprotocol != NULL) {
    evbuffer_add_printf(output, "Sec-WebSocket-Protocol: %s\r\n\r\n",
        subprotocol);
  } else {
    evbuffer_add_printf(output, "\r\n");
  }

  remove_pending(pending);
  struct evwsconn *wsconn = evwsconn_new(pending->bev, subprotocol);
  pending->bev = NULL;
  levws->cb(levws, wsconn, pending->address, pending->socklen,
      levws->user_data);
  free_pending(pending);
}
示例#2
0
static void pending_event(struct bufferevent *bev, short events,
    void *pending_ptr) {
  struct evwspendingconn* pending = (struct evwspendingconn *)pending_ptr;
  if (events & BEV_EVENT_EOF) {
    fprintf(stderr, "Connection closed\n");
  } else if (events & BEV_EVENT_ERROR) {
    fprintf(stderr, "Connection error\n");
    if (errno != 0) {
      fprintf(stderr, "Got an error on the connection: %s\n", strerror(errno));
    }
    unsigned long ssl_error = ERR_get_error();
    if (ssl_error != 0) {
      fprintf(stderr, "SSL error: %s\n", ERR_error_string(ssl_error, NULL));
    }
    ssl_error = bufferevent_get_openssl_error(bev);
    if (ssl_error != 0) {
      fprintf(stderr, "Got an SSL error on the connection: %s\n",
          ERR_error_string(ssl_error, NULL));
    }
  } else if (events & BEV_EVENT_CONNECTED) {
    return; // SSL connected
  } else {
    fprintf(stderr, "Unknown event: %x\n", (int)events);
  }

  remove_pending(pending);
  free_pending(pending);
}
示例#3
0
文件: session.c 项目: Commers/obexd
static gboolean session_request_proceed(gpointer data)
{
	struct pending_data *pending = data;
	struct transfer_data *transfer = pending->transfer;

	pending->cb(transfer->session, NULL, transfer);
	free_pending(pending);

	return FALSE;
}
示例#4
0
static gboolean plugin_unload(GaimPlugin * plugin)
{
    gaim_signals_disconnect_by_handle(plugin);

    GSList *search = NULL;
    for (search = pending_list; search; search = search->next) {
        free_pending(search, TRUE);
    }

    return TRUE;
}
示例#5
0
void evwsconnlistener_free(struct evwsconnlistener *levws) {
  if (levws == NULL) {
    return;
  }
  struct evwspendingconn* curr = levws->head;
  while (curr) {
    struct evwspendingconn* temp = curr;
    curr = curr->next;
    free_pending(temp);
  }
  evconnlistener_free(levws->lev);
  free(levws);
}
示例#6
0
/**
 * Purge pending_list of entries older than BOT_MAX_MINUTES minutes
 */
void expire_pending_list()
{
    const glong max_sec = 60 * BOT_MAX_MINUTES;
    GTimeVal *now = NULL;
    now = g_new0(GTimeVal, 1);
    g_get_current_time(now);
    GSList *search = NULL;
    for (search = pending_list; search; search = search->next) {
        PendingMessage *pending = search->data;
        if (pending->tv_sec < (now->tv_sec - max_sec)) {
            free_pending(search, TRUE);
        }
    }
    g_free(now);
}
示例#7
0
文件: session.c 项目: Commers/obexd
static void session_request_reply(DBusPendingCall *call, gpointer user_data)
{
	struct session_data *session = user_data;
	struct agent_data *agent = session->agent;
	struct pending_data *pending = agent->pending;
	DBusMessage *reply = dbus_pending_call_steal_reply(call);
	const char *name;
	DBusError derr;

	dbus_error_init(&derr);
	if (dbus_set_error_from_message(&derr, reply)) {
		GError *gerr = NULL;

		error("Replied with an error: %s, %s",
				derr.name, derr.message);
		dbus_error_free(&derr);
		dbus_message_unref(reply);

		g_set_error(&gerr, OBEX_IO_ERROR, -ECANCELED, "%s",
								derr.message);
		session_terminate_transfer(session, pending->transfer, gerr);
		g_clear_error(&gerr);

		return;
	}

	dbus_message_get_args(reply, NULL,
			DBUS_TYPE_STRING, &name,
			DBUS_TYPE_INVALID);

	DBG("Agent.Request() reply: %s", name);

	if (strlen(name)) {
		g_free(pending->transfer->name);
		pending->transfer->name = g_strdup(name);
	}

	agent->pending = NULL;

	pending->cb(session, NULL, pending->transfer);
	dbus_message_unref(reply);
	free_pending(pending);

	return;
}
示例#8
0
文件: session.c 项目: Commers/obexd
static void agent_free(struct session_data *session)
{
	struct agent_data *agent = session->agent;

	if (agent->watch)
		g_dbus_remove_watch(session->conn, agent->watch);

	if (agent->pending) {
		dbus_pending_call_cancel(agent->pending->call);
		free_pending(agent->pending);
	}

	session->agent = NULL;

	g_free(agent->name);
	g_free(agent->path);
	g_free(agent);
}
示例#9
0
/**
 * This is our callback for the receiving-im-msg signal.
 *
 * We return TRUE to block the IM, FALSE to accept the IM
 */
static gboolean receiving_im_msg_cb(GaimAccount * account, char **sender,
                                    char **buffer, int *flags, void *data)
{
    gboolean retval = FALSE;    /* assume the sender is allowed */
    gboolean found = FALSE;
    gint pos = -1;
    char *botmsg = NULL;


    PendingMessage *pending = NULL;
    GSList *slist = NULL;
    GSList *search = NULL;

    GaimConnection *connection = NULL;

    /* expire any old entries in pending */
    expire_pending_list();

    connection = gaim_account_get_connection(account);

    /* not good, but don't do anything */
    if (!connection || !sender) {
        return retval;
    }

    /* if there is already an open conversation, allowed it */
    if (gaim_find_conversation_with_account(*sender, account)) {
        return retval;
    }

    /* don't make buddies use the challenge/response system */
    if (gaim_find_buddy(account, *sender)) {
        return retval;
    }

    /* don't make permit list members use the challenge/response system */
    for (slist = account->permit; slist != NULL; slist = slist->next) {
        if (!gaim_utf8_strcasecmp
            (*sender, gaim_normalize(account, (char *) slist->data))) {
            return retval;
        }
    }

    /* if there is no question or no answer, allow the sender */
    const char *question =
        gaim_prefs_get_string("/plugins/core/bot/challenger/question");
    const char *answer =
        gaim_prefs_get_string("/plugins/core/bot/challenger/answer");
    if (!question || !answer) {
        return retval;
    }

    /* blank / null message ... can this even happen? */
    if (!*buffer) {
        return retval;
    }

    /* search if this sender is already in pending */
    for (search = pending_list; search; search = search->next) {
        pending = search->data;
        pos = g_slist_position(pending_list, search);

        if (protocmp(account, pending) && usercmp(account, pending)
            && sendercmp(*sender, pending)) {
            found = TRUE;
            break;
        }
    }

    if (!found) {
        /**
         * its the first time through, save the nick/msg to the
         * queue and ask the question
         */
        GTimeVal *now = NULL;
        now = g_new0(GTimeVal, 1);
        g_get_current_time(now);
        PendingMessage *newpend = NULL;

        newpend = g_new0(PendingMessage, 1);
        newpend->tv_sec = now->tv_sec;
        newpend->protocol = g_strdup(account->protocol_id);
        newpend->username = g_strdup(account->username);
        newpend->sender = g_strdup(*sender);
        newpend->message = g_strdup(*buffer);
        pending_list = g_slist_append(pending_list, newpend);

        botmsg =
            g_strdup_printf(_
                            ("Bot Challenger engaged:  you are now being ignored!  Your message will be delivered if you can correctly answer the following question within %i minutes:  %s"),
                            BOT_MAX_MINUTES, question);
        send_auto_reply(account, *sender, botmsg);

        g_free(now);
        g_free(botmsg);
        retval = TRUE;
    } else {
        if (gaim_utf8_strcasecmp(*buffer, answer)) {
                /**
                 * Sorry, thanks for playing, please try again
                 */
            retval = TRUE;
        } else {
            botmsg =
                _
                ("Bot Challenger accepted your answer and delivered your original message.  You may now speak freely.");
            send_auto_reply(account, *sender, botmsg);

            if (gaim_prefs_get_bool
                ("/plugins/core/bot/challenger/auto_add_permit")) {
                if (!gaim_privacy_permit_add(account, *sender, FALSE)) {
                    gaim_debug_info("bot-challenger",
                                    "Unable to add %s/%s/%s to permit list\n",
                                    *sender, pending->username,
                                    pending->protocol);
                }
            }

            /**
             * Free what is currently in the buffer (the correct answer)
             * and replace it with the user's first message that was
             * queued, pending the correct answer.  I think some other
             * process is supposed to free the buffer after its sent.
             */
            g_free(*buffer);
            *buffer = pending->message;

            /* Clean up everything else except pending->message */
            free_pending(search, FALSE);

            retval = FALSE;     /* Don't block this message */
        }
    }
    debug_pending_list();
    return retval;              /* returning TRUE will block the IM */
}