static void get_verify_image(LwqqClient *lc) { LwqqHttpRequest *req = NULL; char url[512]; int ret; char chkuin[64]; char image_file[256]; int image_length = 0; LwqqErrorCode err; snprintf(url, sizeof(url), LWQQ_URL_VERIFY_IMG, APPID, lc->username); req = lwqq_http_create_default_request(url, &err); if (!req) { goto failed; } snprintf(chkuin, sizeof(chkuin), "chkuin=%s", lc->username); req->set_header(req, "Cookie", chkuin); ret = req->do_request(req, 0, NULL); if (ret) { goto failed; } if (req->http_code != 200) { goto failed; } const char *content_length = req->get_header(req, "Content-Length"); if (content_length) { image_length = atoi(content_length); } update_cookies(lc->cookies, req, "verifysession", 1); snprintf(image_file, sizeof(image_file), "/tmp/%s.jpeg", lc->username); /* Delete old file first */ unlink(image_file); int fd = creat(image_file, S_IRUSR | S_IWUSR); if (fd != -1) { ret = write(fd, req->response, image_length); if (ret <= 0) { lwqq_log(LOG_ERROR, "Saving erify image file error\n"); } close(fd); } lc->vc->data = req->response; lc->vc->size = req->resp_len; req->response = NULL; failed: lwqq_http_request_free(req); }
static void get_version(LwqqClient *lc, LwqqErrorCode *err) { LwqqHttpRequest *req; char *response = NULL; int ret; req = lwqq_http_create_default_request(LWQQ_URL_VERSION, err); if (!req) { goto done; } /* Send request */ lwqq_log(LOG_DEBUG, "Get webqq version from %s\n", LWQQ_URL_VERSION); ret = req->do_request(req, 0, NULL); if (ret || req->http_code!=200) { *err = LWQQ_EC_NETWORK_ERROR; goto done; } response = req->response; if(response == NULL){ *err = LWQQ_EC_NETWORK_ERROR; goto done; } if (strstr(response, "ptuiV")) { char *s, *t; char *v; s = strchr(response, '('); t = strchr(response, ')'); if (!s || !t) { *err = LWQQ_EC_ERROR; goto done; } s++; v = alloca(t - s + 1); memset(v, 0, t - s + 1); strncpy(v, s, t - s); s_free(lc->version); lc->version = s_strdup(v); *err = LWQQ_EC_OK; } done: lwqq_http_request_free(req); }
LwqqErrorCode qq_download(const char* url,const char* file,const char* dir) { LwqqHttpRequest* req = lwqq_http_request_new(url); req->do_request(req,0,NULL); if(req->http_code != 200) return LWQQ_EC_ERROR; if(!req->response) return LWQQ_EC_ERROR; char path[2048]; snprintf(path,sizeof(path),"%s/%s",dir,file); char* content = req->response; FILE* f; f = fopen(path, "w"); if(!f) mkdir(dir,0755); if(!f) return LWQQ_EC_ERROR; fwrite(content, 1, strlen(content), f); fclose(f); lwqq_http_request_free(req); return LWQQ_EC_OK; }
/** * WebQQ logout function * * @param client Lwqq Client * @param err Error code */ void lwqq_logout(LwqqClient *client, LwqqErrorCode *err) { char url[512]; LwqqHttpRequest *req = NULL; int ret; json_t *json = NULL; char *value; struct timeval tv; char *cookies; long int re; if (!client) { lwqq_log(LOG_ERROR, "Invalid pointer\n"); return ; } /* Get the milliseconds of now */ if (gettimeofday(&tv, NULL)) { if (err) *err = LWQQ_EC_ERROR; return ; } re = tv.tv_usec / 1000; re += tv.tv_sec; snprintf(url, sizeof(url), "%s/channel/logout2?clientid=%s&psessionid=%s&t=%ld", "http://d.web2.qq.com", client->clientid, client->psessionid, re); /* Create a GET request */ req = lwqq_http_create_default_request(url, err); if (!req) { goto done; } /* Set header needed by server */ req->set_header(req, "Referer", "http://ptlogin2.qq.com/proxy.html?v=20101025002"); /* Set http cookie */ cookies = lwqq_get_cookies(client); if (cookies) { req->set_header(req, "Cookie", cookies); s_free(cookies); } ret = req->do_request(req, 0, NULL); if (ret) { lwqq_log(LOG_ERROR, "Send logout request failed\n"); if (err) *err = LWQQ_EC_NETWORK_ERROR; goto done; } if (req->http_code != 200) { if (err) *err = LWQQ_EC_HTTP_ERROR; goto done; } ret = json_parse_document(&json, req->response); if (ret != JSON_OK) { if (err) *err = LWQQ_EC_ERROR; goto done; } /* Check whether logout correctly */ value = json_parse_simple_value(json, "retcode"); if (!value || strcmp(value, "0")) { if (err) *err = LWQQ_EC_ERROR; goto done; } value = json_parse_simple_value(json, "result"); if (!value || strcmp(value, "ok")) { if (err) *err = LWQQ_EC_ERROR; goto done; } /* Ok, seems like all thing is ok */ if (err) *err = LWQQ_EC_OK; done: if (json) json_free_value(&json); lwqq_http_request_free(req); }
/** * Set online status, this is the last step of login * * @param err * @param lc */ static void set_online_status(LwqqClient *lc, char *status, LwqqErrorCode *err) { char msg[1024] ={0}; char *buf; LwqqHttpRequest *req = NULL; char *response = NULL; char *cookies; int ret; json_t *json = NULL; char *value; if (!status || !err) { goto done ; } lc->clientid = generate_clientid(); if (!lc->clientid) { lwqq_log(LOG_ERROR, "Generate clientid error\n"); *err = LWQQ_EC_ERROR; goto done ; } snprintf(msg, sizeof(msg), "{\"status\":\"%s\",\"ptwebqq\":\"%s\"," "\"passwd_sig\":""\"\",\"clientid\":\"%s\"" ", \"psessionid\":null}" ,status, lc->cookies->ptwebqq ,lc->clientid); buf = url_encode(msg); snprintf(msg, sizeof(msg), "r=%s", buf); s_free(buf); /* Create a POST request */ req = lwqq_http_create_default_request(LWQQ_URL_SET_STATUS, err); if (!req) { goto done; } /* Set header needed by server */ req->set_header(req, "Cookie2", "$Version=1"); req->set_header(req, "Referer", "http://d.web2.qq.com/proxy.html?v=20101025002"); req->set_header(req, "Content-type", "application/x-www-form-urlencoded"); /* Set http cookie */ cookies = lwqq_get_cookies(lc); if (cookies) { req->set_header(req, "Cookie", cookies); s_free(cookies); } ret = req->do_request(req, 1, msg); if (ret) { *err = LWQQ_EC_NETWORK_ERROR; goto done; } if (req->http_code != 200) { *err = LWQQ_EC_HTTP_ERROR; goto done; } /** * Here, we got a json object like this: * {"retcode":0,"result":{"uin":1421032531,"cip":2013211875,"index":1060,"port":43415,"status":"online","vfwebqq":"e7ce7913336ad0d28de9cdb9b46a57e4a6127161e35b87d09486001870226ec1fca4c2ba31c025c7","psessionid":"8368046764001e636f6e6e7365727665725f77656271714031302e3133332e34312e32303200006b2900001544016e0400533cb3546d0000000a4046674d4652585136496d00000028e7ce7913336ad0d28de9cdb9b46a57e4a6127161e35b87d09486001870226ec1fca4c2ba31c025c7","user_state":0,"f":0}} * */ response = req->response; ret = json_parse_document(&json, response); if (ret != JSON_OK) { *err = LWQQ_EC_ERROR; goto done; } if (!(value = json_parse_simple_value(json, "retcode"))) { *err = LWQQ_EC_ERROR; goto done; } /** * Do we need parse "seskey? from kernelhcy's code, we need it, * but from the response we got like above, we dont need * */ if ((value = json_parse_simple_value(json, "seskey"))) { lc->seskey = s_strdup(value); } if ((value = json_parse_simple_value(json, "cip"))) { lc->cip = s_strdup(value); } if ((value = json_parse_simple_value(json, "index"))) { lc->index = s_strdup(value); } if ((value = json_parse_simple_value(json, "port"))) { lc->port = s_strdup(value); } if ((value = json_parse_simple_value(json, "status"))) { /* This really need? */ lc->status = s_strdup(value); } if ((value = json_parse_simple_value(json, "vfwebqq"))) { lc->vfwebqq = s_strdup(value); } if ((value = json_parse_simple_value(json, "psessionid"))) { lc->psessionid = s_strdup(value); } *err = LWQQ_EC_OK; done: if (json) json_free_value(&json); lwqq_http_request_free(req); }
/** * Do really login * * @param lc * @param md5 The md5 calculated from calculate_password_md5() * @param err */ static void do_login(LwqqClient *lc, const char *md5, LwqqErrorCode *err) { char url[1024]; LwqqHttpRequest *req; char *response = NULL; char *cookies; int ret; snprintf(url, sizeof(url), "%s/login?u=%s&p=%s&verifycode=%s&" "webqq_type=10&remember_uin=1&aid=1003903&login2qq=1&" "u1=http%%3A%%2F%%2Fweb.qq.com%%2Floginproxy.html" "%%3Flogin2qq%%3D1%%26webqq_type%%3D10&h=1&ptredirect=0&" "ptlang=2052&from_ui=1&pttype=1&dumy=&fp=loginerroralert&" "action=2-11-7438&mibao_css=m_webqq&t=1&g=1", LWQQ_URL_LOGIN_HOST, lc->username, md5, lc->vc->str); req = lwqq_http_create_default_request(url, err); if (!req) { goto done; } /* Setup http header */ cookies = lwqq_get_cookies(lc); if (cookies) { req->set_header(req, "Cookie", cookies); s_free(cookies); } /* Send request */ ret = req->do_request(req, 0, NULL); if (ret) { *err = LWQQ_EC_NETWORK_ERROR; goto done; } if (req->http_code != 200) { *err = LWQQ_EC_HTTP_ERROR; goto done; } response = req->response; char *p = strstr(response, "\'"); if (!p) { *err = LWQQ_EC_ERROR; goto done; } char buf[4] = {0}; int status; strncpy(buf, p + 1, 1); status = atoi(buf); switch (status) { case 0: if (sava_cookie(lc, req, err)) { goto done; } break; case 1: lwqq_log(LOG_WARNING, "Server busy! Please try again\n"); *err = LWQQ_EC_ERROR; goto done; case 2: lwqq_log(LOG_ERROR, "Out of date QQ number\n"); *err = LWQQ_EC_ERROR; goto done; case 3: lwqq_log(LOG_ERROR, "Wrong password\n"); *err = LWQQ_EC_ERROR; goto done; case 4: lwqq_log(LOG_ERROR, "Wrong verify code\n"); *err = LWQQ_EC_ERROR; goto done; case 5: lwqq_log(LOG_ERROR, "Verify failed\n"); *err = LWQQ_EC_ERROR; goto done; case 6: lwqq_log(LOG_WARNING, "You may need to try login again\n"); *err = LWQQ_EC_ERROR; goto done; case 7: lwqq_log(LOG_ERROR, "Wrong input\n"); *err = LWQQ_EC_ERROR; goto done; case 8: lwqq_log(LOG_ERROR, "Too many logins on this IP. Please try again\n"); *err = LWQQ_EC_ERROR; goto done; default: *err = LWQQ_EC_ERROR; lwqq_log(LOG_ERROR, "Unknow error"); goto done; } set_online_status(lc, "online", err); done: lwqq_http_request_free(req); }
static void get_verify_code(LwqqClient *lc, LwqqErrorCode *err) { LwqqHttpRequest *req; char url[512]; char response[256]; int ret; char chkuin[64]; snprintf(url, sizeof(url), "%s%s?uin=%s&appid=%s", LWQQ_URL_CHECK_HOST, VCCHECKPATH, lc->username, APPID); req = lwqq_http_create_default_request(url, err); if (!req) { goto failed; } snprintf(chkuin, sizeof(chkuin), "chkuin=%s", lc->username); req->set_header(req, "Cookie", chkuin); ret = req->do_request(req, 0, NULL); if (ret) { *err = LWQQ_EC_NETWORK_ERROR; goto failed; } if (req->http_code != 200) { *err = LWQQ_EC_HTTP_ERROR; goto failed; } /** * * The http message body has two format: * * ptui_checkVC('1','9ed32e3f644d968809e8cbeaaf2cce42de62dfee12c14b74'); * ptui_checkVC('0','!LOB'); * The former means we need verify code image and the second * parameter is vc_type. * The later means we don't need the verify code image. The second * parameter is the verify code. The vc_type is in the header * "Set-Cookie". */ snprintf(response, sizeof(response), "%s", req->response); lwqq_log(LOG_NOTICE, "Get response verify code: %s\n", response); char *c = strstr(response, "ptui_checkVC"); char *s; if (!c) { *err = LWQQ_EC_HTTP_ERROR; goto failed; } c = strchr(response, '\''); if (!c) { *err = LWQQ_EC_HTTP_ERROR; goto failed; } c++; lc->vc = s_malloc0(sizeof(*lc->vc)); if (*c == '0') { /* We got the verify code. */ /* Parse uin first */ lc->vc->uin = parse_verify_uin(response); if (!lc->vc->uin) goto failed; s = c; c = strstr(s, "'"); s = c + 1; c = strstr(s, "'"); s = c + 1; c = strstr(s, "'"); *c = '\0'; lc->vc->type = s_strdup("0"); lc->vc->str = s_strdup(s); /* We need get the ptvfsession from the header "Set-Cookie" */ update_cookies(lc->cookies, req, "ptvfsession", 1); lwqq_log(LOG_NOTICE, "Verify code: %s\n", lc->vc->str); } else if (*c == '1') { /* We need get the verify image. */ /* Parse uin first */ lc->vc->uin = parse_verify_uin(response); s = c; c = strstr(s, "'"); s = c + 1; c = strstr(s, "'"); s = c + 1; c = strstr(s, "'"); *c = '\0'; lc->vc->type = s_strdup("1"); // ptui_checkVC('1','7ea19f6d3d2794eb4184c9ae860babf3b9c61441520c6df0', '\x00\x00\x00\x00\x04\x7e\x73\xb2'); lc->vc->str = s_strdup(s); *err = LWQQ_EC_LOGIN_NEED_VC; lwqq_log(LOG_NOTICE, "We need verify code image: %s\n", lc->vc->str); } lwqq_http_request_free(req); return ; failed: lwqq_http_request_free(req); }
/** * WebQQ logout function * * @param client Lwqq Client * @param err Error code */ LWQQ_EXPORT void lwqq_logout(LwqqClient *client, LwqqErrorCode *err) { LwqqClient* lc = client; char url[512]; LwqqHttpRequest *req = NULL; int ret; json_t *json = NULL; char *value; struct timeval tv; long int re; if (!client) { lwqq_log(LOG_ERROR, "Invalid pointer\n"); return ; } /* Get the milliseconds of now */ if (gettimeofday(&tv, NULL)) { if (err) *err = LWQQ_EC_ERROR; return ; } re = tv.tv_usec / 1000; re += tv.tv_sec; snprintf(url, sizeof(url), "%s/channel/logout2" "?clientid=%s&psessionid=%s&t=%ld", WEBQQ_D_HOST, client->clientid, client->psessionid, re); /* Create a GET request */ req = lwqq_http_create_default_request(client,url, err); if (!req) { goto done; } /* Set header needed by server */ req->set_header(req, "Referer", WEBQQ_LOGIN_REF_URL); lwqq_http_set_option(req, LWQQ_HTTP_ALL_TIMEOUT,5L); req->retry = 0; ret = req->do_request(req, 0, NULL); if (ret) { lwqq_log(LOG_ERROR, "Send logout request failed\n"); if (err) *err = LWQQ_EC_NETWORK_ERROR; goto done; } if (req->http_code != 200) { if (err) *err = LWQQ_EC_HTTP_ERROR; goto done; } ret = json_parse_document(&json, req->response); if (ret != JSON_OK) { if (err) *err = LWQQ_EC_ERROR; goto done; } /* Check whether logout correctly */ value = json_parse_simple_value(json, "retcode"); if (!value || strcmp(value, "0")) { if (err) *err = LWQQ_EC_ERROR; goto done; } value = json_parse_simple_value(json, "result"); if (!value || strcmp(value, "ok")) { if (err) *err = LWQQ_EC_ERROR; goto done; } /* Ok, seems like all thing is ok */ if (err) *err = LWQQ_EC_OK; done: if (json) json_free_value(&json); lwqq_http_request_free(req); client->stat = LWQQ_STATUS_LOGOUT; }