void pecan_cmd_server_free (PecanCmdServer *conn) { pecan_log ("begin"); g_object_unref (G_OBJECT (conn)); pecan_log ("end"); }
static void dispose (GObject *obj) { PecanCmdServer *cmd_conn = CMD_PECAN_NODE (obj); pecan_log ("begin"); if (cmd_conn->cmdproc) { msn_cmdproc_destroy (cmd_conn->cmdproc); cmd_conn->cmdproc = NULL; } G_OBJECT_CLASS (parent_class)->dispose (obj); pecan_log ("end"); }
PecanCmdServer * pecan_cmd_server_new (const gchar *name, PecanNodeType type) { PecanCmdServer *conn; pecan_log ("begin"); conn = CMD_PECAN_NODE (g_type_create_instance (CMD_PECAN_NODE_TYPE)); { PecanNode *tmp = PECAN_NODE (conn); tmp->name = g_strdup (name); tmp->type = type; } pecan_log ("end"); return conn; }
static void error_cb (PecanNode *node, gpointer arg, gpointer data) { PecanSession *session; PecanSessionPrivate *priv; session = PECAN_SESSION (data); priv = session->priv; pecan_log ("begin"); { PecanSessionClass *class; class = g_type_class_peek (PECAN_SESSION_TYPE); g_signal_emit (G_OBJECT (session), class->error_sig, 0, arg); } pecan_log ("end"); }
static void close_impl (PecanNode *conn) { PecanCmdServer *cmd_conn; pecan_log ("begin"); cmd_conn = CMD_PECAN_NODE (conn); g_free (cmd_conn->rx_buf); cmd_conn->rx_buf = NULL; cmd_conn->rx_len = 0; cmd_conn->payload_len = 0; if (cmd_conn->cmdproc) msn_cmdproc_flush (cmd_conn->cmdproc); PECAN_NODE_CLASS (parent_class)->close (conn); pecan_log ("end"); }
static void open_cb (PecanNode *conn, MsnNotification *notification) { MsnSession *session; PecanCmdServer *cmd_conn; g_return_if_fail (conn != NULL); pecan_log ("begin"); session = conn->session; cmd_conn = CMD_PECAN_NODE (conn); if (session->login_step == PECAN_LOGIN_STEP_START) msn_session_set_login_step (session, PECAN_LOGIN_STEP_HANDSHAKE); else msn_session_set_login_step (session, PECAN_LOGIN_STEP_HANDSHAKE2); msn_cmdproc_send (cmd_conn->cmdproc, "VER", "MSNP12 CVR0"); pecan_log ("end"); }
/** @todo add extensive tests for this */ static void parse_impl (PecanNode *base_conn, gchar *buf, gsize bytes_read) { PecanCmdServer *cmd_conn; gchar *cur, *end, *old_rx_buf; gint cur_len; pecan_log ("begin"); pecan_debug ("conn=%p,name=%s", base_conn, base_conn->name); cmd_conn = CMD_PECAN_NODE (base_conn); buf[bytes_read] = '\0'; cmd_conn->rx_buf = g_realloc (cmd_conn->rx_buf, bytes_read + cmd_conn->rx_len + 1); memcpy (cmd_conn->rx_buf + cmd_conn->rx_len, buf, bytes_read + 1); cmd_conn->rx_len += bytes_read; end = old_rx_buf = cmd_conn->rx_buf; cmd_conn->rx_buf = NULL; do { cur = end; if (cmd_conn->payload_len) { if (cmd_conn->payload_len > cmd_conn->rx_len) /* The payload is still not complete. */ break; cur_len = cmd_conn->payload_len; end += cur_len; } else { end = strstr(cur, "\r\n"); if (end == NULL) /* The command is still not complete. */ break; *end = '\0'; end += 2; cur_len = end - cur; } cmd_conn->rx_len -= cur_len; if (cmd_conn->cmdproc) { if (cmd_conn->payload_len) { msn_cmdproc_process_payload (cmd_conn->cmdproc, cur, cur_len); cmd_conn->payload_len = 0; } else { msn_cmdproc_process_cmd_text (cmd_conn->cmdproc, cur); cmd_conn->payload_len = cmd_conn->cmdproc->last_cmd->payload_len; } } } while (cmd_conn->rx_len > 0); if (cmd_conn->rx_len > 0) cmd_conn->rx_buf = g_memdup (cur, cmd_conn->rx_len); else cmd_conn->rx_buf = NULL; g_free (old_rx_buf); pecan_log ("end"); }
void login_connect_cb(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond) { MsnNexus *nexus; MsnSession *session; char *username, *password; char *request_str, *head, *tail; char *buffer = NULL; guint32 ctint; nexus = data; g_return_if_fail(nexus != NULL); session = nexus->session; g_return_if_fail(session != NULL); msn_session_set_login_step(session, PECAN_LOGIN_STEP_GET_COOKIE); username = g_strdup(purple_url_encode(msn_session_get_username(session))); password = g_strdup(purple_url_encode(msn_session_get_password(session))); ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200; head = pecan_strdup_printf( "GET %s HTTP/1.1\r\n" "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s", nexus->login_path, (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), username); tail = pecan_strdup_printf( "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n" "User-Agent: MSMSGS\r\n" "Host: %s\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n", nexus_challenge_data_lookup(nexus->challenge_data, "lc"), nexus_challenge_data_lookup(nexus->challenge_data, "id"), nexus_challenge_data_lookup(nexus->challenge_data, "tw"), nexus_challenge_data_lookup(nexus->challenge_data, "fs"), nexus_challenge_data_lookup(nexus->challenge_data, "ru"), ctint, nexus_challenge_data_lookup(nexus->challenge_data, "kpp"), nexus_challenge_data_lookup(nexus->challenge_data, "kv"), nexus_challenge_data_lookup(nexus->challenge_data, "ver"), nexus_challenge_data_lookup(nexus->challenge_data, "tpf"), nexus->login_host); buffer = pecan_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail); request_str = pecan_strdup_printf("%s,pwd=%s,%s\r\n", head, password, tail); pecan_log ("sending: [%s]", buffer); g_free(buffer); g_free(head); g_free(tail); g_free(username); g_free(password); nexus->write_buf = request_str; nexus->written_len = 0; nexus->read_len = 0; nexus->written_cb = nexus_login_written_cb; nexus->input_handler = purple_input_add(gsc->fd, PURPLE_INPUT_WRITE, nexus_write_cb, nexus); nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); return; }
static void nexus_login_written_cb(gpointer data, gint source, PurpleInputCondition cond) { MsnNexus *nexus = data; MsnSession *session; int len; session = nexus->session; g_return_if_fail(session != NULL); if (nexus->input_handler == 0) /* TODO: Use purple_ssl_input_add()? */ nexus->input_handler = purple_input_add(nexus->gsc->fd, PURPLE_INPUT_READ, nexus_login_written_cb, nexus); len = msn_ssl_read(nexus); if (len < 0 && errno == EAGAIN) return; else if (len < 0) { purple_input_remove(nexus->input_handler); nexus->input_handler = 0; g_free(nexus->read_buf); nexus->read_buf = NULL; nexus->read_len = 0; /* TODO: error handling */ return; } if (g_strstr_len(nexus->read_buf, nexus->read_len, "\r\n\r\n") == NULL) return; purple_input_remove(nexus->input_handler); nexus->input_handler = 0; purple_ssl_close(nexus->gsc); nexus->gsc = NULL; pecan_log ("ssl buffer: [%s]", nexus->read_buf); if (strstr(nexus->read_buf, "HTTP/1.1 302") != NULL) { /* Redirect. */ char *location, *c; location = strstr(nexus->read_buf, "Location: "); if (location == NULL) { g_free(nexus->read_buf); nexus->read_buf = NULL; nexus->read_len = 0; return; } location = strchr(location, ' ') + 1; if ((c = strchr(location, '\r')) != NULL) *c = '\0'; /* Skip the http:// */ if ((c = strchr(location, '/')) != NULL) location = c + 2; if ((c = strchr(location, '/')) != NULL) { g_free(nexus->login_path); nexus->login_path = g_strdup(c); *c = '\0'; } g_free(nexus->login_host); nexus->login_host = g_strdup(location); nexus->gsc = purple_ssl_connect(session->account, nexus->login_host, PURPLE_SSL_DEFAULT_PORT, login_connect_cb, login_error_cb, nexus); } else if (strstr(nexus->read_buf, "HTTP/1.1 401 Unauthorized") != NULL) { const char *error; if ((error = strstr(nexus->read_buf, "WWW-Authenticate")) != NULL) { if ((error = strstr(error, "cbtxt=")) != NULL) { const char *c; char *temp; error += strlen("cbtxt="); if ((c = strchr(error, '\n')) == NULL) c = error + strlen(error); temp = g_strndup(error, c - error); error = purple_url_decode(temp); g_free(temp); if ((temp = strstr(error, " Do one of the following or try again:")) != NULL) *temp = '\0'; } } msn_session_set_error(session, MSN_ERROR_AUTH, error); } else if (strstr(nexus->read_buf, "HTTP/1.1 503 Service Unavailable")) { msn_session_set_error(session, MSN_ERROR_SERV_UNAVAILABLE, NULL); } else if (strstr(nexus->read_buf, "HTTP/1.1 200 OK")) { char *base, *c; char *login_params; #if 0 /* All your base are belong to us. */ base = buffer; /* For great cookie! */ while ((base = strstr(base, "Set-Cookie: ")) != NULL) { base += strlen("Set-Cookie: "); c = strchr(base, ';'); session->login_cookies = g_list_append(session->login_cookies, g_strndup(base, c - base)); } #endif base = strstr(nexus->read_buf, "Authentication-Info: "); g_return_if_fail(base != NULL); base = strstr(base, "from-PP='"); base += strlen("from-PP='"); c = strchr(base, '\''); login_params = g_strndup(base, c - base); msn_got_login_params(session, login_params); g_free(login_params); msn_nexus_destroy(nexus); session->nexus = NULL; return; } g_free(nexus->read_buf); nexus->read_buf = NULL; nexus->read_len = 0; }
static void got_ok(MsnSlpCall *slpcall, const char *type, const char *content) { g_return_if_fail(slpcall != NULL); g_return_if_fail(type != NULL); pecan_log ("type=%s", type); if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) { #ifdef MSN_DIRECTCONN if (slpcall->slplink->session->use_directconn && slpcall->type == MSN_SLPCALL_DC) { /* First let's try a DirectConnection. */ MsnSlpLink *slplink; MsnSlpMessage *slpmsg; char *header; gchar *new_content; char *branch; slplink = slpcall->slplink; branch = msn_rand_guid(); new_content = pecan_strdup_printf( "Bridges: TRUDPv1 TCPv1\r\n" "NetID: 0\r\n" "Conn-Type: Direct-Connect\r\n" "UPnPNat: false\r\n" "ICF: false\r\n" ); header = pecan_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0", slplink->remote_user); slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, branch, "application/x-msnmsgr-transreqbody", new_content); #ifdef PECAN_DEBUG_SLP slpmsg->info = "SLP INVITE"; slpmsg->text_body = TRUE; #endif msn_slplink_send_slpmsg(slplink, slpmsg); g_free(header); g_free(new_content); g_free(branch); } else { msn_slp_call_session_init(slpcall); } #else msn_slp_call_session_init(slpcall); #endif /* MSN_DIRECTCONN */ } else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) { /* Do we get this? */ pecan_info ("OK with transreqbody"); } #ifdef MSN_DIRECTCONN else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) { char *ip_addrs; char *temp; char *nonce; int port; { char *listening; listening = get_token(content, "Listening: ", "\r\n"); if (strcmp (listening, "false") == 0) { /** @todo I'm not sure if this is OK. */ msn_slp_call_session_init(slpcall); g_free (listening); return; } g_free (listening); } nonce = get_token(content, "Nonce: {", "}\r\n"); ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); if (temp != NULL) port = atoi(temp); else port = -1; g_free(temp); if (ip_addrs == NULL) return; if (port > 0) got_transresp(slpcall, nonce, ip_addrs, port); g_free(nonce); g_free(ip_addrs); } #endif /* MSN_DIRECTCONN */ }
static void got_invite(MsnSlpCall *slpcall, const char *branch, const char *type, const char *content) { MsnSlpLink *slplink; slplink = slpcall->slplink; pecan_log ("type=%s", type); if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) { char *euf_guid, *context; char *temp; euf_guid = get_token(content, "EUF-GUID: {", "}\r\n"); temp = get_token(content, "SessionID: ", "\r\n"); if (temp != NULL) slpcall->session_id = atoi(temp); g_free(temp); temp = get_token(content, "AppID: ", "\r\n"); if (temp != NULL) slpcall->app_id = atoi(temp); g_free(temp); context = get_token(content, "Context: ", "\r\n"); if (context != NULL) got_sessionreq(slpcall, branch, euf_guid, context); g_free(context); g_free(euf_guid); } else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) { /* A direct connection? */ const gchar *listening; gchar *new_content, *nonce; if (FALSE) { #if 0 MsnDirectConn *directconn; /* const char *ip_addr; */ char *ip_port; int port; /* ip_addr = purple_prefs_get_string("/purple/ft/public_ip"); */ ip_port = "5190"; listening = "true"; nonce = msn_rand_guid(); directconn = msn_directconn_new(slplink); /* msn_directconn_parse_nonce(directconn, nonce); */ directconn->nonce = g_strdup(nonce); msn_directconn_listen(directconn); port = directconn->port; new_content = pecan_strdup_printf( "Bridge: TCPv1\r\n" "Listening: %s\r\n" "Nonce: {%s}\r\n" "Ipv4Internal-Addrs: 192.168.0.82\r\n" "Ipv4Internal-Port: %d\r\n" "\r\n", listening, nonce, port); #endif } else { listening = "false"; nonce = g_strdup("00000000-0000-0000-0000-000000000000"); new_content = pecan_strdup_printf( "Bridge: TCPv1\r\n" "Listening: %s\r\n" "Nonce: {%s}\r\n" "\r\n", listening, nonce); } send_ok(slpcall, branch, "application/x-msnmsgr-transrespbody", new_content); g_free(new_content); g_free(nonce); } #ifdef MSN_DIRECTCONN else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) { char *ip_addrs; char *temp; char *nonce; int port; nonce = get_token(content, "Nonce: {", "}\r\n"); ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); if (temp != NULL) port = atoi(temp); else port = -1; g_free(temp); if (ip_addrs == NULL) return; if (port > 0) got_transresp(slpcall, nonce, ip_addrs, port); g_free(nonce); g_free(ip_addrs); } #endif /* MSN_DIRECTCONN */ }