Files correlati : authoriz.exe Ricompilazione Demo : [ ] Commento : Accettava un utente in meno del massimo previsto sulla chiave di protezione. git-svn-id: svn://10.65.10.50/trunk@11304 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			934 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			934 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "BaseServ.h"
 | 
						||
#include "Dongle.h"
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TBit_array
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TBit_array::TBit_array(size_t size) 
 | 
						||
          : _bit(NULL), _size(0)
 | 
						||
{
 | 
						||
  if (size)
 | 
						||
    resize(index(size));
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::copy(const TBit_array& ba)
 | 
						||
{
 | 
						||
  if (_bit)
 | 
						||
  {
 | 
						||
    delete _bit;
 | 
						||
    _bit = NULL;
 | 
						||
    _size = 0;
 | 
						||
  }
 | 
						||
  resize(ba._size-1);
 | 
						||
  memcpy(_bit, ba._bit, _size);
 | 
						||
}
 | 
						||
 | 
						||
TBit_array::TBit_array(const TBit_array& ba) : _bit(NULL), _size(0)
 | 
						||
{ copy(ba); }
 | 
						||
 | 
						||
TBit_array& TBit_array::operator=(const TBit_array& ba)
 | 
						||
{
 | 
						||
  copy(ba);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
TBit_array::~TBit_array()
 | 
						||
{
 | 
						||
  if (_bit)
 | 
						||
    delete _bit;
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::set()
 | 
						||
{
 | 
						||
  if (_bit) memset(_bit, 0xFF, _size);
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::reset()
 | 
						||
{
 | 
						||
  if (_bit) memset(_bit, 0x0, _size);
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::resize(size_t size)
 | 
						||
{
 | 
						||
  size_t oldsize = _size;
 | 
						||
  unsigned long* oldbit = _bit;
 | 
						||
 | 
						||
  _size = size+1;
 | 
						||
  _bit = new unsigned long[_size];
 | 
						||
  reset();
 | 
						||
 | 
						||
  if (oldsize)
 | 
						||
  {
 | 
						||
    memcpy(_bit, oldbit, oldsize);
 | 
						||
    delete oldbit;
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
bool TBit_array::operator[] (size_t n) const
 | 
						||
{
 | 
						||
  const size_t i = index(n);
 | 
						||
  if (i >= _size) return false;
 | 
						||
  return (_bit[i] & mask(n)) != 0;
 | 
						||
}
 | 
						||
 | 
						||
TBit_array& TBit_array::operator|= (const TBit_array& ba)
 | 
						||
{
 | 
						||
  if (_size < ba._size)
 | 
						||
    resize(ba._size);
 | 
						||
 | 
						||
  for (size_t i = 0; i < _size; i++)
 | 
						||
    _bit[i] |= ba._bit[i];
 | 
						||
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::set(size_t n)
 | 
						||
{
 | 
						||
  const size_t i = index(n);
 | 
						||
  if (i >= _size)
 | 
						||
    resize(i);
 | 
						||
  _bit[i] |= mask(n);
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::reset(size_t n)
 | 
						||
{
 | 
						||
  const size_t i = index(n);
 | 
						||
  if (i < _size)
 | 
						||
    _bit[i] &= ~mask(n);
 | 
						||
}
 | 
						||
 | 
						||
void TBit_array::not(size_t n)
 | 
						||
{
 | 
						||
  const size_t i = index(n);
 | 
						||
  if (i >= _size) resize(i);
 | 
						||
  _bit[i] ^= mask(n);
 | 
						||
}
 | 
						||
 | 
						||
size_t TBit_array::ones() const
 | 
						||
{
 | 
						||
  size_t one = 0;
 | 
						||
  for (size_t i = 0; i < _size; i++)
 | 
						||
  {
 | 
						||
    const unsigned long b = _bit[i];
 | 
						||
    if (b)
 | 
						||
    {
 | 
						||
      for (unsigned long m = 1; m; m <<= 1)
 | 
						||
        if (b & m) one++;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return one;
 | 
						||
}
 | 
						||
 | 
						||
long TBit_array::last_one() const
 | 
						||
{
 | 
						||
  for (size_t i = _size; i--;)
 | 
						||
  {
 | 
						||
    const unsigned long b = _bit[i];
 | 
						||
    if (b)
 | 
						||
    {
 | 
						||
      for (int j = 32; j--;)
 | 
						||
        if ((1<<j) & b) return (long(i)<<5) + j;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return -1;
 | 
						||
}
 | 
						||
 | 
						||
long TBit_array::first_one() const
 | 
						||
{
 | 
						||
  for (size_t i = 0; i < _size; i++)
 | 
						||
  {
 | 
						||
    const unsigned long b = _bit[i];
 | 
						||
    if (b)
 | 
						||
    {
 | 
						||
      for (int j = 0; j < 32; j++)
 | 
						||
        if ((1<<j) & b) return (long(i)<<5)+j;
 | 
						||
    }
 | 
						||
  }
 | 
						||
  return -1;
 | 
						||
}
 | 
						||
 | 
						||
bool TBit_array::ok() const
 | 
						||
{
 | 
						||
  return _bit != NULL && _size > 0;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Date utilities
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
wxDateTime julian2date(long julian)
 | 
						||
{
 | 
						||
  long x, z, m, d, y;
 | 
						||
  const long daysPer400Years = 146097L;
 | 
						||
  const long fudgedDaysPer4000Years = 1460970L + 31;
 | 
						||
 | 
						||
  x = julian + 68569L;
 | 
						||
  z = 4 * x / daysPer400Years;
 | 
						||
  x = x - (daysPer400Years * z + 3) / 4;
 | 
						||
  y = 4000 * (x + 1) / fudgedDaysPer4000Years;
 | 
						||
  x = x - 1461 * y / 4 + 31;
 | 
						||
  m = 80 * x / 2447;
 | 
						||
  d = x - 2447 * m / 80;
 | 
						||
  x = m / 11;
 | 
						||
  m = m + 2 - 12 * x;
 | 
						||
  y = 100 * (z - 49) + y + x;
 | 
						||
 | 
						||
	wxDateTime date;
 | 
						||
	date.SetYear(y);
 | 
						||
	date.SetMonth((wxDateTime::Month)m);
 | 
						||
	date.SetDay(d);
 | 
						||
  return date;
 | 
						||
}
 | 
						||
 | 
						||
long date2julian(const wxDateTime& date)
 | 
						||
{                      
 | 
						||
  const int d = date.GetDay(), m = date.GetMonth()+1, y = date.GetYear();
 | 
						||
  
 | 
						||
  return (long)(d - 32076)
 | 
						||
    + 1461L * (y + 4800L + (m - 14) / 12) / 4
 | 
						||
      + 367 * ( m - 2 - (m - 14) / 12 * 12) / 12
 | 
						||
        - 3 * ((y + 4900L + (m - 14) / 12) / 100) / 4
 | 
						||
          + 1;
 | 
						||
}
 | 
						||
 | 
						||
long date2long(const wxDateTime& date)
 | 
						||
{
 | 
						||
	long n = date.GetYear()*10000 + (date.GetMonth()+1)*100 + date.GetDay();
 | 
						||
	return n;
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Utilities
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
const char* const encryption_key = "QSECOFR-";
 | 
						||
 | 
						||
wxString encode(const wxChar* data)
 | 
						||
{
 | 
						||
	wxString tmp;
 | 
						||
	wxChar* buf = tmp.GetWriteBuf(80);
 | 
						||
  for (int i = 0; data[i]; i++)
 | 
						||
    buf[i] = data[i] + (i < 8 ? encryption_key[i] : data[i - 8]);
 | 
						||
  buf[i] = '\0';
 | 
						||
	tmp.UngetWriteBuf();
 | 
						||
  return tmp; 
 | 
						||
}
 | 
						||
 | 
						||
wxString decode(const char* data)
 | 
						||
{
 | 
						||
	wxString tmp;
 | 
						||
	wxChar* buf = tmp.GetWriteBuf(80);
 | 
						||
  for (int i = 0; data[i]; i++)
 | 
						||
    buf[i] = data[i] - (i < 8 ? encryption_key[i] : buf[i - 8]);
 | 
						||
  buf[i] = '\0';
 | 
						||
	tmp.UngetWriteBuf();
 | 
						||
  return tmp; 
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Hardlock stuff
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
#include "hlapi_c.h"
 | 
						||
 | 
						||
#define USERADR    26952
 | 
						||
#define AGAADR     26953
 | 
						||
#define PRASSIADR  26954
 | 
						||
#define PROCOMADR  26955
 | 
						||
#define REFKEY     (unsigned char*)"CAMPOKEY"
 | 
						||
#define VERKEY     (unsigned char*)"<22>pو<70>c<EFBFBD><"
 | 
						||
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Smartkey stuff
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
#include "skeylink.h"
 | 
						||
static KEY_NET* _eutron_key = NULL;
 | 
						||
 | 
						||
#pragma pack(push, 1)
 | 
						||
 | 
						||
struct TEutronHeader
 | 
						||
{ 
 | 
						||
  char           _serno[8];             //  8
 | 
						||
  unsigned short _year_assist;          // 10
 | 
						||
  unsigned short _max_users;            // 12
 | 
						||
  unsigned long  _last_date;            // 16
 | 
						||
  unsigned long  _scad_date;            // 20
 | 
						||
  unsigned long  _checksum;             // 24 
 | 
						||
  unsigned short _version;              // 26
 | 
						||
  unsigned short _patch;                // 28
 | 
						||
  unsigned short _offset_to_bits;       // 30
 | 
						||
  unsigned short _size_of_bits;         // 32
 | 
						||
};
 | 
						||
 | 
						||
struct TEutronFooter
 | 
						||
{                
 | 
						||
  unsigned long _size;                  // Should be sizeof(TEutronFooter)
 | 
						||
  unsigned long _checksum;              // Much smarter position than header
 | 
						||
  unsigned long _filler1;
 | 
						||
  unsigned long _filler2;
 | 
						||
  unsigned long _filler3;
 | 
						||
  unsigned long _filler4;
 | 
						||
  unsigned long _filler5;
 | 
						||
  unsigned long _last_assist;                   // Last date of assistance query
 | 
						||
  unsigned long _assistance[MAX_DONGLE_ASSIST]; // Pre-payed assistance
 | 
						||
  
 | 
						||
  unsigned long checksum(bool set);
 | 
						||
  bool valid();
 | 
						||
  TEutronFooter();
 | 
						||
};
 | 
						||
 | 
						||
#pragma pack(pop)
 | 
						||
 | 
						||
TEutronFooter::TEutronFooter()
 | 
						||
{
 | 
						||
  const int s = sizeof(TEutronFooter);
 | 
						||
  memset(&_size, 0, s);
 | 
						||
  _size = s;
 | 
						||
}
 | 
						||
 | 
						||
unsigned long TEutronFooter::checksum(bool set)
 | 
						||
{
 | 
						||
  if (set) _size = sizeof(TEutronFooter);
 | 
						||
 | 
						||
  const unsigned short offset = sizeof(_size) + sizeof(_checksum);
 | 
						||
  unsigned char* ptr = (unsigned char*)(&_size) + offset;
 | 
						||
  const unsigned short len = unsigned short(_size - offset);
 | 
						||
  
 | 
						||
  unsigned long cs = 0;
 | 
						||
  for (unsigned short i = 0; i < len; i++, ptr++)
 | 
						||
    cs += *ptr | ~(short(*ptr << 8));
 | 
						||
  if (set) _checksum = cs;
 | 
						||
  return cs;  
 | 
						||
}
 | 
						||
 | 
						||
bool TEutronFooter::valid() 
 | 
						||
{
 | 
						||
  if (_size == 0 || _checksum == 0)
 | 
						||
    return false;
 | 
						||
  return _checksum == checksum(false);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// Bit helper functions
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
inline bool test_bit(unsigned short w, int b)
 | 
						||
{                            
 | 
						||
  bool on = (w & (1 << b)) != 0;
 | 
						||
  return on;
 | 
						||
}
 | 
						||
 | 
						||
inline void set_bit(unsigned short& w, int b, bool on = true)
 | 
						||
{                        
 | 
						||
  if (on)  
 | 
						||
    w |= 1 << b;
 | 
						||
  else  
 | 
						||
    w &= ~(1 << b);
 | 
						||
}
 | 
						||
 | 
						||
inline void reset_bit(unsigned short& w, unsigned char b)
 | 
						||
{                        
 | 
						||
  w &= ~(1 << b);
 | 
						||
}
 | 
						||
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
// TDongle
 | 
						||
///////////////////////////////////////////////////////////
 | 
						||
 | 
						||
TDongle::TDongle() 
 | 
						||
       : _hardware(_dongle_unknown), _type(_no_dongle), _serno(0xFFFF), 
 | 
						||
         _dirty(false), _max_users(1), _year_assist(2002)
 | 
						||
{
 | 
						||
  memset(_eprom, 0, sizeof(_eprom));
 | 
						||
}  
 | 
						||
 | 
						||
TDongle::~TDongle() 
 | 
						||
{ 
 | 
						||
  if (_serno != 0xFFFF)
 | 
						||
    Logout(); 
 | 
						||
}
 | 
						||
 | 
						||
// Data punta ad un array di 4 words 
 | 
						||
// Deve essere cosi' per problemi del C,
 | 
						||
// non trasformare in array: pena di morte! 
 | 
						||
void TDongle::garble(unsigned short* data) const
 | 
						||
{   
 | 
						||
  switch (_hardware)
 | 
						||
  {
 | 
						||
  case _dongle_hardlock:
 | 
						||
    HL_CODE(data, 1);
 | 
						||
    break;
 | 
						||
  case _dongle_eutron:
 | 
						||
    if (_eutron_key)
 | 
						||
    {   
 | 
						||
      _eutron_key->net_command = NET_KEY_ACCESS;
 | 
						||
      _eutron_key->command = SCRAMBLING_MODE;
 | 
						||
      memcpy(_eutron_key->data, data, 8);
 | 
						||
      smartlink(_eutron_key);
 | 
						||
      if (_eutron_key->status == ST_OK)
 | 
						||
        memcpy(data, _eutron_key->data, 8);
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    break;  
 | 
						||
  }  
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::already_programmed() const
 | 
						||
{     
 | 
						||
/*
 | 
						||
  if (_hardware == _dongle_hardlock)
 | 
						||
  {
 | 
						||
    unsigned short data[4];
 | 
						||
    memcpy(data, &_eprom[60], sizeof(data));
 | 
						||
    garble(data);
 | 
						||
    
 | 
						||
    if (data[0] < 1997 || data[0] > 2997)
 | 
						||
      return false;
 | 
						||
      
 | 
						||
    if (data[1] == 0 || data[1] >= 10000)  
 | 
						||
      return false;
 | 
						||
    
 | 
						||
    const TDate today(TODAY);
 | 
						||
    const long& giulio = (const long&)data[2];
 | 
						||
    const long yyyymmdd = today.julian2date(giulio);
 | 
						||
    const TDate d(yyyymmdd);
 | 
						||
    if (d.year() < 1997 || d > today)
 | 
						||
      return false;
 | 
						||
  } else
 | 
						||
  if (_hardware == _dongle_eutron)
 | 
						||
  {
 | 
						||
    const TEutronHeader* eh = (const TEutronHeader*)_eprom;
 | 
						||
    if (eh->_serno[0] == 0 || eh->_checksum == 0)
 | 
						||
      return false;   // Really virgin.
 | 
						||
      
 | 
						||
    unsigned long cs = 0;
 | 
						||
    for (byte* ptr = (byte*)_eprom; ptr < (byte*)&eh->_checksum; ptr++)
 | 
						||
      cs += *ptr | ~(short(*ptr << 8));
 | 
						||
    if (eh->_checksum != cs)  
 | 
						||
      return false;   // Malicious programming!
 | 
						||
  }   
 | 
						||
*/
 | 
						||
  return true;  
 | 
						||
}
 | 
						||
           
 | 
						||
bool TDongle::hardlock_login(bool test_all_keys)
 | 
						||
{
 | 
						||
  bool ok = true;
 | 
						||
  _type = _user_dongle;
 | 
						||
  if (test_all_keys)
 | 
						||
  {
 | 
						||
    HL_LOGOUT();
 | 
						||
    if (HL_LOGIN(AGAADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK) 
 | 
						||
      _type = _aga_dongle;
 | 
						||
    else
 | 
						||
    {
 | 
						||
      HL_LOGOUT();
 | 
						||
      if (HL_LOGIN(PRASSIADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK)
 | 
						||
        _type = _prassi_dongle;
 | 
						||
      else
 | 
						||
      {
 | 
						||
        HL_LOGOUT();
 | 
						||
        if (HL_LOGIN(PROCOMADR, LOCAL_DEVICE, REFKEY, VERKEY) == STATUS_OK)
 | 
						||
          _type = _procom_dongle;
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  HL_LOGOUT();
 | 
						||
  ok = HL_LOGIN(USERADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK;
 | 
						||
  
 | 
						||
  if (ok)
 | 
						||
  {     
 | 
						||
    _hardware = _dongle_hardlock;
 | 
						||
    
 | 
						||
    HL_READBL((unsigned char*)_eprom);
 | 
						||
 | 
						||
    unsigned short data[4];
 | 
						||
    memcpy(data, _eprom, sizeof(data));
 | 
						||
    garble(data);
 | 
						||
    
 | 
						||
    if (data[0] == 0xFAE8)
 | 
						||
      _serno = data[1];
 | 
						||
    else
 | 
						||
    {                  
 | 
						||
      if (data[0] == 0x3283 || data[0] == 0xA3AA) // chiave programmatori !!
 | 
						||
      {         
 | 
						||
        if (_type == _user_dongle)
 | 
						||
          _type = _developer_dongle;
 | 
						||
        _serno = 0;  
 | 
						||
      }  
 | 
						||
    }  
 | 
						||
  }  
 | 
						||
 | 
						||
  if (ok) 
 | 
						||
  {
 | 
						||
    _max_users = 1;
 | 
						||
    _last_update = wxDateTime::Now();
 | 
						||
    _year_assist = _last_update.GetYear();
 | 
						||
 | 
						||
    if (_type == _user_dongle)
 | 
						||
    {  
 | 
						||
      const bool already = already_programmed();
 | 
						||
      
 | 
						||
      _module.reset(); // Disattiva  tutti i moduli
 | 
						||
      const int last_word = already ? 12 : 4;                    
 | 
						||
      unsigned short data[4];
 | 
						||
 | 
						||
      // Legge flag di attivazione dei moduli
 | 
						||
      for (int i = 0; i < last_word; i += 4)
 | 
						||
      {
 | 
						||
        memcpy(data, &_eprom[48+i], sizeof(data));
 | 
						||
        garble(data);
 | 
						||
        if (data[3] == _serno) // Validate block
 | 
						||
        {
 | 
						||
          for (int j = 0; j < 3; j++)
 | 
						||
          {
 | 
						||
            unsigned short parola = data[j] ^ _serno;
 | 
						||
            if (parola)
 | 
						||
            {
 | 
						||
              for (int b = 15; b >= 0; b--)
 | 
						||
              {
 | 
						||
                if (test_bit(parola, b))             
 | 
						||
                {
 | 
						||
                  const unsigned short bit = i * 12 + j * 16 + b;
 | 
						||
                  _module.set(bit+1);
 | 
						||
                }  
 | 
						||
              }  
 | 
						||
            }  
 | 
						||
          }
 | 
						||
        }
 | 
						||
        else
 | 
						||
          break;
 | 
						||
      }
 | 
						||
      _module.set(0, true); // Forza l'attivazione della base
 | 
						||
 | 
						||
      // Legge anno di assitenza e numero massimo di utenti
 | 
						||
      memcpy(data, &_eprom[60], sizeof(data));
 | 
						||
      garble(data);      
 | 
						||
      
 | 
						||
      if (already)
 | 
						||
      {
 | 
						||
        _year_assist = data[0];
 | 
						||
        _max_users = data[1];
 | 
						||
        const long& giulio = (const long&)data[2];
 | 
						||
        _last_update = julian2date(giulio);
 | 
						||
      }
 | 
						||
      else
 | 
						||
      {
 | 
						||
        _year_assist = 0;
 | 
						||
        _dirty = true;
 | 
						||
      }
 | 
						||
    }  
 | 
						||
    else
 | 
						||
    {                   
 | 
						||
      _module.set(255); // Last module on key
 | 
						||
      _module.set();     // Activate all modules
 | 
						||
 | 
						||
      _max_users = 4;
 | 
						||
      _last_update = wxDateTime::Now();
 | 
						||
      _year_assist = _last_update.GetYear();
 | 
						||
    }  
 | 
						||
  }  
 | 
						||
  else
 | 
						||
    _type = _no_dongle;
 | 
						||
  
 | 
						||
  return ok;  
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::eutron_login(bool test_all_keys)
 | 
						||
{
 | 
						||
  bool ok = false;
 | 
						||
 | 
						||
  if (_eutron_key == NULL)             
 | 
						||
    _eutron_key = new KEY_NET;
 | 
						||
  memset(_eutron_key, 0, sizeof(KEY_NET));
 | 
						||
  _eutron_key->net_command = NET_KEY_OPEN;
 | 
						||
  // _eutron_key->command = LOCATING_MODE;
 | 
						||
	_eutron_key->status = ST_HW_FAILURE; // Don't leave ST_OK = 0 here!
 | 
						||
 | 
						||
  const char* labels[5] = { "AGA.INFORMATICA", "AGA.PRASSI", "AGA.PROCOM", 
 | 
						||
                            "AGA.CAMPO", "25EBAI" };
 | 
						||
  TDongleType types[5]  = { _aga_dongle, _prassi_dongle, _procom_dongle, 
 | 
						||
                            _user_dongle, _developer_dongle };
 | 
						||
  for (int k = test_all_keys ? 0 : 3; k < 5; k++)
 | 
						||
  {
 | 
						||
    memset(_eutron_key->label, 0, LABEL_LENGTH);
 | 
						||
    memcpy(_eutron_key->label, labels[k], strlen(labels[k]));  
 | 
						||
    memset(_eutron_key->password, 0, PASSWORD_LENGTH);
 | 
						||
    memcpy(_eutron_key->password, ::encode(labels[k]), strlen(labels[k]));  
 | 
						||
 | 
						||
    smartlink(_eutron_key);
 | 
						||
    ok = _eutron_key->status == ST_OK;
 | 
						||
    if (ok)
 | 
						||
    {                  
 | 
						||
      _hardware = _dongle_eutron;
 | 
						||
      _type = types[k];
 | 
						||
      break;
 | 
						||
    }
 | 
						||
  }  
 | 
						||
  if (ok)
 | 
						||
  { 
 | 
						||
    _serno = 0;
 | 
						||
    _max_users = 1;
 | 
						||
    _last_update = wxDateTime::Now();
 | 
						||
    _year_assist = _last_update.GetYear();
 | 
						||
 | 
						||
    if (_type == _user_dongle)
 | 
						||
    {   
 | 
						||
      _module.reset();   // Disattiva tutti i moduli
 | 
						||
      if (read_words(0, sizeof(TEutronHeader) / 2, _eprom))
 | 
						||
      {
 | 
						||
        const TEutronHeader* eh = (const TEutronHeader*)_eprom;
 | 
						||
        wxString serno = eh->_serno; serno.Truncate(8);
 | 
						||
        _serno = unsigned(atol(serno));
 | 
						||
        if (already_programmed())
 | 
						||
        {
 | 
						||
          _max_users   = eh->_max_users;
 | 
						||
          _last_update = eh->_last_date;
 | 
						||
          _year_assist = eh->_year_assist;
 | 
						||
          
 | 
						||
          // Calcola il numero della word dove cominciano i bit di attivazione
 | 
						||
          unsigned short otb = eh->_offset_to_bits;
 | 
						||
          if (otb == 0) otb = 16;   // Compatibile Hardlock
 | 
						||
 | 
						||
          unsigned short sob = eh->_size_of_bits;
 | 
						||
          if (sob == 0) sob = 16;   // Compatibile Hardlock
 | 
						||
          
 | 
						||
          unsigned short data[64];
 | 
						||
          if (read_words(otb, sob, data))
 | 
						||
          {  
 | 
						||
            int module = 1;
 | 
						||
            for (unsigned short w = 0; w < sob; w++)
 | 
						||
            {
 | 
						||
              for (int b = 0; b < 16; b++)
 | 
						||
              {
 | 
						||
                if (test_bit(data[w], b))
 | 
						||
                  _module.set(module);
 | 
						||
                module++;  
 | 
						||
              }    
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }  
 | 
						||
        else
 | 
						||
          _dirty = true;
 | 
						||
      }  
 | 
						||
      _module.set(0, true); // Forza l'attivazione della base
 | 
						||
    }
 | 
						||
    else
 | 
						||
    {
 | 
						||
			_max_users = 4;
 | 
						||
      _module.set(255); // Last module on key
 | 
						||
      _module.set();    // Activate all modules
 | 
						||
    }  
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {
 | 
						||
    delete _eutron_key;
 | 
						||
    _eutron_key = NULL;
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::Login(bool test_all_keys)
 | 
						||
{                                                                   
 | 
						||
  bool ok = true;
 | 
						||
 | 
						||
  if (_type != _no_dongle) // Already logged in
 | 
						||
    Logout();
 | 
						||
 | 
						||
  TDongleHardware hw = _hardware;               
 | 
						||
  if (hw == _dongle_unknown)
 | 
						||
    hw = (TDongleHardware)GetServerApp().GetConfigInt("Donglehw");
 | 
						||
  switch(hw)
 | 
						||
  {
 | 
						||
  case _dongle_hardlock: 
 | 
						||
    ok = hardlock_login(test_all_keys); 
 | 
						||
    break;
 | 
						||
  case _dongle_eutron: 
 | 
						||
    ok = eutron_login(test_all_keys); 
 | 
						||
    break;
 | 
						||
  default:
 | 
						||
    ok = false;
 | 
						||
    break;
 | 
						||
  }
 | 
						||
  if (!ok) 
 | 
						||
  {
 | 
						||
    if (!ok && hw != _dongle_eutron)
 | 
						||
      ok = eutron_login(test_all_keys);
 | 
						||
    if (!ok && hw != _dongle_hardlock)
 | 
						||
      ok = hardlock_login(test_all_keys);
 | 
						||
    if (ok)
 | 
						||
      GetServerApp().SetConfigInt("Donglehw",(int)_hardware);
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::Logout()
 | 
						||
{ 
 | 
						||
  if (_type != _no_dongle)
 | 
						||
  {
 | 
						||
    switch (_hardware)
 | 
						||
    {
 | 
						||
    case _dongle_hardlock:  
 | 
						||
      HL_LOGOUT(); 
 | 
						||
      break;
 | 
						||
    case _dongle_eutron:   
 | 
						||
      if (_eutron_key)
 | 
						||
      {
 | 
						||
        _eutron_key->net_command = NET_KEY_CLOSE;
 | 
						||
        _eutron_key->command = 0;
 | 
						||
        smartlink(_eutron_key);
 | 
						||
      }  
 | 
						||
      break;
 | 
						||
    default:
 | 
						||
      break;  
 | 
						||
    }
 | 
						||
  }  
 | 
						||
 | 
						||
  _type = _no_dongle;
 | 
						||
  _serno = 0xFFFF;
 | 
						||
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::Connected()
 | 
						||
{
 | 
						||
	bool ok = false;
 | 
						||
  if (type() != _no_dongle)
 | 
						||
	{
 | 
						||
		unsigned short a[4] = { 0, 0, 0, 0 };
 | 
						||
		garble(a);
 | 
						||
		for (int i = 0; i < 4; i++)
 | 
						||
			ok |= (a[0] != 0);
 | 
						||
	}
 | 
						||
	return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Data punta ad un array di 4 words 
 | 
						||
// Deve essere cosi' per problemi del C,
 | 
						||
// non trasformare in array: pena di morte! 
 | 
						||
bool TDongle::read_words(unsigned short reg, unsigned short len, unsigned short* ud) const
 | 
						||
{         
 | 
						||
  bool ok = false;
 | 
						||
  switch (_hardware)
 | 
						||
  { 
 | 
						||
  case _dongle_hardlock:
 | 
						||
    {
 | 
						||
      for (unsigned short i = 0; i < len; i++)
 | 
						||
        HL_READ(reg+i, &ud[i]);
 | 
						||
      ok = true;
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case _dongle_eutron:
 | 
						||
    if (_eutron_key)
 | 
						||
    {
 | 
						||
      _eutron_key->net_command = NET_KEY_ACCESS;
 | 
						||
      _eutron_key->command = BLOCK_READING_MODE;
 | 
						||
      unsigned short* pointer = (unsigned short*)(&_eutron_key->data[0]);
 | 
						||
      unsigned short* number  = (unsigned short*)(&_eutron_key->data[2]);
 | 
						||
      while (len > 0)
 | 
						||
      {
 | 
						||
        *pointer = reg;
 | 
						||
        *number = (len <= 16) ? len : 16;
 | 
						||
        smartlink(_eutron_key);
 | 
						||
 | 
						||
        ok = _eutron_key->status == ST_OK;
 | 
						||
        if (ok)
 | 
						||
          memcpy(ud, &_eutron_key->data[4], (*number)*2);
 | 
						||
        else
 | 
						||
        {
 | 
						||
          GetServerApp().WriteLog("*** EUTRON read error");
 | 
						||
          break;
 | 
						||
        }  
 | 
						||
        len -= *number;
 | 
						||
        reg += *number;
 | 
						||
        ud  += *number;
 | 
						||
      }    
 | 
						||
    }
 | 
						||
    break; 
 | 
						||
  default:
 | 
						||
    break;
 | 
						||
  }  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
// Data punta ad un array di 4 words 
 | 
						||
// Deve essere cosi' per problemi del C,
 | 
						||
// non trasformare in array: pena di morte! 
 | 
						||
bool TDongle::write_words(unsigned short reg, unsigned short len, unsigned short* data) const
 | 
						||
{                     
 | 
						||
  bool ok = false;
 | 
						||
  switch(_hardware)
 | 
						||
  {                
 | 
						||
  case _dongle_hardlock:
 | 
						||
    {
 | 
						||
      int err = STATUS_OK;
 | 
						||
      for (unsigned short r = 0; r < len; r++)
 | 
						||
      {           
 | 
						||
        const unsigned short address = reg+r;
 | 
						||
        err = HL_WRITE(address, data[r]);
 | 
						||
        if (err != STATUS_OK)                                     
 | 
						||
        {
 | 
						||
          GetServerApp().WriteLog("*** HARDLOCK write error");
 | 
						||
          break;
 | 
						||
        }  
 | 
						||
      }  
 | 
						||
      ok = err == STATUS_OK;
 | 
						||
    }  
 | 
						||
    break;
 | 
						||
  case _dongle_eutron:
 | 
						||
    if (_eutron_key)
 | 
						||
    {
 | 
						||
      _eutron_key->net_command = NET_KEY_ACCESS;
 | 
						||
      _eutron_key->command = BLOCK_WRITING_MODE;
 | 
						||
      unsigned short* pointer = (unsigned short*)(&_eutron_key->data[0]);
 | 
						||
      unsigned short* number  = (unsigned short*)(&_eutron_key->data[2]);
 | 
						||
      while (len > 0)
 | 
						||
      {
 | 
						||
        *pointer = reg;
 | 
						||
        *number = len > 16 ? 16 : len;
 | 
						||
        memcpy(&_eutron_key->data[4], data, (*number)*2);
 | 
						||
        smartlink(_eutron_key);
 | 
						||
        ok = _eutron_key->status == ST_OK;
 | 
						||
        if (!ok)
 | 
						||
        {
 | 
						||
          GetServerApp().WriteLog("*** EUTRON write error");
 | 
						||
          break;
 | 
						||
        }  
 | 
						||
        reg  += *number;
 | 
						||
        len  -= *number;
 | 
						||
        data += *number;
 | 
						||
      }    
 | 
						||
    }
 | 
						||
  default:
 | 
						||
    break;  
 | 
						||
  }
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::burn_hardlock()
 | 
						||
{
 | 
						||
  unsigned short data[4];
 | 
						||
 | 
						||
  const wxDateTime today = wxDateTime::Now();   
 | 
						||
  const bool already = already_programmed();
 | 
						||
  if (already)  
 | 
						||
  {       
 | 
						||
    memcpy(data, &_eprom[60], sizeof(data));
 | 
						||
    garble(data);                         
 | 
						||
    if (data[0] < 1997 || data[0] > 2997)
 | 
						||
		{
 | 
						||
			GetServerApp().WriteLog("On Line Assistance error.");
 | 
						||
      return false;
 | 
						||
		}
 | 
						||
    if (data[1] == 0 || data[1] >= 10000)
 | 
						||
		{
 | 
						||
			GetServerApp().WriteLog("*** Bad users number.");
 | 
						||
      return false;
 | 
						||
		}
 | 
						||
    const long& val = (const long&)data[2];
 | 
						||
    const wxDateTime date= julian2date(val);
 | 
						||
    if (date > today)
 | 
						||
		{
 | 
						||
      GetServerApp().WriteLog("*** Too late sir: key has already expired!");
 | 
						||
      return false;
 | 
						||
		}
 | 
						||
  }
 | 
						||
  
 | 
						||
  data[0] = _year_assist;
 | 
						||
  data[1] = _max_users;
 | 
						||
  long& val = (long&)data[2];
 | 
						||
  val = date2julian(today);
 | 
						||
  garble(data);
 | 
						||
  write_words(60, 4, data);
 | 
						||
  _last_update = today;
 | 
						||
 | 
						||
  // Il primo bit della memoria della chiave corrisponde al modulo uno 
 | 
						||
  // non allo zero (che e' la base ed e' sempre attivo)
 | 
						||
  unsigned short module = 1;
 | 
						||
  for (int octect = 0; octect < 3; octect++)  
 | 
						||
  {                                       
 | 
						||
    for(int parola = 0; parola < 3; parola++)  
 | 
						||
    {        
 | 
						||
      unsigned short& p = data[parola];
 | 
						||
      p = 0;
 | 
						||
      for (int bit = 0; bit < 16; bit++)
 | 
						||
      {          
 | 
						||
        if (Active(module))
 | 
						||
          set_bit(p, bit);
 | 
						||
        module++;
 | 
						||
      }
 | 
						||
      p ^= _serno;
 | 
						||
    }
 | 
						||
    data[3] = _serno;
 | 
						||
    garble(data);
 | 
						||
    write_words(48 + 4*octect, 4, data);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return true;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::burn_eutron()
 | 
						||
{
 | 
						||
  TEutronHeader* eh = (TEutronHeader*)_eprom;
 | 
						||
  memset(eh, 0, sizeof(TEutronHeader));
 | 
						||
  
 | 
						||
  _last_update = wxDateTime::Now();
 | 
						||
  sprintf(eh->_serno, "%lu", (unsigned long)_serno);
 | 
						||
  eh->_year_assist = _year_assist;
 | 
						||
  eh->_max_users   = _max_users;
 | 
						||
  eh->_last_date   = date2long(_last_update);
 | 
						||
  eh->_scad_date   = 0;
 | 
						||
  
 | 
						||
  unsigned long cs = 0;
 | 
						||
  for (unsigned char* ptr = (unsigned char*)_eprom; ptr < (unsigned char*)&eh->_checksum; ptr++)
 | 
						||
    cs += *ptr | ~(short(*ptr << 8));
 | 
						||
  eh->_checksum = cs;
 | 
						||
  
 | 
						||
  const unsigned short otb = sizeof(TEutronHeader) / 2;
 | 
						||
  const unsigned short sob = 16;
 | 
						||
  eh->_offset_to_bits = otb;
 | 
						||
  eh->_size_of_bits = sob;
 | 
						||
  
 | 
						||
  bool ok = write_words(0, otb, _eprom);
 | 
						||
  
 | 
						||
  if (ok)
 | 
						||
  {
 | 
						||
    unsigned short data[sob]; memset(data, 0, sizeof(data));
 | 
						||
    for (int module = 1; module < 256; module++)
 | 
						||
    {                             
 | 
						||
      if (Active(module))
 | 
						||
      {
 | 
						||
        unsigned short& w = data[(module-1) / 16];
 | 
						||
        set_bit(w, (module-1) % 16, true);
 | 
						||
      }  
 | 
						||
    }
 | 
						||
    ok = write_words(otb, sob, data);
 | 
						||
  }
 | 
						||
  
 | 
						||
  return ok;
 | 
						||
}
 | 
						||
 | 
						||
bool TDongle::Burn()
 | 
						||
{          
 | 
						||
  bool ok = _type == _user_dongle;
 | 
						||
 | 
						||
  if (ok) 
 | 
						||
  {       
 | 
						||
    switch(_hardware)
 | 
						||
    {
 | 
						||
      case _dongle_hardlock: ok = burn_hardlock(); break;
 | 
						||
      case _dongle_eutron  : ok = burn_eutron(); break;
 | 
						||
      default              : break;
 | 
						||
    }  
 | 
						||
  }   
 | 
						||
  if (ok)
 | 
						||
    _dirty = false; 
 | 
						||
 | 
						||
  return ok;  
 | 
						||
}
 | 
						||
 |