/** * Do really login * * @param lc * @param md5 The md5 calculated from calculate_password_md5() * @param err */ static LwqqAsyncEvent* do_login(LwqqClient *lc, const char *md5, LwqqErrorCode *err) { char url[1024]; char refer[1024]; LwqqHttpRequest *req; snprintf(url, sizeof(url), WEBQQ_LOGIN_HOST"/login?" "u=%s&p=%s&verifycode=%s&" "webqq_type=%d&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&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&" "action=2-10-5837&mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10034&login_sig=%s", lc->username, md5, lc->vc->str,lc->stat,lc->login_sig); req = lwqq_http_create_default_request(lc,url, err); /* Setup http header */ req->set_header(req, "Referer", WEBQQ_LOGIN_LONG_REF_URL(refer)); LwqqAsyncEvent* ret = lwqq_async_event_new(NULL); /* Send request */ LwqqAsyncEvent* ev = req->do_request_async(req, lwqq__hasnot_post(),_C_(2p_i,do_login_back,req,ret)); lwqq_async_add_event_chain(ev,ret); return ret; }
static LwqqAsyncEvent* get_version(LwqqClient *lc, LwqqErrorCode *err) { LwqqHttpRequest *req; req = lwqq_http_create_default_request(lc,WEBQQ_VERSION_URL, err); /* Send request */ lwqq_log(LOG_DEBUG, "Get webqq version from %s\n", WEBQQ_VERSION_URL); return req->do_request_async(req, 0, NULL,_C_(p_i,get_version_back,req)); }
static LwqqAsyncEvent* get_login_sig(LwqqClient* lc) { char url[512]; snprintf(url,sizeof(url),WEBQQ_LOGIN_UI_HOST"/cgi-bin/login" "?daid=164&target=self&style=5&mibao_css=m_webqq&appid=1003903" "&enable_qlogin=0&s_url=http%%3A%%2F%%2Fweb2.qq.com%%2Floginproxy.html" ); LwqqHttpRequest* req = lwqq_http_create_default_request(lc, url, NULL); lwqq_http_set_option(req, LWQQ_HTTP_TIMEOUT,5); lwqq_http_set_option(req, LWQQ_HTTP_TIMEOUT_INCRE,5); return req->do_request_async(req,lwqq__hasnot_post(),_C_(p_i,get_login_sig_back,req)); }
LwqqAsyncEvent* lwqq_get_version(LwqqClient *lc, LwqqErrorCode *err) { LwqqHttpRequest *req; const char* url = WEBQQ_VERSION_URL; req = lwqq_http_create_default_request(lc,url , err); lwqq_http_set_option(req, LWQQ_HTTP_ALL_TIMEOUT,5L); /* Send request */ lwqq_log(LOG_DEBUG, "Get webqq version from %s\n", WEBQQ_VERSION_URL); return req->do_request_async(req, lwqq__hasnot_post(),_C_(p_i,get_version_back,req)); }
static LwqqAsyncEvent* get_verify_image(LwqqClient *lc) { LwqqHttpRequest *req = NULL; char url[512]; char chkuin[64]; LwqqErrorCode err; snprintf(url, sizeof(url), WEBQQ_CAPTCHA_HOST"/getimage?aid=%s&uin=%s", APPID, lc->username); req = lwqq_http_create_default_request(lc,url, &err); snprintf(chkuin, sizeof(chkuin), "chkuin=%s", lc->username); req->set_header(req, "Cookie", chkuin); return req->do_request_async(req, lwqq__hasnot_post(),_C_(2p_i,request_captcha_back,req,lc->vc)); }
static LwqqAsyncEvent* get_verify_code(LwqqClient *lc,const char* appid) { LwqqHttpRequest *req; char url[512]; char chkuin[64]; snprintf(url, sizeof(url), WEBQQ_CHECK_HOST"/check?uin=%s&appid=%s", lc->username, appid); req = lwqq_http_create_default_request(lc,url,NULL); lwqq_verbose(3,"%s\n",url); snprintf(chkuin, sizeof(chkuin), "chkuin=%s", lc->username); req->set_header(req, "Cookie", chkuin); return req->do_request_async(req, 0, NULL,_C_(p_i,get_verify_code_back,req)); }
LwqqAsyncEvent* lwqq_relogin(LwqqClient* lc) { if(!lc) return NULL; char url[128]; char post[512]; if(!lc->new_ptwebqq) lc->new_ptwebqq = s_strdup(lc->cookies->ptwebqq); snprintf(url, sizeof(url), WEBQQ_D_HOST"/channel/login2"); snprintf(post, sizeof(post), "r={\"status\":\"%s\",\"ptwebqq\":\"%s\",\"passwd_sig\":\"\",\"clientid\":\"%s\",\"psessionid\":\"%s\"}",lwqq_status_to_str(lc->stat),lc->new_ptwebqq,lc->clientid,lc->psessionid); lwqq_verbose(3,"%s\n",url); lwqq_verbose(3,"%s\n",post); LwqqHttpRequest* req = lwqq_http_create_default_request(lc, url, NULL); req->set_header(req,"Referer",WEBQQ_D_REF_URL); lwqq_set_cookie(lc->cookies, "ptwebqq", lc->new_ptwebqq); req->set_header(req,"Cookie",lwqq_get_cookies(lc)); return req->do_request_async(req,1,post,_C_(p_i,process_login2,req)); }
LwqqAsyncEvent* lwqq_relink(LwqqClient* lc) { if(!lc) return NULL; char url[128]; char post[512]; if(!lc->new_ptwebqq){ lc->new_ptwebqq = lwqq_http_get_cookie(lwqq_get_http_handle(lc), "ptwebqq"); } snprintf(url, sizeof(url), "%s/channel/login2",WEBQQ_D_HOST); snprintf(post, sizeof(post), "r={\"status\":\"%s\",\"ptwebqq\":\"%s\",\"passwd_sig\":\"\",\"clientid\":\"%s\",\"psessionid\":\"%s\"}",lwqq_status_to_str(lc->stat),lc->new_ptwebqq,lc->clientid,lc->psessionid); LwqqHttpRequest* req = lwqq_http_create_default_request(lc, url, NULL); req->set_header(req,"Referer",WEBQQ_D_REF_URL); lwqq_http_set_cookie(req, "ptwebqq", lc->new_ptwebqq); req->retry = 0; return req->do_request_async(req,lwqq__has_post(),_C_(p_i,process_login2,req)); }
LwqqAsyncEvent* lwqq__request_captcha(LwqqClient* lc,LwqqVerifyCode* c) { if(!lc||!c) return NULL; char url[512]; c->lc = lc; srand48(time(NULL)); double random = drand48(); snprintf(url,sizeof(url),"%s/getimage?" "aid=1003901&%.16lf", "http://captcha.qq.com",random); lwqq_puts(url); LwqqHttpRequest* req = lwqq_http_create_default_request(lc,url,NULL); req->set_header(req,"Referer","http://web2.qq.com/"); req->set_header(req,"Connection","keep-alive"); return req->do_request_async(req,0,NULL,_C_(2p_i,request_captcha_back,req,c)); }
static LwqqAsyncEvent* check_need_verify(LwqqClient *lc,const char* appid) { LwqqHttpRequest *req; char url[512]; char buf[256]; srand48(time(NULL)); double random = drand48(); snprintf(url, sizeof(url), WEBQQ_CHECK_HOST"/check?uin=%s&appid=%s&" "js_ver=10037&js_type=0&%s%s&u1=http%%3A%%2F%%2Fweb2.qq.com%%2Floginproxy.html&r=%.16lf", lc->username, appid, lc->login_sig?"login_sig=":"", lc->login_sig?:"", random); req = lwqq_http_create_default_request(lc,url,NULL); req->set_header(req,"Referer",WEBQQ_LOGIN_LONG_REF_URL(buf)); return req->do_request_async(req, lwqq__hasnot_post(),_C_(p_i,check_need_verify_back,req)); }
/** * Do really login * * @param lc * @param md5 The md5 calculated from calculate_password_md5() * @param err */ static LwqqAsyncEvent* do_login(LwqqClient *lc, const char *md5, LwqqErrorCode *err) { char url[1024]; LwqqHttpRequest *req; snprintf(url, sizeof(url), WEBQQ_LOGIN_HOST"/login?" "u=%s&p=%s&verifycode=%s&" "webqq_type=%d&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", lc->username, md5, lc->vc->str,lc->stat); req = lwqq_http_create_default_request(lc,url, err); lwqq_verbose(3,"%s\n",url); /* Setup http header */ req->set_header(req, "Cookie", lwqq_get_cookies(lc)); /* Send request */ return req->do_request_async(req, 0, NULL,_C_(p_i,do_login_back,req)); }
/** * Set online status, this is the last step of login * * @param err * @param lc */ static LwqqAsyncEvent* set_online_status(LwqqClient *lc,const char *status) { char msg[1024] ={0}; char *buf; LwqqHttpRequest *req = NULL; if (!status) { return NULL; } lc->clientid = generate_clientid(); if (!lc->clientid) { lwqq_log(LOG_ERROR, "Generate clientid error\n"); return NULL; } 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(lc,WEBQQ_D_HOST"/channel/login2", NULL); lwqq_puts("[set online status]\n"); /* Set header needed by server */ req->set_header(req, "Cookie2", "$Version=1"); req->set_header(req, "Referer", WEBQQ_D_REF_URL); req->set_header(req, "Content-type", "application/x-www-form-urlencoded"); /* Set http cookie */ req->set_header(req, "Cookie", lwqq_get_cookies(lc)); return req->do_request_async(req, 1, msg,_C_(p_i,set_online_status_back,req)); }
/** * Set online status, this is the last step of login * * @param err * @param lc */ static LwqqAsyncEvent* set_online_status(LwqqClient *lc,const char *status) { char msg[1024] ={0}; char* post = msg; LwqqHttpRequest *req = NULL; if (!status) { return NULL; } lc->clientid = generate_clientid(); if (!lc->clientid) { lwqq_log(LOG_ERROR, "Generate clientid error\n"); return NULL; } char* ptwebqq = lwqq_http_get_cookie(lwqq_get_http_handle(lc), "ptwebqq"); snprintf(msg, sizeof(msg), "r={\"status\":\"%s\",\"ptwebqq\":\"%s\"," "\"passwd_sig\":""\"\",\"clientid\":\"%s\"" ", \"psessionid\":null}" ,status, ptwebqq ,lc->clientid); urlencode(msg, 2); s_free(ptwebqq); /* Create a POST request */ char url[512] ={0}; snprintf(url,sizeof(url),"%s/channel/login2",WEBQQ_D_HOST); req = lwqq_http_create_default_request(lc,url, NULL); /* Set header needed by server */ //req->set_header(req, "Cookie2", "$Version=1"); req->set_header(req, "Referer", WEBQQ_D_REF_URL); req->set_header(req, "Content-type", "application/x-www-form-urlencoded"); return req->do_request_async(req, lwqq__has_post(),_C_(p_i,set_online_status_back,req)); }
static int do_login_back(LwqqHttpRequest* req,LwqqAsyncEvent* event) { char refer[1024]; LwqqClient* lc = req->lc; int err = LWQQ_EC_OK; const char* response; //const char redirect_url[512]; if (req->http_code != 200) { err = LWQQ_EC_HTTP_ERROR; goto done; } if (strstr(req->response,"aq.qq.com")!=NULL){ err = LWQQ_EC_LOGIN_ABNORMAL; const char* beg = strstr(req->response,"http://aq.qq.com"); if(beg) sscanf(beg,"%[^']",lc->error_description); // beg may be null goto done; } if(req->response == NULL){ lwqq_puts("login no response\n"); err = LWQQ_EC_NETWORK_ERROR; goto done; } response = req->response; lwqq_verbose(3,"%s\n",response); char *p = strstr(response, "\'"); if (!p) { err = LWQQ_EC_ERROR; goto done; } int status,param2; char url[512]; int param4; char msg[512]; char user[64]; //void url is '' which makes sscanf failed //%*c is for eat a blank before 'user' sscanf(response,"ptuiCB('%d','%d','%[^,],'%d','%[^']',%*c'%[^']');", &status,¶m2,url,¶m4,msg,user); url[strlen(url)-1]=0; switch (status) { case 0: { err = LWQQ_EC_OK; LwqqHttpRequest* req = lwqq_http_create_default_request(lc, url, NULL); req->set_header(req,"Referer",WEBQQ_LOGIN_LONG_REF_URL(refer)); lwqq_http_set_option(req, LWQQ_HTTP_MAXREDIRS,1L); LwqqAsyncEvent* ev = req->do_request_async(req,lwqq__hasnot_post(),_C_(p_i,lwqq__process_empty,req)); lwqq_async_add_event_chain(ev, event); } break; case 1: lwqq_log(LOG_WARNING, "Server busy! Please try again\n"); lc->last_err = "Server busy! Please try again"; err = LWQQ_EC_ERROR; goto done; case 2: lwqq_log(LOG_ERROR, "Out of date QQ number\n"); lc->last_err = "Out of date QQ number"; err = LWQQ_EC_ERROR; goto done; case 3: lwqq_log(LOG_ERROR, "Wrong password\n"); err = LWQQ_EC_WRONG_PASS; lc->last_err = "Wrong username or password"; goto done; case 4: lwqq_log(LOG_ERROR, "Wrong verify code\n"); err = LWQQ_EC_WRONG_VERIFY; lc->last_err = "Wrong verify code"; goto done; case 5: lwqq_log(LOG_ERROR, "Verify failed\n"); lc->last_err = "Verify failed"; err = LWQQ_EC_FAILD_VERIFY; goto done; case 6: lwqq_log(LOG_WARNING, "You may need to try login again\n"); lc->last_err = "You may need to try login again"; err = LWQQ_EC_ERROR; goto done; case 7: lwqq_log(LOG_ERROR, "Wrong input\n"); lc->last_err = "Wrong input"; err = LWQQ_EC_ERROR; goto done; case 8: lwqq_log(LOG_ERROR, "Too many logins on this IP. Please try again\n"); lc->last_err = "Too many logins on this IP.Please try again"; err = LWQQ_EC_ERROR; goto done; case LWQQ_EC_LOGIN_NEED_BARCODE: lwqq_log(LOG_ERROR, "%s\n",msg); lc->error_description = s_strdup(msg); err = LWQQ_EC_LOGIN_NEED_BARCODE; goto done; default: err = LWQQ_EC_ERROR; lc->last_err = "Unknow error"; lwqq_log(LOG_ERROR, "Unknow error"); goto done; } done: lwqq_http_request_free(req); return err; }