2014-11-22 16:30:56 +01:00
|
|
|
/*
|
|
|
|
* This file is a part of Winix
|
|
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2021-04-09 17:50:58 +02:00
|
|
|
* Copyright (c) 2014-2021, Tomasz Sowa
|
2014-11-22 16:30:56 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "sessionidmanager.h"
|
|
|
|
#include "space/spaceparser.h"
|
|
|
|
#include "utf8/utf8.h"
|
|
|
|
#include "date/date.h"
|
|
|
|
#include "misc.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Winix
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
SessionIdManager::SessionIdManager()
|
|
|
|
{
|
|
|
|
algorithm_type = 'a';
|
|
|
|
key_tab_size = 256;
|
|
|
|
key_index = 0;
|
|
|
|
last_key_generated = 0;
|
|
|
|
key_renew_time = 60;
|
|
|
|
was_inited = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::Init(const std::wstring & keys_file)
|
|
|
|
{
|
|
|
|
was_inited = true;
|
|
|
|
|
|
|
|
key_tab1.resize(key_tab_size);
|
|
|
|
key_tab2.resize(key_tab_size);
|
|
|
|
|
|
|
|
aes1.resize(key_tab_size);
|
|
|
|
aes2.resize(key_tab_size);
|
|
|
|
|
|
|
|
key_file_name = keys_file;
|
|
|
|
ReadKeysFromFile(key_file_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::SetKeyRenewTime(time_t renew_time)
|
|
|
|
{
|
|
|
|
key_renew_time = renew_time;
|
|
|
|
|
|
|
|
if( key_renew_time < 10 )
|
|
|
|
key_renew_time = 10;
|
|
|
|
|
|
|
|
time_t one_month = 60 * 60 * 24 * 31;
|
|
|
|
|
|
|
|
if( key_renew_time > one_month )
|
|
|
|
key_renew_time = one_month;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
void SessionIdManager::ReadKey(const wchar_t * name, pt::Space & space, std::vector<std::string> & dest_key)
|
2014-11-22 16:30:56 +01:00
|
|
|
{
|
|
|
|
std::vector<std::wstring> keys;
|
|
|
|
std::string key_ascii, key_base64_decoded;
|
|
|
|
|
2021-04-09 17:50:58 +02:00
|
|
|
space.to_list(name, keys);
|
2014-11-22 16:30:56 +01:00
|
|
|
|
|
|
|
for(size_t i=0 ; i<key_tab_size ; ++i)
|
|
|
|
dest_key[i].clear();
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<keys.size() && i<key_tab_size ; ++i)
|
|
|
|
{
|
|
|
|
dest_key[i].clear();
|
|
|
|
|
2021-05-21 00:41:27 +02:00
|
|
|
if( pt::wide_to_utf8(keys[i], key_ascii) )
|
2014-11-22 16:30:56 +01:00
|
|
|
{
|
|
|
|
if( base64.Decode(key_ascii, key_base64_decoded) )
|
|
|
|
{
|
|
|
|
size_t len = key_base64_decoded.size();
|
|
|
|
|
|
|
|
if( len == 16 || len == 24 || len == 32 )
|
|
|
|
{
|
|
|
|
dest_key[i] = key_base64_decoded;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::InitializeAesKeys(size_t index)
|
|
|
|
{
|
|
|
|
if( !aes1[index].Key((unsigned char*)key_tab1[index].c_str(), key_tab1[index].size()) )
|
|
|
|
log << log1 << "SIM: I cannot initialize a key1, size of the key: " << key_tab1[index].size() << logend;
|
|
|
|
|
|
|
|
if( !aes2[index].Key((unsigned char*)key_tab2[index].c_str(), key_tab2[index].size()) )
|
|
|
|
log << log1 << "SIM: I cannot initialize a key2, size of the key: " << key_tab2[index].size() << logend;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::InitializeAesKeys()
|
|
|
|
{
|
|
|
|
for(size_t i=0 ; i < key_tab_size ; ++i)
|
|
|
|
{
|
|
|
|
if( AreKeysCorrect(i) )
|
|
|
|
InitializeAesKeys(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::ReadKeysFromFile(const wchar_t * file)
|
|
|
|
{
|
2021-05-20 20:59:12 +02:00
|
|
|
pt::Space space;
|
|
|
|
pt::SpaceParser parser;
|
|
|
|
pt::Date date;
|
2014-11-22 16:30:56 +01:00
|
|
|
|
2021-05-21 04:51:58 +02:00
|
|
|
pt::SpaceParser::Status status = parser.parse_space_file(file, space);
|
2014-11-22 16:30:56 +01:00
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
if( status == pt::SpaceParser::ok )
|
2014-11-22 16:30:56 +01:00
|
|
|
{
|
2021-04-09 17:50:58 +02:00
|
|
|
key_index = space.to_ulong(L"key_index");
|
2014-11-22 16:30:56 +01:00
|
|
|
|
|
|
|
if( key_index >= 256 )
|
|
|
|
key_index = 0;
|
|
|
|
|
2021-04-09 17:50:58 +02:00
|
|
|
if( date.Parse(space.to_wstr(L"last_key_generated", L"0")) )
|
2014-11-22 16:30:56 +01:00
|
|
|
last_key_generated = date.ToTime();
|
|
|
|
|
|
|
|
ReadKey(L"key_tab1", space, key_tab1);
|
|
|
|
ReadKey(L"key_tab2", space, key_tab2);
|
|
|
|
InitializeAesKeys();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: I cannot read the session keys from: " << file << logend;
|
|
|
|
}
|
|
|
|
|
2021-05-20 20:59:12 +02:00
|
|
|
return status == pt::SpaceParser::ok;
|
2014-11-22 16:30:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::ReadKeysFromFile(const std::wstring & file)
|
|
|
|
{
|
|
|
|
return ReadKeysFromFile(file.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::SaveKeysToFile(std::vector<std::string> & keys)
|
|
|
|
{
|
|
|
|
out_file << "(\n";
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<keys.size() ; ++i)
|
|
|
|
{
|
|
|
|
base64.Encode(keys[i], tmp_key_base64_encoded);
|
|
|
|
out_file << '\"' << tmp_key_base64_encoded << "\"\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
out_file << ")\n\n";
|
|
|
|
tmp_key_base64_encoded.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::SaveKeysToFile(const wchar_t * file)
|
|
|
|
{
|
2021-05-20 20:59:12 +02:00
|
|
|
pt::Date date = last_key_generated;
|
2021-05-21 00:41:27 +02:00
|
|
|
pt::wide_to_utf8(file, file_name_ascii);
|
2014-11-22 16:30:56 +01:00
|
|
|
|
|
|
|
out_file.clear();
|
|
|
|
out_file.open(file_name_ascii, std::ios_base::binary | std::ios_base::out);
|
|
|
|
|
|
|
|
if( out_file )
|
|
|
|
{
|
|
|
|
out_file << "key_index = " << key_index << "\n";
|
|
|
|
|
|
|
|
out_file << "last_key_generated = \"";
|
|
|
|
date.Serialize(out_file);
|
|
|
|
out_file << "\"\n\n";
|
|
|
|
|
|
|
|
out_file << "key_tab1 = ";
|
|
|
|
SaveKeysToFile(key_tab1);
|
|
|
|
|
|
|
|
out_file << "key_tab2 = ";
|
|
|
|
SaveKeysToFile(key_tab2);
|
|
|
|
|
|
|
|
out_file.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
out_file.close();
|
|
|
|
file_name_ascii.clear();
|
|
|
|
SetPriv(file, 0600);
|
|
|
|
|
|
|
|
return !out_file.fail();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::SaveKeysToFile(const std::wstring & file)
|
|
|
|
{
|
|
|
|
return SaveKeysToFile(file.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::AreKeysCorrect(size_t index)
|
|
|
|
{
|
|
|
|
if( index >= 256 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
size_t len = key_tab1[index].size();
|
|
|
|
|
|
|
|
if( len != 16 && len != 24 && len != 32 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
len = key_tab2[index].size();
|
|
|
|
|
|
|
|
if( len != 16 && len != 24 && len != 32 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IMPROVE ME
|
|
|
|
* we need a better algorithm
|
|
|
|
*/
|
|
|
|
void SessionIdManager::GenerateKey(std::string & key, time_t cur_utc_time)
|
|
|
|
{
|
|
|
|
unsigned int pid = (unsigned int)getpid();
|
|
|
|
unsigned int t = (unsigned int)cur_utc_time;
|
|
|
|
|
|
|
|
key.clear();
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<16 ; ++i)
|
|
|
|
{
|
|
|
|
unsigned int r = rand();
|
|
|
|
unsigned int v = r ^ pid ^ t;
|
|
|
|
v = ((v >> 24) ^ (v >> 16) ^ (v >> 8) ^ v) & 0xff;
|
|
|
|
|
|
|
|
key.push_back((unsigned char)v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::GenerateKeys(size_t index, time_t cur_utc_time)
|
|
|
|
{
|
|
|
|
GenerateKey(key_tab1[index], cur_utc_time);
|
|
|
|
GenerateKey(key_tab2[index], cur_utc_time);
|
|
|
|
InitializeAesKeys(index);
|
|
|
|
|
|
|
|
last_key_generated = cur_utc_time;
|
|
|
|
|
|
|
|
if( !SaveKeysToFile(key_file_name) )
|
|
|
|
log << log2 << "SIM: I cannot save the session keys to: " << key_file_name << logend;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::CheckKeys(time_t cur_utc_time)
|
|
|
|
{
|
|
|
|
if( !AreKeysCorrect(key_index) )
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: keys with index: " << key_index << " are incorrect, generating new keys" << logend;
|
|
|
|
|
|
|
|
GenerateKeys(key_index, cur_utc_time);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if( last_key_generated + key_renew_time < cur_utc_time )
|
|
|
|
{
|
|
|
|
key_index += 1;
|
|
|
|
|
|
|
|
if( key_index >= key_tab_size )
|
|
|
|
key_index = 0;
|
|
|
|
|
|
|
|
log << log2 << "SIM: generating new AES keys with index: " << key_index << logend;
|
|
|
|
|
|
|
|
GenerateKeys(key_index, cur_utc_time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::RandPadding(size_t & pad_top_size, char & pad_top_value,
|
|
|
|
size_t & pad_bottom_size, char & pad_bottom_value)
|
|
|
|
{
|
|
|
|
pad_top_size = (std::rand() * 5) / RAND_MAX; // multiply by 5 (not by 4)
|
|
|
|
|
|
|
|
if( pad_top_size > 4 )
|
|
|
|
pad_top_size = 4;
|
|
|
|
|
|
|
|
pad_top_size += 5; // now pad_top_size is from <5;9>
|
|
|
|
pad_top_value = (char)std::rand();
|
|
|
|
|
|
|
|
pad_bottom_size = 14 - pad_top_size; // pad_bottom_size is from <5;9> too
|
|
|
|
pad_bottom_value = (char)std::rand();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::AppendSum(std::string & str)
|
|
|
|
{
|
|
|
|
int s = 0;
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<str.size() ; ++i)
|
|
|
|
s += (int)(unsigned char)str[i];
|
|
|
|
|
|
|
|
str += (unsigned char)s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::AppendXor(std::string & str)
|
|
|
|
{
|
|
|
|
int s = 0;
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<str.size() ; ++i)
|
|
|
|
s ^= (int)(unsigned char)str[i];
|
|
|
|
|
|
|
|
str += (unsigned char)s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::CopyString(const std::string & in, std::wstring & out)
|
|
|
|
{
|
|
|
|
out.clear();
|
|
|
|
|
|
|
|
if( out.capacity() < in.size() )
|
|
|
|
out.reserve(in.size());
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<in.size() ; ++i)
|
|
|
|
out += in[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SessionIdManager::CopyString(const std::wstring & in, std::string & out)
|
|
|
|
{
|
|
|
|
out.clear();
|
|
|
|
|
|
|
|
if( out.capacity() < in.size() )
|
|
|
|
out.reserve(in.size());
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<in.size() ; ++i)
|
|
|
|
out += in[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::Encode(std::string & str)
|
|
|
|
{
|
|
|
|
if( str.size() != 34 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if( !aes1[key_index].Encode((unsigned char*)string_token.c_str()+2, 16) )
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: I cannot AES encode the first part of the token" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aes2[key_index].Encode((unsigned char*)string_token.c_str()+16+2, 16) )
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: I cannot AES encode the second part of the token" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::EncodeToken(size_t id, unsigned int index, time_t cur_utc_time, std::wstring & token)
|
|
|
|
{
|
|
|
|
size_t pad_top_size;
|
|
|
|
size_t pad_bottom_size;
|
|
|
|
char pad_top_value;
|
|
|
|
char pad_bottom_value;
|
|
|
|
|
|
|
|
string_token.clear();
|
|
|
|
string_token.reserve(50);
|
|
|
|
|
|
|
|
if( !was_inited )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CheckKeys(cur_utc_time);
|
|
|
|
RandPadding(pad_top_size, pad_top_value, pad_bottom_size, pad_bottom_value);
|
|
|
|
|
|
|
|
string_token += algorithm_type;
|
|
|
|
string_token += (unsigned char)key_index;
|
|
|
|
string_token += pad_top_value;
|
|
|
|
string_token += pad_bottom_value;
|
|
|
|
string_token += (unsigned char)pad_top_size;
|
|
|
|
string_token += (unsigned char)pad_bottom_size;
|
|
|
|
string_token.append(pad_top_size, pad_top_value);
|
|
|
|
Append(string_token, id);
|
|
|
|
Append(string_token, index);
|
|
|
|
string_token.append(pad_bottom_size, pad_bottom_value);
|
|
|
|
AppendSum(string_token);
|
|
|
|
AppendXor(string_token);
|
|
|
|
|
|
|
|
if( !Encode(string_token) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
base64.Encode(string_token, string_token_base64);
|
|
|
|
CopyString(string_token_base64, token);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::IsPaddingCorrect(const char * str, size_t len, char val)
|
|
|
|
{
|
|
|
|
if( len < 5 || len > 9 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for(size_t i=0 ; i<len ; ++i)
|
|
|
|
if( str[i] != val )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::DecodeAES(const char * str, size_t key)
|
|
|
|
{
|
|
|
|
if( !aes1[key].Decode((unsigned char*)str, 16) )
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: I cannot AES decode the first block" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !aes2[key].Decode((unsigned char*)str + 16, 16) )
|
|
|
|
{
|
|
|
|
log << log1 << "SIM: I cannot AES decode the second block" << logend;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::CheckControlSums(const char * str)
|
|
|
|
{
|
|
|
|
char old_sum = *(str++);
|
|
|
|
char old_xor = *(str++);
|
|
|
|
|
|
|
|
string_token.erase(string_token.size()-2);
|
|
|
|
|
|
|
|
AppendSum(string_token);
|
|
|
|
AppendXor(string_token);
|
|
|
|
|
|
|
|
if( old_sum != string_token[string_token.size()-2] ||
|
|
|
|
old_xor != string_token[string_token.size()-1] )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::DecodeTokenA(size_t & id, unsigned int & index)
|
|
|
|
{
|
|
|
|
size_t pad_top_size;
|
|
|
|
size_t pad_bottom_size;
|
|
|
|
char pad_top_value;
|
|
|
|
char pad_bottom_value;
|
|
|
|
|
|
|
|
const char * str = string_token.c_str() + 1;
|
|
|
|
size_t key = (unsigned char)(*str);
|
|
|
|
|
|
|
|
str += 1;
|
|
|
|
|
|
|
|
if( !DecodeAES(str, key) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
pad_top_value = *(str++);
|
|
|
|
pad_bottom_value = *(str++);
|
|
|
|
pad_top_size = (unsigned char)*(str++);
|
|
|
|
pad_bottom_size = (unsigned char)*(str++);
|
|
|
|
|
|
|
|
if( pad_bottom_size != 14 - pad_top_size )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if( !IsPaddingCorrect(str, pad_top_size, pad_top_value) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
str += pad_top_size;
|
|
|
|
|
|
|
|
Read(str, id);
|
|
|
|
str += 8; // sizeof(id), it's better to use constant '8' instead of sizeof() operator
|
|
|
|
// because at the beginning we are making a test whether the string size is equal to 34
|
|
|
|
// (in the future sizeof(size_t) can be different from 8)
|
|
|
|
Read(str, index);
|
|
|
|
str += 4; // sizeof(index)
|
|
|
|
|
|
|
|
if( !IsPaddingCorrect(str, pad_bottom_size, pad_bottom_value) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
str += pad_bottom_size;
|
|
|
|
|
|
|
|
return CheckControlSums(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool SessionIdManager::DecodeToken(const std::wstring & token, size_t & id, unsigned int & index)
|
|
|
|
{
|
|
|
|
if( !was_inited )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
CopyString(token, string_token_base64);
|
|
|
|
|
|
|
|
if( !base64.Decode(string_token_base64, string_token) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if( string_token.size() != 34 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if( string_token[0] == 'a' )
|
|
|
|
return DecodeTokenA(id, index);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Winix
|
|
|
|
|
|
|
|
|