diff --git a/Extension/steamtools/blob.h b/Extension/steamtools/blob.h new file mode 100644 index 0000000..f2b1b63 --- /dev/null +++ b/Extension/steamtools/blob.h @@ -0,0 +1,133 @@ +/* + * ====================================================== + * OpenCoordinator + * Copyright (C) 2011 The OpenCoordinator Team. + * All rights reserved. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +/* Modified for SteamWorks, taken from SteamTools. */ + +#pragma once + +class CBlob +{ +public: + CBlob(const void *pMessage, size_t iSize) + : m_pMessage(pMessage) + , m_iSize(iSize) + , m_iCurrentOffset(0) + {}; + +private: + const void *m_pMessage; + size_t m_iSize; + size_t m_iCurrentOffset; + +public: + inline size_t GetPosition() + { + return m_iCurrentOffset; + } + + inline size_t AdvancePosition(size_t iAdditionalOffset) + { + m_iCurrentOffset += iAdditionalOffset; + return m_iCurrentOffset; + } + + inline size_t RewindPosition(size_t iAdditionalNegativeOffset) + { + m_iCurrentOffset -= iAdditionalNegativeOffset; + return m_iCurrentOffset; + } + + inline void SetPosition(size_t iNewOffset) + { + m_iCurrentOffset = iNewOffset; + } + + inline void ResetPosition() + { + m_iCurrentOffset = 0; + } + + inline bool CanStillRead(void) + { + return (m_iCurrentOffset >= m_iSize); + } + +public: + template + inline T Read(bool *bError = NULL) + { + if ((m_iCurrentOffset + sizeof(T)) > m_iSize) + { + if (bError) + *bError = true; + return (T)0; + } + + T tempBuffer = *((T *)((intptr_t)m_pMessage + m_iCurrentOffset)); + m_iCurrentOffset += sizeof(T); + + if (bError) + *bError = false; + + return tempBuffer; + } + + template + inline bool Read(T *pOut) + { + if ((m_iCurrentOffset + sizeof(T)) > m_iSize) + return false; + + T *pTempBuffer = (T *)((intptr_t)m_pMessage + m_iCurrentOffset); + m_iCurrentOffset += sizeof(T); + memcpy(pOut, pTempBuffer, sizeof(T)); + + return true; + } + + template + inline bool Read(T &Out) + { + if ((m_iCurrentOffset + sizeof(T)) > m_iSize) + return false; + + T *pTempBuffer = (T *)((intptr_t)m_pMessage + m_iCurrentOffset); + m_iCurrentOffset += sizeof(T); + Out = *pTempBuffer; + + return true; + } + + inline bool Read(void *pOut, size_t iLength) + { + if ((m_iCurrentOffset + iLength) > m_iSize) + return false; + + void *pTempBuffer = (void *)((intptr_t)m_pMessage + m_iCurrentOffset); + m_iCurrentOffset += iLength; + memcpy(pOut, pTempBuffer, iLength); + + return true; + } +}; \ No newline at end of file diff --git a/Extension/steamtools/ticket.h b/Extension/steamtools/ticket.h new file mode 100644 index 0000000..29f79b3 --- /dev/null +++ b/Extension/steamtools/ticket.h @@ -0,0 +1,239 @@ +/* + This file is part of SourcePawn SteamWorks. + + SourcePawn SteamWorks 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. + + SourcePawn SteamWorks 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 SourcePawn SteamWorks. If not, see . + + Author: Kyle Sanderson (KyleS). +*/ + +#pragma once + +#include "blob.h" +class GCTokenSection +{ +public: + GCTokenSection(CBlob &blob) + { + blob.Read(this->length); + + if (this->length != this->expectedlen) + { + this->bValid = false; + return; + } + + blob.Read(this->token); + blob.Read(this->steamid); + this->bValid = blob.Read(this->generation); + }; +public: + bool IsValid(void) + { + return this->bValid; + } + +public: /* No ideal packing, but it saves us from having to comment. */ + static const uint32 expectedlen = 20; /* Magic number for GC? */ + uint32 length; + uint64 token; + CSteamID steamid; + time_t generation; + bool bValid; +}; + +class SessionSection +{ +public: + SessionSection(CBlob &blob) + { + blob.Read(this->length); + + if (this->length != this->expectedlen) + { + this->bValid = false; + return; + } + + blob.Read(this->unk1); + blob.Read(this->unk2); + blob.Read(this->externalip); + blob.Read(this->filler); + blob.Read(this->timestamp); + this->bValid = blob.Read(this->connectioncount); + } +public: + bool IsValid(void) + { + return this->bValid; + } + +public: + static const uint32 expectedlen = 24; /* Magic number for Session? */ + uint32 length; + uint32 unk1; + uint32 unk2; + uint32 externalip; + uint32 filler; + uint32 timestamp; + uint32 connectioncount; + bool bValid; +}; + +class DLCInfo +{ +public: + DLCInfo() : pSub(NULL) + { + }; + + ~DLCInfo() + { + delete [] this->pSub; + }; +public: + void TakeBlob(CBlob &blob) + { + blob.Read(this->appid); + blob.Read(this->subcount); + + this->pSub = new uint32[this->subcount]; + + if (this->pSub == NULL) + { + return; + } + + for (size_t iter = 0; iter < this->subcount; ++iter) + { + blob.Read(this->pSub[iter]); + } + } +public: + uint32 appid; + uint16 subcount; + uint32 *pSub; +}; + +class OwnershipSection +{ +public: + OwnershipSection(CBlob &blob) + { + blob.Read(this->length); + + if (this->length == 0) + { + this->pLicense = NULL; + this->pDLC = NULL; + this->bValid = false; + return; + } + + blob.Read(this->length); + blob.Read(this->version); + blob.Read(this->steamid); + blob.Read(this->appid); + blob.Read(this->externalIP); + blob.Read(this->internalIP); + blob.Read(this->ownershipFlags); + blob.Read(this->ticketGeneration); + blob.Read(this->ticketExpiration); + blob.Read(this->licenseCount); + + this->pLicense = new uint32[this->licenseCount]; + + if (this->pLicense == NULL) + { + this->pDLC = NULL; + this->bValid = false; + return; + } + + for (size_t iter = 0; iter < this->licenseCount; ++iter) + { + blob.Read(this->pLicense[iter]); + } + + blob.Read(this->dlcCount); + this->pDLC = new DLCInfo[this->dlcCount]; + if (this->pDLC == NULL) + { + this->bValid = false; + return; + } + + for (size_t iter = 0; iter < this->dlcCount; ++iter) + { + this->pDLC[iter].TakeBlob(blob); + } + + blob.Read(this->reserved); + bValid = blob.Read(this->signature, sizeof(this->signature)); + }; + + ~OwnershipSection() + { + delete [] this->pLicense; + delete [] this->pDLC; + } +public: + bool IsValid(void) + { + return this->bValid; + } + +public: + uint32 length; + uint32 version; + uint64 steamid; + uint32 appid; + uint32 externalIP; + uint32 internalIP; + uint32 ownershipFlags; + time_t ticketGeneration; + time_t ticketExpiration; + uint16 licenseCount; + uint32 *pLicense; + uint16 dlcCount; + DLCInfo *pDLC; + uint16 reserved; + unsigned char signature[128]; + bool bValid; +}; + +class AuthBlob /* Concept and CBlob adapted from SteamTools; Ticket Information from OpenSteamWorks. */ +{ +public: + AuthBlob(const void *pAuthTicket, int cbAuthTicket) + { + CBlob blob(pAuthTicket, cbAuthTicket); + this->pGCTokenSection = new GCTokenSection(blob); + this->pSessionSection = new SessionSection(blob); + this->pOwnershipSection = new OwnershipSection(blob); + + this->bExpectedTicket = (this->pGCTokenSection->IsValid() && this->pSessionSection->IsValid() && this->pOwnershipSection->IsValid()); + } + + ~AuthBlob() + { + delete pGCTokenSection; + delete pSessionSection; + delete pOwnershipSection; + } +public: + GCTokenSection *pGCTokenSection; + SessionSection *pSessionSection; + OwnershipSection *pOwnershipSection; + bool bExpectedTicket; +};