예제 #1
0
/**
 * Pobiera token do autoryzacji operacji na katalogu publicznym.
 *
 * Token jest niezbędny do tworzenia nowego i usuwania użytkownika,
 * zmiany hasła itd.
 *
 * \param async Flaga połączenia asynchronicznego
 *
 * \return Struktura \c gg_http lub \c NULL w przypadku błędu
 *
 * \ingroup token
 */
struct gg_http *gg_token(int async)
{
	struct gg_http *h;
	const char *query;

	query = "Host: " GG_REGISTER_HOST "\r\n"
		"Content-Type: application/x-www-form-urlencoded\r\n"
		"User-Agent: " GG_HTTP_USERAGENT "\r\n"
		"Content-Length: 0\r\n"
		"Pragma: no-cache\r\n"
		"\r\n";

	if (!(h = gg_http_connect(GG_REGISTER_HOST, GG_REGISTER_PORT, async, "POST", "/appsvc/regtoken.asp", query))) {
		gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
		return NULL;
	}

	h->type = GG_SESSION_TOKEN;

	h->callback = gg_token_watch_fd;
	h->destroy = gg_token_free;
	
	if (!async)
		gg_token_watch_fd(h);
	
	return h;
}
void GaduTokenSocketNotifiers::socketEvent()
{
	kdebugf();

	if (gg_token_watch_fd(H) == -1)
	{
		kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "getting token error\n");
		finished(QString(), QPixmap());
		return;
	}

	struct gg_pubdir *p = (struct gg_pubdir *)H->data;

	switch (H->state)
	{

		case GG_STATE_CONNECTING:
			kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "changing QSocketNotifiers.\n");
			watchFor(H);
			break;

		case GG_STATE_ERROR:
			kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "getting token error\n");
			finished(QString(), QPixmap());
			break;

		case GG_STATE_DONE:
			if (p->success)
			{
				kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "success\n");

				struct gg_token *t = (struct gg_token *)H->data;
				QString tokenId = QString::fromUtf8(t->tokenid);

				//nie optymalizowac!!!
				QByteArray buf(H->body_size, '0');
				for (unsigned int i = 0; i < H->body_size; ++i)
					buf[i] = H->body[i];

				QPixmap tokenImage;
				tokenImage.loadFromData(buf);

				finished(tokenId, tokenImage);
			}
			else
			{
				kdebugmf(KDEBUG_NETWORK|KDEBUG_INFO, "getting token error\n");
				finished(QString(), QPixmap());
			}

			break;
	}

	kdebugf2();
}
예제 #3
0
void RegisterCommand::watcher()
{
	gg_pubdir* pubDir;

	if ( state == RegisterStateWaitingForToken  ) {
		disableNotifiers();
		if ( gg_token_watch_fd( session_ ) == -1 ) {
			deleteNotifiers();
			emit error( i18n( "Gadu-Gadu" ), i18n( "Unknown connection error while retrieving token." ) );
			gg_token_free( session_ );
			session_ = NULL;
			state = RegisterStateNoToken;
			return;
		}

		pubDir = (struct gg_pubdir *)session_->data;
		emit operationStatus( i18n( "Token retrieving status: %1", GaduSession::stateDescription( session_->state ) ) );
		switch ( session_->state ) {
			case GG_STATE_CONNECTING:
				kDebug( 14100 ) << "Recreating notifiers ";
				deleteNotifiers();
				checkSocket( session_->fd, 0);
				break;
			case GG_STATE_ERROR:
				deleteNotifiers();
				emit error( i18n( "Gadu-Gadu token retrieve problem" ), GaduSession::errorDescription(  session_->error )  );
				gg_token_free( session_ );
				session_ = NULL;
				state = RegisterStateNoToken;
				return;
				break;
			case GG_STATE_DONE:
				struct gg_token* sp = ( struct gg_token* )session_->data;
				tokenId = (char *)sp->tokenid;
				kDebug( 14100 ) << "got Token!, ID: " << tokenId;
				deleteNotifiers();
				if ( pubDir->success ) {
					QPixmap tokenImg;
					tokenImg.loadFromData( (const unsigned char *)session_->body, session_->body_size );
					state = RegisterStateGotToken;
					emit tokenRecieved( tokenImg, tokenId );
				}
				else {
					emit error( i18n( "Gadu-Gadu" ), i18n( "Unable to retrieve token." ) );
					state = RegisterStateNoToken;
					deleteLater();
				}
				gg_token_free( session_ );
				session_ = NULL;
				disconnect( this, SLOT(watcher()) );
				return;
				break;
		}
		enableNotifiers( session_->check );
	}
	if ( state == RegisterStateWaitingForNumber ) {
		disableNotifiers();
		if ( gg_register_watch_fd( session_ ) == -1 ) {
			deleteNotifiers();
			emit error( i18n( "Gadu-Gadu" ), i18n( "Unknown connection error while registering." ) );
			gg_free_register( session_ );
			session_ = NULL;
			state = RegisterStateGotToken;
			return;
		}
		pubDir = (gg_pubdir*) session_->data;
		emit operationStatus( i18n( "Registration status: %1", GaduSession::stateDescription( session_->state ) ) );
		switch ( session_->state ) {
			case GG_STATE_CONNECTING:
				kDebug( 14100 ) << "Recreating notifiers ";
				deleteNotifiers();
				checkSocket( session_->fd, 0);
				break;
			case GG_STATE_ERROR:
				deleteNotifiers();
				emit error( i18n( "Gadu-Gadu Registration Error" ), GaduSession::errorDescription(  session_->error ) );
				gg_free_register( session_ );
				session_ = NULL;
				state = RegisterStateGotToken;
				return;
				break;

			case GG_STATE_DONE:
				deleteNotifiers();
				if ( pubDir->success && pubDir->uin ) {
					uin= pubDir->uin;
					state = RegisterStateDone;
					emit done( i18n( "Registration Finished" ), i18n( "Registration has been completed successfully." ) );
				}
				else {
					emit error( i18n( "Registration Error" ), i18n( "Incorrect data sent to server." ) );
					state = RegisterStateGotToken;
				}
				gg_free_register( session_ );
				session_ = NULL;
				disconnect( this, SLOT(watcher()) );
				deleteLater();
				return;
				break;
		}
		enableNotifiers( session_->check );
		return;
	}
}
예제 #4
0
////////////////////////////////////////////////////////////////////////////////
// Gets GG token
int gg_gettoken(GGPROTO *gg, GGTOKEN *token)
{
	struct gg_http *h = NULL;
	struct gg_token *t = NULL;
	IMGSRVC_MEMIO memio = {0};
	GGTOKENDLGDATA dat = {0};

	// Zero tokens
	strcpy(token->id, "");
	strcpy(token->val, "");

	if(!(h = gg_token(0)) || gg_token_watch_fd(h) || h->state == GG_STATE_ERROR || h->state != GG_STATE_DONE)
	{
		char error[128];
		mir_snprintf(error, sizeof(error), Translate("Token retrieval failed because of error:\n\t%s"), http_error_string(h ? h->error : 0));
		MessageBox(
				NULL,
				error,
				GG_PROTONAME,
				MB_OK | MB_ICONSTOP
		);
		gg_free_pubdir(h);
		return FALSE;
	}

	if (!(t = (struct gg_token *)h->data) || (!h->body))
	{
		char error[128];
		mir_snprintf(error, sizeof(error), Translate("Token retrieval failed because of error:\n\t%s"), http_error_string(h ? h->error : 0));
		MessageBox(
				NULL,
				error,
				GG_PROTONAME,
				MB_OK | MB_ICONSTOP
		);
		gg_free_pubdir(h);
		return FALSE;
	}

	// Return token id
	strncpy(dat.id, t->tokenid, sizeof(dat.id));
	dat.width = t->width;
	dat.height = t->height;

	// Load bitmap
	memio.iLen = h->body_size;
	memio.pBuf = (void *)h->body;
	memio.fif = -1; /* detect */
	memio.flags = 0;
	dat.hBitmap = (HBITMAP) CallService(MS_IMG_LOADFROMMEM, (WPARAM) &memio, 0);
	if(dat.hBitmap == NULL)
	{
		MessageBox(
				NULL,
				Translate("Could not load token image."),
				GG_PROTONAME,
				MB_OK | MB_ICONSTOP
		);
		gg_free_pubdir(h);
		return FALSE;
	}

	// Load token dialog
	if(DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_TOKEN), NULL, gg_tokendlgproc, (LPARAM)&dat) == IDCANCEL)
		return FALSE;

	// Fillup patterns
	strncpy(token->id, dat.id, sizeof(token->id));
	strncpy(token->val, dat.val, sizeof(token->val));

	return TRUE;
}
예제 #5
0
/**
 * Funkcja wywoływana po zaobserwowaniu zmian na deskryptorze połączenia.
 *
 * Operacja będzie zakończona, gdy pole \c state będzie równe \c GG_STATE_DONE.
 * Jeśli wystąpi błąd, \c state będzie równe \c GG_STATE_ERROR, a kod błędu
 * znajdzie się w polu \c error.
 *
 * \param h Struktura połączenia
 *
 * \return 0 jeśli się powiodło, -1 w przypadku błędu
 *
 * \ingroup token
 */
int gg_token_watch_fd(struct gg_http *h)
{
	if (!h) {
		errno = EFAULT;
		return -1;
	}

	if (h->state == GG_STATE_ERROR) {
		gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
		errno = EINVAL;
		return -1;
	}
	
	if (h->state != GG_STATE_PARSING) {
		if (gg_http_watch_fd(h) == -1) {
			gg_debug(GG_DEBUG_MISC, "=> token, http failure\n");
			errno = EINVAL;
			return -1;
		}
	}

	if (h->state != GG_STATE_PARSING)
		return 0;
	
	/* jeśli h->data jest puste, to ściągaliśmy tokenid i url do niego,
	 * ale jeśli coś tam jest, to znaczy, że mamy drugi etap polegający
	 * na pobieraniu tokenu. */
	if (!h->data) {
		int width, height, length;
		char *url = NULL, *tokenid = NULL, *path, *headers;
		const char *host;
		struct gg_http *h2;
		struct gg_token *t;

		gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body);

		if (h->body && (!(url = (char*)malloc(strlen(h->body) + 1)) || !(tokenid = (char*)malloc(strlen(h->body) + 1)))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n");
			free(url);
			return -1;
		}
		
		if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) {
			gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
			free(url);
			free(tokenid);
			errno = EINVAL;
			return -1;
		}
		
		/* dostaliśmy tokenid i wszystkie niezbędne informacje,
		 * więc pobierzmy obrazek z tokenem */

		if (strncmp(url, "http://", 7)) {
			path = gg_saprintf("%s?tokenid=%s", url, tokenid);
			host = GG_REGISTER_HOST;
		} else {
			char *slash = strchr(url + 7, '/');

			if (slash) {
				path = gg_saprintf("%s?tokenid=%s", slash, tokenid);
				*slash = 0;
				host = url + 7;
			} else {
				gg_debug(GG_DEBUG_MISC, "=> token, url parsing failed\n");
				free(url);
				free(tokenid);
				errno = EINVAL;
				return -1;
			}
		}

		if (!path) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
			free(url);
			free(tokenid);
			return -1;
		}

		if (!(headers = gg_saprintf("Host: %s\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n", host))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
			free(path);
			free(url);
			free(tokenid);
			return -1;
		}			

		if (!(h2 = gg_http_connect(host, GG_REGISTER_PORT, h->async, "GET", path, headers))) {
			gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
			free(headers);
			free(url);
			free(path);
			free(tokenid);
			return -1;
		}

		free(headers);
		free(path);
		free(url);

		gg_http_free_fields(h);

		memcpy(h, h2, sizeof(struct gg_http));
		free(h2);

		h->type = GG_SESSION_TOKEN;

		h->callback = gg_token_watch_fd;
		h->destroy = gg_token_free;
	
		if (!h->async)
			gg_token_watch_fd(h);

		if (!(h->data = t = (struct gg_token*)malloc(sizeof(struct gg_token)))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n");
			free(tokenid);
			return -1;
		}

		t->width = width;
		t->height = height;
		t->length = length;
		t->tokenid = tokenid;
	} else {
		/* obrazek mamy w h->body */
		h->state = GG_STATE_DONE;
	}
	
	return 0;
}
예제 #6
0
/*
 * gg_token_watch_fd()
 *
 * przy asynchronicznych operacjach zwi±zanych z tokenem nale¿y wywo³ywaæ
 * tê funkcjê przy zmianach na obserwowanym deskryptorze.
 *
 *  - h - struktura opisuj±ca po³±czenie
 *
 * je¶li wszystko posz³o dobrze to 0, inaczej -1. operacja bêdzie
 * zakoñczona, je¶li h->state == GG_STATE_DONE. je¶li wyst±pi jaki¶
 * b³±d, to bêdzie tam GG_STATE_ERROR i odpowiedni kod b³êdu w h->error.
 */
int gg_token_watch_fd(struct gg_http *h)
{
	if (!h) {
		errno = EINVAL;
		return -1;
	}

        if (h->state == GG_STATE_ERROR) {
                gg_debug(GG_DEBUG_MISC, "=> token, watch_fd issued on failed session\n");
                errno = EINVAL;
                return -1;
        }
	
	if (h->state != GG_STATE_PARSING) {
		if (gg_http_watch_fd(h) == -1) {
			gg_debug(GG_DEBUG_MISC, "=> token, http failure\n");
                        errno = EINVAL;
			return -1;
		}
	}

	if (h->state != GG_STATE_PARSING)
                return 0;
	
	/* je¶li h->data jest puste, to ¶ci±gali¶my tokenid i url do niego,
	 * ale je¶li co¶ tam jest, to znaczy, ¿e mamy drugi etap polegaj±cy
	 * na pobieraniu tokenu. */
	if (!h->data) {
		int width, height, length;
		char *url = NULL, *tokenid = NULL, *path;
		struct gg_http *h2;
		struct gg_token *t;

		gg_debug(GG_DEBUG_MISC, "=> token body \"%s\"\n", h->body);

		if (h->body && (!(url = malloc(strlen(h->body))) || !(tokenid = malloc(strlen(h->body))))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for results\n");
			free(url);
			return -1;
		}
		
		if (!h->body || sscanf(h->body, "%d %d %d\r\n%s\r\n%s", &width, &height, &length, tokenid, url) != 5) {
			gg_debug(GG_DEBUG_MISC, "=> token, parsing failed\n");
			free(url);
			free(tokenid);
			return -1;
		}
		
		/* dostali¶my tokenid i wszystkie niezbêdne informacje,
		 * wiêc pobierzmy obrazek z tokenem */

		if (!(path = gg_saprintf("%s?tokenid=%s", url, tokenid))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token url\n");
			free(url);
			free(tokenid);
			return -1;
		}

		free(url);
	
		if (!(h2 = gg_http_connect(GG_APPMSG_HOST, GG_APPMSG_PORT, h->async, "GET", path, "Host: " GG_APPMSG_HOST "\r\nUser-Agent: " GG_HTTP_USERAGENT "\r\n\r\n"))) {
			gg_debug(GG_DEBUG_MISC, "=> token, gg_http_connect() failed mysteriously\n");
			free(path);
			free(tokenid);
			return -1;
		}

		free(path);

		memcpy(h, h2, sizeof(struct gg_http));
		free(h2);

		h->type = GG_SESSION_TOKEN;

		h->callback = gg_token_watch_fd;
		h->destroy = gg_token_free;
	
		if (!h->async)
			gg_token_watch_fd(h);

		if (!(h->data = t = malloc(sizeof(struct gg_token)))) {
			gg_debug(GG_DEBUG_MISC, "=> token, not enough memory for token data\n");
			free(tokenid);
			return -1;
		}

		t->width = width;
		t->height = height;
		t->length = length;
		t->tokenid = tokenid;
	} else {
		/* obrazek mamy w h->body */
		h->state = GG_STATE_DONE;
	}
	
	return 0;
}