Ejemplo n.º 1
0
Archivo: login.c Proyecto: yet/lwqq
/** 
 * WebQQ login function
 * Step:
 * 1. Get webqq version
 * 2. Get verify code
 * 3. Calculate password's md5
 * 4. Do real login 
 * 5. check whether logining successfully
 * 
 * @param client Lwqq Client 
 * @param err Error code
 */
void lwqq_login(LwqqClient *client, LwqqErrorCode *err)
{
    if (!client || !err) {
        lwqq_log(LOG_ERROR, "Invalid pointer\n");
        return ;
    }

    /* First: get webqq version */
    get_version(client, err);
    if (*err) {
        lwqq_log(LOG_ERROR, "Get webqq version error\n");
        return ;
    }
    lwqq_log(LOG_NOTICE, "Get webqq version: %s\n", client->version);

    /**
     * Second, we get the verify code from server.
     * If server provide us a image and let us enter code shown
     * in image number, in this situation, we just return LWQQ_EC_LOGIN_NEED_VC
     * simply, so user should call lwqq_login() again after he set correct
     * code to vc->str;
     * Else, if we can get the code directly, do login immediately.
     * 
     */
    if (!client->vc) {
        get_verify_code(client, err);
        switch (*err) {
        case LWQQ_EC_LOGIN_NEED_VC:
            get_verify_image(client);
            lwqq_log(LOG_WARNING, "Need to enter verify code\n");
            return ;
        
        case LWQQ_EC_NETWORK_ERROR:
            lwqq_log(LOG_ERROR, "Network error\n");
            return ;

        case LWQQ_EC_OK:
            lwqq_log(LOG_DEBUG, "Get verify code OK\n");
            break;

        default:
            lwqq_log(LOG_ERROR, "Unknown error\n");
            return ;
        }
    }
    
    /* Third: calculate the md5 */
    char *md5 = lwqq_enc_pwd(client->password, client->vc->str, client->vc->uin);

    /* Last: do real login */
    do_login(client, md5, err);
    s_free(md5);

    /* Free old value */
    lwqq_vc_free(client->vc);
    client->vc = NULL;
}
Ejemplo n.º 2
0
static LwqqAsyncEvent* get_version(LwqqClient *lc, LwqqErrorCode *err)
{
    LwqqHttpRequest *req;

    req = lwqq_http_create_default_request(lc,WEBQQ_VERSION_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, 0, NULL,_C_(p_i,get_version_back,req));
}
Ejemplo n.º 3
0
static char* hash_with_remote_file(const char* uin, const char* ptwebqq,
                                   void* js)
{
   // github.com is too slow
   const char* url = "http://pidginlwqq.sinaapp.com/hash.js";
   LwqqErrorCode ec = qq_download(url, "hash.js", lwdb_get_config_dir());
   if (ec) {
      lwqq_log(LOG_ERROR, "Could not download JS From %s", url);
   }
   return hash_with_local_file(uin, ptwebqq, js);
}
Ejemplo n.º 4
0
/**
 * I hacked the javascript file named comm.js, which received from tencent
 * server, and find that f**k tencent has changed encryption algorithm
 * for password in webqq3 . The new algorithm is below(descripted with javascript):
 * var M=C.p.value; // M is the qq password 
 * var I=hexchar2bin(md5(M)); // Make a md5 digest
 * var H=md5(I+pt.uin); // Make md5 with I and uin(see below)
 * var G=md5(H+C.verifycode.value.toUpperCase());
 * 
 * @param pwd User's password
 * @param vc Verify Code. e.g. "!M6C"
 * @param uin A string like "\x00\x00\x00\x00\x54\xb3\x3c\x53", NB: it
 *        must contain 8 hexadecimal number, in this example, it equaled
 *        to "0x0,0x0,0x0,0x0,0x54,0xb3,0x3c,0x53"
 * 
 * @return Encoded password on success, else NULL on failed
 */
static char *lwqq_enc_pwd(const char *pwd, const char *vc, const char *uin)
{
	int i;
	int uin_byte_length;
	char buf[128] = {0};
	unsigned char sig[32];
	char _uin[9] = {0};

	if (!pwd || !vc || !uin) {
		lwqq_log(LOG_ERROR, "Null parameterment\n");
		return NULL;
	}


	/* Calculate the length of uin (it must be 8?) */
	uin_byte_length = strlen(uin) / 4;

	/**
	 * Ok, parse uin from string format.
	 * "\x00\x00\x00\x00\x54\xb3\x3c\x53" -> {0,0,0,0,54,b3,3c,53}
	 */
	for (i = 0; i < uin_byte_length ; i++) {
		char u[5] = {0};
		char tmp;
		strncpy(u, uin + i * 4 + 2, 2);

		errno = 0;
		tmp = strtol(u, NULL, 16);
		if (errno) {
			return NULL;
		}
		_uin[i] = tmp;
	}
	/* Equal to "var I=hexchar2bin(md5(M));" */
	md5_buffer(pwd,strlen(pwd),sig);
	memcpy(buf,sig,sizeof(sig));

	/* Equal to "var H=md5(I+pt.uin);" */
	memcpy(buf + 16, _uin, uin_byte_length);
	md5_buffer(buf, 16 + uin_byte_length, sig);
	md5_sig_to_string(sig,buf,sizeof(buf));

	/* Equal to var G=md5(H+C.verifycode.value.toUpperCase()); */
	snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s", vc);
	upcase_string(buf, strlen(buf));

	md5_buffer(buf, strlen(buf), sig);
	md5_sig_to_string(sig,buf,sizeof(buf));
	upcase_string(buf, strlen(buf));

	/* OK, seems like every is OK */
	return s_strdup(buf);
}
Ejemplo n.º 5
0
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));
}
Ejemplo n.º 6
0
/** 
 * WebQQ login function
 * Step:
 * 1. Get webqq version
 * 2. Get verify code
 * 3. Calculate password's md5
 * 4. Do real login 
 * 5. check whether logining successfully
 * 
 * @param client Lwqq Client 
 * @param err Error code
 */
void lwqq_login(LwqqClient *client, LwqqStatus status,LwqqErrorCode *err)
{
    if (!client || !status) {
        lwqq_log(LOG_ERROR, "Invalid pointer\n");
        return ;
    }

    client->stat = status;

    lwqq_puts("[login stage 1:get webqq version]\n");
    /* optional: get webqq version */
    //get_version(client, err);
    login_stage_2(client);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
/** 
 * WebQQ login function
 * Step:
 * 1. Get webqq version
 * 2. Get verify code
 * 3. Calculate password's md5
 * 4. Do real login 
 * 5. check whether logining successfully
 * 
 * @param client Lwqq Client 
 * @param err Error code
 */
void lwqq_login(LwqqClient *client, LwqqStatus status,LwqqErrorCode *err)
{
    if (!client || !status) {
        lwqq_log(LOG_ERROR, "Invalid pointer\n");
        return ;
    }

    client->stat = status;

    lwqq_puts("[login stage 1:get webqq version]\n");
    /* First: get webqq version */
    LwqqAsyncEvent* ev = get_version(client, err);
    lwqq_async_add_event_listener(ev,_C_(p,login_stage_2,ev));
}
Ejemplo n.º 9
0
/** 
 * WebQQ login function
 * Step:
 * 1. Get webqq version
 * 2. Get verify code
 * 3. Calculate password's md5
 * 4. Do real login 
 * 5. check whether logining successfully
 * 
 * @param client Lwqq Client 
 * @param err Error code
 */
void lwqq_login(LwqqClient *client, LwqqStatus status,LwqqErrorCode *err)
{
    if (!client) {
        lwqq_log(LOG_ERROR, "Invalid pointer\n");
        return ;
    }
	if(status == LWQQ_STATUS_LOGOUT || status == LWQQ_STATUS_OFFLINE){
		lwqq_log(LOG_WARNING, "Invalid online status\n");
		return;
	}

    client->stat = status;

	client->args->login_ec = LWQQ_EC_NO_RESULT;
	vp_do_repeat(client->events->start_login, NULL);
    /* optional: get webqq version */
    //get_version(client, err);
    if(!client->vc){
        LwqqAsyncEvent* ev = get_login_sig(client);
        lwqq_async_add_event_listener(ev, _C_(2p,login_stage_2,client,err));
    }else{
        login_stage_4(client,err);
    }
}
Ejemplo n.º 10
0
static void recv_file_cancel(PurpleXfer* xfer)
{
	LwqqMsg* msg = xfer->data;
	if(!msg) return;
	if(lwqq_mt_bits(msg->type)==LWQQ_MT_FILE_MSG){
		LwqqMsgFileMessage* file = (LwqqMsgFileMessage*)msg;
		lwqq_http_cancel(file->req);
		lwqq_msg_free((LwqqMsg*)file);
	}else if(lwqq_mt_bits(msg->type)==LWQQ_MT_OFFFILE){
		LwqqMsgOffFile* file = (LwqqMsgOffFile*)msg;
		lwqq_http_cancel(file->req);
		lwqq_msg_free((LwqqMsg*)file);
	}else{
		lwqq_log(LOG_ERROR,"msg file cast failed");
	}
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
GQQMessageLoop* gqq_msgloop_start(const gchar *name)
{
    if (name == NULL) {
        name = "";
    }

    GQQMessageLoop *ml = g_slice_new0(GQQMessageLoop);
    ml->name = g_strdup(name);

    GError *err = NULL;
    if (g_thread_create(thread_main, ml, FALSE, &err) == NULL) {
        lwqq_log(LOG_WARNING, "Create main loop thread failed\n", err->message);
        g_error_free(err);
        g_free(ml->name);
        g_slice_free(GQQMessageLoop, ml);
        return NULL;
    }
    return ml;
}
Ejemplo n.º 13
0
/** 
 * 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));
}
Ejemplo n.º 14
0
static int get_verify_image_back(LwqqHttpRequest* req)
{
    int ret;
    int err = LWQQ_EC_OK;
    char image_file[256];
    int image_length = 0;
    LwqqClient* lc = req->lc;
    if (req->http_code != 200) {
        err = LWQQ_EC_ERROR;
        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);
    return err;
}
Ejemplo n.º 15
0
/** 
 * 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));
}
Ejemplo n.º 16
0
Archivo: login.c Proyecto: yet/lwqq
/** 
 * 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);    
}
Ejemplo n.º 17
0
Archivo: login.c Proyecto: yet/lwqq
/** 
 * 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);
}
Ejemplo n.º 18
0
Archivo: login.c Proyecto: yet/lwqq
/** 
 * Update the cookies needed by webqq
 *
 * @param req  
 * @param key 
 * @param value 
 * @param update_cache Weather update lwcookies member
 */
static void update_cookies(LwqqCookies *cookies, LwqqHttpRequest *req,
                           const char *key, int update_cache)
{
    if (!cookies || !req || !key) {
        lwqq_log(LOG_ERROR, "Null pointer access\n");
        return ;
    }

    char *value = req->get_cookie(req, key);
    if (!value)
        return ;
    
#define FREE_AND_STRDUP(a, b)                   \
    if (a)                                      \
        s_free(a);                              \
    a = s_strdup(b);
    
    if (!strcmp(key, "ptvfsession")) {
        FREE_AND_STRDUP(cookies->ptvfsession, value);
    } else if (!strcmp(key, "ptcz")) {
        FREE_AND_STRDUP(cookies->ptcz, value);
    } else if (!strcmp(key, "skey")) {
        FREE_AND_STRDUP(cookies->skey, value);
    } else if (!strcmp(key, "ptwebqq")) {
        FREE_AND_STRDUP(cookies->ptwebqq, value);
    } else if (!strcmp(key, "ptuserinfo")) {
        FREE_AND_STRDUP(cookies->ptuserinfo, value);
    } else if (!strcmp(key, "uin")) {
        FREE_AND_STRDUP(cookies->uin, value);
    } else if (!strcmp(key, "ptisp")) {
        FREE_AND_STRDUP(cookies->ptisp, value);
    } else if (!strcmp(key, "pt2gguin")) {
        FREE_AND_STRDUP(cookies->pt2gguin, value);
    } else if (!strcmp(key, "verifysession")) {
        FREE_AND_STRDUP(cookies->verifysession, value);
    } else {
        lwqq_log(LOG_WARNING, "No this cookie: %s\n", key);
    }
    s_free(value);

    if (update_cache) {
        char buf[4096] = {0};           /* 4K is enough for cookies. */
        int buflen = 0;
        if (cookies->ptvfsession) {
            snprintf(buf, sizeof(buf), "ptvfsession=%s; ", cookies->ptvfsession);
            buflen = strlen(buf);
        }
        if (cookies->ptcz) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "ptcz=%s; ", cookies->ptcz);
            buflen = strlen(buf);
        }
        if (cookies->skey) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "skey=%s; ", cookies->skey);
            buflen = strlen(buf);
        }
        if (cookies->ptwebqq) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "ptwebqq=%s; ", cookies->ptwebqq);
            buflen = strlen(buf);
        }
        if (cookies->ptuserinfo) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "ptuserinfo=%s; ", cookies->ptuserinfo);
            buflen = strlen(buf);
        }
        if (cookies->uin) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "uin=%s; ", cookies->uin);
            buflen = strlen(buf);
        }
        if (cookies->ptisp) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "ptisp=%s; ", cookies->ptisp);
            buflen = strlen(buf);
        }
        if (cookies->pt2gguin) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "pt2gguin=%s; ", cookies->pt2gguin);
            buflen = strlen(buf);
        }
        if (cookies->verifysession) {
            snprintf(buf + buflen, sizeof(buf) - buflen, "verifysession=%s; ", cookies->verifysession);
            buflen = strlen(buf);
        }
        
        FREE_AND_STRDUP(cookies->lwcookies, buf);
    }
#undef FREE_AND_STRDUP
}
Ejemplo n.º 19
0
Archivo: login.c Proyecto: yet/lwqq
/** 
 * 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);
}
Ejemplo n.º 20
0
Archivo: login.c Proyecto: yet/lwqq
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);
}
Ejemplo n.º 21
0
/** 
 * 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;
}
Ejemplo n.º 22
0
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,&param2,url,&param4,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;
}
Ejemplo n.º 23
0
static int get_verify_code_back(LwqqHttpRequest* req)
{
    int err = LWQQ_EC_OK;
    char response[256];
    LwqqClient* lc = req->lc;
    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){
            err = LWQQ_EC_ERROR;
            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);
    }
    
failed:
    lwqq_http_request_free(req);
    return err;
}
Ejemplo n.º 24
0
static int do_login_back(LwqqHttpRequest* req)
{
    LwqqClient* lc = req->lc;
    int err = LWQQ_EC_OK;
    const char* response;
    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");
        sscanf(beg,"%[^']",lc->error_description);
        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;
    }
    char buf[4] = {0};
    int status;
    strncpy(buf, p + 1, 1);
    status = atoi(buf);

    switch (status) {
    case 0:
        //sava_cookie(lc, req, NULL);
        err = LWQQ_EC_OK;
        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_ERROR;
        lc->last_err = "Wrong username or password";
        goto done;

    case 4:
        lwqq_log(LOG_ERROR, "Wrong verify code\n");
        err = LWQQ_EC_ERROR;
        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_ERROR;
        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;

    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;
}