campo-sirio/include/dongle.cpp
guy 043790be92 applicat.cpp Tolti commenti e riscritto meglio controllo di abiliatzione cambio ditta
controls.cpp   Migliorato riconoscimento tasti estesi
dongle.cpp     Aggiunto riconoscimento delle nuove chiavi programmatori
execp.cpp      Aggiunta chiamata per chiudere tutto il chiudibile prima di un'esecuzione sincrona


git-svn-id: svn://10.65.10.50/trunk@6455 c028cbd2-c16b-5b4b-a496-9718f37d4682
1998-03-30 13:39:21 +00:00

683 lines
16 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdlib.h>
#include <applicat.h>
#include <config.h>
#include <dongle.h>
#include <isamrpc.h>
#include <utility.h>
///////////////////////////////////////////////////////////
// Hardlock stuff
///////////////////////////////////////////////////////////
#ifndef _DEMO_
#include <hlapi_c.h>
#define USERADR 26952
#define AGAADR 26953
#define PRASSIADR 26954
#define PROCOMADR 26956
#define REFKEY "CAMPOKEY"
#define VERKEY "ìpÙˆ¬cê<"
#endif
///////////////////////////////////////////////////////////
// Smartkey stuff
///////////////////////////////////////////////////////////
#ifndef _DEMO_
#define PANDLL
extern "C"
{
#include "skeytsr.h"
}
HIDDEN KEY_NET* _eutron_key = NULL;
struct TEutronHeader
{
char _serno[8];
unsigned short _year_assist;
unsigned short _max_users;
unsigned long _last_date;
unsigned long _scad_date;
unsigned long _checksum; // Must be the last item!
};
#endif // _DEMO_
///////////////////////////////////////////////////////////
// Current dongle
///////////////////////////////////////////////////////////
static TDongle* _dongle = NULL;
TDongle& dongle()
{
if (_dongle == NULL)
_dongle = new TDongle;
return *_dongle;
}
bool destroy_dongle()
{
bool ok = _dongle != NULL;
if (ok)
{
delete _dongle;
_dongle = NULL;
if (_eutron_key)
{
delete _eutron_key;
_eutron_key = NULL;
}
}
return ok;
}
///////////////////////////////////////////////////////////
// Bit helper functions
///////////////////////////////////////////////////////////
inline bool test_bit(word w, int b)
{
bool on = (w & (1 << b)) != 0;
return on;
}
inline void set_bit(word& w, int b, bool on = TRUE)
{
if (on)
w |= 1 << b;
else
w &= ~(1 << b);
}
inline void reset_bit(word& w, byte b)
{
w &= ~(1 << b);
}
///////////////////////////////////////////////////////////
// TDongle
///////////////////////////////////////////////////////////
TDongle::TDongle()
: _hardware(_dongle_unknown), _type(_no_dongle), _serno(0xFFFF),
_dirty(FALSE), _max_users(1), _year_assist(1997)
{
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(word* data) const
{
#ifndef _DEMO_
switch (_hardware)
{
case _dongle_hardlock:
HL_CODE(EYECAST 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);
else
NFCHECK("EUTRON scrambling error: %d", _eutron_key->status);
}
break;
default:
break;
}
#endif
}
bool TDongle::already_programmed() const
{
#ifndef _DEMO_
if (_hardware == _dongle_hardlock)
{
word 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 | ~(*ptr << 8);
if (eh->_checksum != cs)
return FALSE; // Malicious programming!
}
#endif // _DEMO_
return TRUE;
}
#ifndef _DEMO_
bool TDongle::hardlock_login(bool test_all_keys)
{
bool ok = TRUE;
_type = _user_dongle;
if (test_all_keys)
{
HL_LOGOUT();
if (HL_LOGIN(AGAADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK)
_type = _aga_dongle;
else
{
HL_LOGOUT();
if (HL_LOGIN(PRASSIADR, DONT_CARE, REFKEY, VERKEY) == STATUS_OK)
_type = _prassi_dongle;
else
{
HL_LOGOUT();
if (HL_LOGIN(PROCOMADR, DONT_CARE, 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((char*)_eprom);
word 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 !!
{
_type = _developer_dongle;
_serno = 0;
}
}
}
if (ok)
{
_max_users = 1;
_last_update = TDate(TODAY);
_year_assist = _last_update.year();
if (_type == _user_dongle)
{
const bool already = already_programmed();
_module.reset();
_module.set(0, TRUE);
const int last_word = already ? 12 : 4;
word 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++)
{
word parola = data[j] ^ _serno;
if (parola)
{
for (int b = 15; b >= 0; b--)
{
if (test_bit(parola, b))
{
const word bit = i * 12 + j * 16 + b;
_module.set(bit+1);
}
}
}
}
}
else
break;
}
// 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];
const long yyyymmdd = _last_update.julian2date(giulio);
_last_update = yyyymmdd;
}
else
{
_dirty = TRUE;
}
}
else
{
_module.set(255); // Last module on key
_module.set(); // Activate all modules
_max_users = 1;
_last_update = TDate(TODAY);
_year_assist = _last_update.year();
}
}
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;
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 = TDate(TODAY);
_year_assist = _last_update.year();
if (_type == _user_dongle)
{
_module.reset();
_module.set(0, TRUE);
if (read_words(0, sizeof(TEutronHeader) / 2, _eprom))
{
const TEutronHeader* eh = (const TEutronHeader*)_eprom;
TString16 serno; serno.strncpy(eh->_serno, 8);
_serno = unsigned(atol(serno));
if (already_programmed())
{
_max_users = eh->_max_users;
_last_update = eh->_last_date;
_year_assist = eh->_year_assist;
word data[16];
if (read_words(16, 16, data))
{
int module = 1;
for (word w = 0; w < 16; w++)
{
for (int b = 0; b < 16; b++)
{
if (test_bit(data[w], b))
_module.set(module);
module++;
}
}
}
}
else
_dirty = TRUE;
}
}
else
{
_module.set(255); // Last module on key
_module.set(); // Activate all modules
}
}
else
{
delete _eutron_key;
_eutron_key = NULL;
}
return ok;
}
bool TDongle::network_login(bool test_all_keys)
{
if (network())
rpc_UserLogout();
TConfig ini(CONFIG_INSTALL, "Server");
const char* server = ini.get("Dongle");
const char* guest = "******";
const TString appname = main_app().firm_change_enabled() ? main_app().name() : "ba0100";
const char* utente = (!xvt_running() && appname == "ba0100") ? guest : user();
const bool ok = rpc_UserLogin(server, utente, guest, appname);
if (ok)
{
_hardware = _dongle_network;
_type = _user_dongle;
_serno = rpc_DongleNumber();
_max_users = 1;
_last_update = TDate(TODAY);
_year_assist = rpc_DongleYear();
rpc_DongleModules(_module);
}
return ok;
}
#endif // _DEMO_
bool TDongle::login(bool test_all_keys)
{
bool ok = TRUE;
#ifdef _DEMO_
_hardware = _dongle_hardlock;
_type = _dongle_user;
_serno = 0;
_max_users = 1;
_last_update = TDate(TODAY);
_year_assist = _last_update.year();
_module.set(255); // Last module on key
_module.set(); // Activate all modules
#else
if (_type != _no_dongle) // Already logged in
logout();
if (_hardware == _dongle_unknown || _hardware == _dongle_hardlock)
ok = hardlock_login(test_all_keys);
if (_hardware == _dongle_unknown || _hardware == _dongle_eutron)
ok = eutron_login(test_all_keys);
if (_hardware == _dongle_unknown || _hardware == _dongle_network)
ok = network_login(test_all_keys);
#endif
return ok;
}
bool TDongle::logout()
{
#ifndef _DEMO_
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;
case _dongle_network:
rpc_UserLogout();
break;
default:
break;
}
}
#endif
_type = _no_dongle;
_serno = 0xFFFF;
return TRUE;
}
// 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(word reg, word len, word* ud) const
{
bool ok = FALSE;
#ifndef _DEMO_
switch (_hardware)
{
case _dongle_hardlock:
{
for (word i = 0; i < len; i++)
HL_READ(reg+i, (int*)&ud[i]);
ok = TRUE;
}
break;
case _dongle_eutron:
if (_eutron_key)
{
_eutron_key->net_command = NET_KEY_ACCESS;
memcpy(&_eutron_key->command, BLOCK_READING_MODE, 2);
word* pointer = (word*)(&_eutron_key->data[0]);
word* number = (word*)(&_eutron_key->data[2]);
*pointer = reg;
*number = len;
smartlink(_eutron_key);
ok = _eutron_key->status == ST_OK;
if (ok)
memcpy(ud, &_eutron_key->data[4], len*2);
else
NFCHECK("EUTRON read error: %d", _eutron_key->status);
}
break;
default:
break;
}
#endif // _DEMO_
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(word reg, word len, word* data) const
{
bool ok = FALSE;
#ifndef _DEMO_
switch(_hardware)
{
case _dongle_hardlock:
{
int err = STATUS_OK;
for (word r = 0; r < len; r++)
{
const word address = reg+r;
err = HL_WRITE(address, data[r]);
if (err != STATUS_OK)
{
NFCHECK("HARDLOCK write error on register %u", address);
break;
}
}
ok = err == STATUS_OK;
}
break;
case _dongle_eutron:
if (_eutron_key)
{
CHECKD(len > 0 && len <= 16, "EUTRON can't write so many words: ", len);
_eutron_key->net_command = NET_KEY_ACCESS;
memcpy(&_eutron_key->command, BLOCK_WRITING_MODE, 2);
word* pointer = (word*)(&_eutron_key->data[0]);
word* number = (word*)(&_eutron_key->data[2]);
*pointer = reg;
*number = len;
memcpy(&_eutron_key->data[4], data, len*2);
smartlink(_eutron_key);
ok = _eutron_key->status == ST_OK;
if (!ok)
NFCHECK("EUTRON write error: %d", _eutron_key->status);
}
default:
break;
}
#endif // _DEMO_
return ok;
}
#ifndef _DEMO_
bool TDongle::burn_hardlock()
{
word data[4];
const TDate today(TODAY);
const bool already = already_programmed();
if (already)
{
memcpy(data, &_eprom[60], sizeof(data));
garble(data);
if (data[0] < 1997 || data[0] > 2997)
return error_box("On Line Assistance error.");
if (data[1] == 0 || data[1] >= 10000)
return error_box("Bad users number.");
const long& val = (const long&)data[2];
const long yyyymmdd = today.julian2date(val);
const TDate date(yyyymmdd);
if (date > today)
return error_box("Too late sir: key has already expired!");
}
data[0] = _year_assist;
data[1] = _max_users;
long& val = (long&)data[2];
val = today.date2julian();
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)
word module = 1;
for (int octect = 0; octect < 3; octect++)
{
for(int parola = 0; parola < 3; parola++)
{
word& 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 = TDate(TODAY);
sprintf(eh->_serno, "%lu", _serno);
eh->_year_assist = _year_assist;
eh->_max_users = _max_users;
eh->_last_date = atol(_last_update.string(ANSI));
eh->_scad_date = 0;
unsigned long cs = 0;
for (byte* ptr = (byte*)_eprom; ptr < (byte*)&eh->_checksum; ptr++)
cs += *ptr | ~(*ptr << 8);
eh->_checksum = cs;
bool ok = write_words(0, sizeof(TEutronHeader)/2, _eprom);
if (ok)
{
word data[16]; memset(data, 0, sizeof(data));
for (int module = 1; module < 256; module++)
{
if (active(module))
{
word& w = data[(module-1) / 16];
set_bit(w, (module-1) % 16, TRUE);
}
}
ok = write_words(16, 16, data);
}
return ok;
}
#endif // _DEMO_
bool TDongle::burn()
{
bool ok = local() && _type == _user_dongle;
#ifndef _DEMO_
if (ok)
{
switch(_hardware)
{
case _dongle_hardlock: ok = burn_hardlock(); break;
case _dongle_eutron : ok = burn_eutron(); break;
default : break;
}
}
#endif
if (ok)
_dirty = FALSE;
return ok;
}