/** * 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(); }
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; } }
//////////////////////////////////////////////////////////////////////////////// // 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; }
/** * 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; }
/* * 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; }