void LoginSession::GetHostname(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); // TODO: hook the below code up to the database, we may // want to send them to a diffrent server if say portal = bot? auto loginName = requestNode->first_node("LoginName")->value(); auto provider = requestNode->first_node("Provider")->value(); // Debug message. printf("User %s is logging in using %s\n", loginName, provider); int sequence = Packet->m_Meta[2] - '0'; // Form a packet, the only element is the detination host name // GW2 will then try to connect to the specified server. GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("Hostname", "cligate-fra.101.ncplatform.net."); // Signal that there is TLS data to be sent next time round. SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload()); packet.m_TLSSendBufferLength = strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); }
void LoginSession::StartSsoLogin(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); char password[1024]; memset(password, 0, 1024); int passwordLength = -1; char* username = nullptr; char* passwordBase64 = nullptr; try { username = requestNode->first_node("LoginName")->value(); if (requestNode->first_node("Password") != nullptr) { passwordBase64 = requestNode->first_node("Password")->value(); auto bio = BIO_new_mem_buf(passwordBase64, -1); auto b64 = BIO_new(BIO_f_base64()); bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); passwordLength = BIO_read(bio, password, strlen(passwordBase64)); BIO_free_all(bio); } } catch(std::exception ex) { printf("Password tokens not supported.\n"); return; } // TODO: add support for resume tokens if (passwordBase64 == nullptr) { printf("Resume tokens not supported yet\n"); m_TSLReady = false; return; } printf("Login >> %s with %s\n", username, password); int sequence = Packet->m_Meta[2] - '0'; const char* temporary_guid = "0687C32C-0331-E611-80C3-ECB1D78A5C75"; const char* temporary_resumeToken = "22236HTR-CCCC-CCCC-CCCC-2310CCCCC93A"; const char* temporary_username = "******"; GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("UserId", temporary_guid); replyPacket.AddElement("UserCenter", "5"); replyPacket.AddElement("UserName", temporary_username); replyPacket.AddElement("Parts", ""); replyPacket.AddElement("ResumeToken", temporary_resumeToken); replyPacket.AddElement("EmailVerified", "1"); SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload()); packet.m_TLSSendBufferLength = strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); }
void LoginSession::RequestGameToken(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); auto gameCode = requestNode->first_node("GameCode")->value(); auto accountAlias = requestNode->first_node("AccountAlias")->value(); printf("Generating Session Token.\n"); int sequence = Packet->m_Meta[2] - '0'; // Form a packet, the only element is the detination host name // GW2 will then try to connect to the specified server. GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("Token", "fe9484c3-d53a-4225-a2d6-096be358af73"); // Signal that there is TLS data to be sent next time round. SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload()); packet.m_TLSSendBufferLength = (int)strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); printf("Handing client to Auth2.101.ArenaNetworks.com\n"); m_LogoutRequested = true; }
GYBOOL GYTestPacketHandler(GYGatewaySession& gatewaySession, const GYGUID& guid, GYPacketInteface& packet) { const GYTestPacket& tPacket = static_cast<GYTestPacket&>(packet); GYSCTest replyPacket(GETSTRINGMANAGERSINGLETON); replyPacket.SetName(tPacket.GetName()); replyPacket.SetUserID(guid); replyPacket.SetGatewayReceiveTime(tPacket.GetGatewayReceiveTime()); replyPacket.SetLogicReceiveGatewayPacketTime(GYTimeController::GetCpuTime()); gatewaySession.SendPacket(guid, replyPacket); return GYTRUE; }
void LoginSession::QueueLoginErrorMessage(int sequence) { // Create the error packet GW2Packet replyPacket("", sequence, PT_REPLY_FAIL); replyPacket.Fill(); replyPacket.SetErrorStatue("11"); // Send it off SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload("ErrBadPasswd")); packet.m_TLSSendBufferLength = (int)strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); }
void LoginSession::RequestGameToken(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); auto gameCode = requestNode->first_node("GameCode")->value(); auto accountAlias = requestNode->first_node("AccountAlias")->value(); printf("Generating Session Token.\n"); int sequence = Packet->m_Meta[2] - '0'; // Form a packet, the only element is the detination host name // GW2 will then try to connect to the specified server. GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("Token", "0XXXX32C-XXXX-XXXX-XXXX-XXXXD78XXXX5"); // Signal that there is TLS data to be sent next time round. SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload()); packet.m_TLSSendBufferLength = strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); }
void LoginSession::StartSsoLogin(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); char password[1024]; char passwordToken[1024]; memset(password, 0, 1024); memset(passwordToken, 0, 1024); int passwordLength = -1; int passwordTokenLength = -1; char* emailaddress = nullptr; char* passwordBase64 = nullptr; char* passwordTokenBase64 = nullptr; std::string sha256Password; std::string guid; std::string username; std::string decodedToken; try { emailaddress = requestNode->first_node("LoginName")->value(); if (requestNode->first_node("PasswordToken") != nullptr) { passwordTokenBase64 = requestNode->first_node("PasswordToken")->value(); auto bio = BIO_new_mem_buf(passwordTokenBase64, -1); auto b64 = BIO_new(BIO_f_base64()); bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); passwordTokenLength = BIO_read(bio, passwordToken, (int)strlen(passwordTokenBase64)); BIO_free_all(bio); } else if (requestNode->first_node("Password") != nullptr) { passwordBase64 = requestNode->first_node("Password")->value(); auto bio = BIO_new_mem_buf(passwordBase64, -1); auto b64 = BIO_new(BIO_f_base64()); bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); passwordLength = BIO_read(bio, password, (int)strlen(passwordBase64)); BIO_free_all(bio); } else { int sequence = Packet->m_Meta[2] - '0'; QueueLoginErrorMessage(sequence); m_LogoutRequested = true; printf("Unsupported authentication method.\n"); return; } auto userQuery = Database::Get().PrepareQuery("SELECT * FROM cligate.Users where userEmail = %0q;"); auto result = userQuery.store(emailaddress); if (result.size() != 0) { if (result.size() > 1) { printf("Data consistency error, an email address appear's more than once in the users table."); } sha256Password = std::string(result.front()["userPassword"]).c_str(); guid = std::string(result.front()["userGuid"]).c_str(); username = std::string(result.front()["userName"]).c_str(); } } catch(std::exception ex) { printf("Unexpected authentication error: %s.\n", ex.what()); int sequence = Packet->m_Meta[2] - '0'; QueueLoginErrorMessage(sequence); m_LogoutRequested = true; return; } catch (const mysqlpp::BadQuery& er) { std::cerr << "Query error: " << er.what() << std::endl; m_LogoutRequested = true; return; } catch (const mysqlpp::BadConversion& er) { std::cerr << "Conversion error: " << er.what() << std::endl << "\tretrieved data size: " << er.retrieved << ", actual size: " << er.actual_size << std::endl; m_LogoutRequested = true; return; } catch (const mysqlpp::Exception& er) { std::cerr << "Error: " << er.what() << std::endl; m_LogoutRequested = true; return; } // Check if there is no password present, if so try using the password token, then try // using a password if (passwordTokenBase64 != nullptr) { if (CheckResumeToken(guid.c_str(), passwordToken)) { printf("Client %s using resume token %s\n", guid.c_str(), passwordToken); } else { printf("Resume token %s failed\n", passwordToken); int sequence = Packet->m_Meta[2] - '0'; QueueLoginErrorMessage(sequence); m_LogoutRequested = true; return; } } else if (passwordBase64 != nullptr) { eSHA256::SHA256 sha256; if (sha256(password).compare(sha256Password) != 0) { int sequence = Packet->m_Meta[2] - '0'; QueueLoginErrorMessage(sequence); m_LogoutRequested = true; return; } } else { printf("Unexpected authentication error\n"); int sequence = Packet->m_Meta[2] - '0'; QueueLoginErrorMessage(sequence); m_LogoutRequested = true; } // Ugly hack to get the sequence number int sequence = Packet->m_Meta[2] - '0'; // Persist the ResumeToken to the DB std::string resumetoken = CreateGuid(); SaveResumeToken(guid.c_str(), resumetoken.c_str()); GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("UserId", guid.c_str()); replyPacket.AddElement("UserCenter", "5"); replyPacket.AddElement("UserName", username.c_str()); replyPacket.AddElement("Parts", ""); replyPacket.AddElement("ResumeToken", resumetoken.c_str()); replyPacket.AddElement("EmailVerified", "1"); SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, replyPacket.Payload()); packet.m_TLSSendBufferLength = (int)strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); // Assume that the login information was correct, persist the email address for this client. m_ClientEmail = std::string(emailaddress); }
void LoginSession::GetHostname(XMLPacket *Packet) { rapidxml::xml_node<>* requestNode = Packet->m_XMLDocument.first_node("Request"); bool validUser = false; int userId = -1; std::string userRegion; std::string userGateway; // TODO: hook the below code up to the database, we may // want to send them to a diffrent server if say portal = bot? auto loginName = requestNode->first_node("LoginName")->value(); auto provider = requestNode->first_node("Provider")->value(); try { auto userQuery = Database::Get().PrepareQuery("SELECT * FROM cligate.Users where userEmail = %0q;"); auto gatewayQuery = Database::Get().PrepareQuery("SELECT * FROM cligate.Gates WHERE gateRegion = %0q;"); auto result = userQuery.store(loginName); if (result.size() != 0) { validUser = true; if (result.size() > 1) { printf("Data consistency error, an email address appear's more than once in the users table."); } userId = atoi(std::string(result.front()["userId"]).c_str()); userRegion = std::string(result.front()["userRegion"]).c_str(); } result = gatewayQuery.store(userRegion); if (result.size() != 0) { validUser = true; if (result.size() > 1) { printf("Data consistency error, more than one gateway exists for a region."); } userGateway = std::string(result.front()["gateAddress"]).c_str(); } } catch (const mysqlpp::BadQuery& er) { std::cerr << "Query error: " << er.what() << std::endl; m_LogoutRequested = true; return; } catch (const mysqlpp::BadConversion& er) { std::cerr << "Conversion error: " << er.what() << std::endl << "\tretrieved data size: " << er.retrieved << ", actual size: " << er.actual_size << std::endl; m_LogoutRequested = true; return; } catch (const mysqlpp::Exception& er) { std::cerr << "Error: " << er.what() << std::endl; m_LogoutRequested = true; return; } // Debug message. printf("User %s is logging in using %s\n", loginName, provider); printf("Forwarding %s to %s\n", loginName, userGateway.c_str()); int sequence = Packet->m_Meta[2] - '0'; // Form a packet, the only element is the detination host name // GW2 will then try to connect to the specified server. GW2Packet replyPacket("", sequence, PT_REPLY); replyPacket.AddElement("Hostname", userGateway.c_str()); //replyPacket.AddElement("Hostname", "cligate-fra.101.ncplatform.net."); // Signal that there is TLS data to be sent next time round. SessionSendPacket packet; memset(packet.m_TLSSendBuffer, 0, 4096); sprintf(packet.m_TLSSendBuffer, "%s", replyPacket.Payload()); packet.m_TLSSendBufferLength = (int)strlen(packet.m_TLSSendBuffer); packet.m_TLSSendNeeded = true; m_SendPackets.push_back(packet); m_LogoutRequested = true; }