166 lines
6 KiB
C++
166 lines
6 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Renegade *
|
|
* *
|
|
* $Archive:: /Commando/Code/Commando/CDKeyAuth.cpp $*
|
|
* *
|
|
* Original Author:: Brian Hayes *
|
|
* *
|
|
* $Author:: Bhayes $*
|
|
* *
|
|
* $Modtime:: 3/15/02 2:56p $*
|
|
* *
|
|
* $Revision:: 3 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include <GameSpy\gcdkeyserver.h>
|
|
#include <GameSpy\gcdkeyclient.h>
|
|
#include <GameSpy\nonport.h>
|
|
#include <GameSpy\gs_md5.h>
|
|
#include <stdlib.h>
|
|
#include "wwdebug.h"
|
|
#include "CDKeyAuth.h"
|
|
#include "gamespyauthmgr.h"
|
|
#include "registry.h"
|
|
#include "playermanager.h"
|
|
#include "_globals.h"
|
|
#include "ServerSettings.h"
|
|
|
|
// static void c_auth_callback(int localid, int authenticated, char *errmsg, void *instance)
|
|
// {
|
|
// ((CCDKeyAuth *)instance)->auth_callback(localid, authenticated, errmsg);
|
|
// }
|
|
|
|
|
|
//generate a rand nchar challenge
|
|
char * CCDKeyAuth::GenChallenge(int nchars)
|
|
{
|
|
static char s[33];
|
|
if (nchars > 32) nchars = 32;
|
|
s[nchars] = 0;
|
|
while (nchars--)
|
|
{
|
|
s[nchars] = (char)('a' + rand() % 26);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/* Callback function to indicate whether a client has been authorized or not.
|
|
If the client has been, then we send them a "welcome" string, representative of
|
|
allowing them to "enter" the game. If they have not been authenticated, we dump
|
|
them after sending an error message */
|
|
void CCDKeyAuth::auth_callback(int localid, int authenticated, char *errmsg, void *instance)
|
|
{
|
|
// client_t *clients = (client_t *)instance;
|
|
// char outbuf[512];
|
|
|
|
WWDEBUG_SAY(("CDKeyAuth -- %d:%d:%s\n", localid, authenticated, errmsg));
|
|
|
|
cPlayer * p_player = cPlayerManager::Find_Player(localid);
|
|
if (p_player != NULL) {
|
|
|
|
if (!authenticated) //doh.. bad!
|
|
{
|
|
// This client failed.
|
|
//p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_REJECTING);
|
|
//cGameSpyAuthMgr::Evict_Player(localid);
|
|
cGameSpyAuthMgr::Initiate_Auth_Rejection(localid);
|
|
|
|
// printf("Client %d was NOT authenticated (%s)\n",localid, errmsg);
|
|
// sprintf(outbuf,"E:%s\n",errmsg);
|
|
// send(clients[localid].sock, outbuf, strlen(outbuf),0);
|
|
// shutdown(clients[localid].sock, 2);
|
|
// closesocket(clients[localid].sock);
|
|
// clients[localid].sock = INVALID_SOCKET;
|
|
} else
|
|
{
|
|
// This client passed.
|
|
p_player->Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_ACCEPTED);
|
|
// printf("Client %d was authenticated (%s)\n",localid, errmsg);
|
|
// sprintf(outbuf,"M:Welcome to the game, have fun! (%s)\n",errmsg);
|
|
// send(clients[localid].sock, outbuf, strlen(outbuf),0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCDKeyAuth::DisconnectUser(int localid) {
|
|
gcd_disconnect_user(localid);
|
|
|
|
}
|
|
|
|
void CCDKeyAuth::AuthenticateUser(int localid, ULONG ip, char *challenge, char *authstring) {
|
|
|
|
// Customize this with our playerdata struct
|
|
// Take the response from our challenge that we sent to the client
|
|
// and send it off to the Authserver along with the original challenge
|
|
|
|
gcd_authenticate_user(localid, ip, challenge, authstring, CCDKeyAuth::auth_callback, NULL);
|
|
|
|
}
|
|
|
|
|
|
void CCDKeyAuth::AuthSerial(const char *challenge, StringClass &resp) {
|
|
|
|
char response[RESPONSE_SIZE];
|
|
StringClass sserial;
|
|
|
|
WWASSERT(challenge);
|
|
|
|
GetSerialNum(sserial);
|
|
|
|
const char *serial = sserial;
|
|
|
|
char *cdkey = new char [strlen(serial)+1];
|
|
char *outb = cdkey;
|
|
const char *linep = serial;
|
|
char md5hash[33];
|
|
|
|
while (*linep) {
|
|
if (*linep >= '0' && *linep <= '9') {
|
|
*outb++ = *linep;
|
|
}
|
|
linep++;
|
|
}
|
|
*outb = 0;
|
|
|
|
// MD5 Hash Here.
|
|
MD5Digest((BYTE *)cdkey, strlen(cdkey), md5hash);
|
|
|
|
// hashserial, challenge, outbuf
|
|
gcd_compute_response(md5hash, challenge, response);
|
|
|
|
delete [] cdkey;
|
|
resp = response;
|
|
}
|
|
|
|
void CCDKeyAuth::GetSerialNum(StringClass &serial) {
|
|
|
|
RegistryClass main_reg(APPLICATION_SUB_KEY_NAME);
|
|
StringClass stringval;
|
|
StringClass serial_out;
|
|
main_reg.Get_String("Serial", stringval);
|
|
ServerSettingsClass::Encrypt_Serial(stringval, serial, false);
|
|
}
|