#include "StdAfx.h" #include "hlapi_c.h" #define EYECAST (Word DATAFAR_ *) extern "C" { #include "skeytsr.h" } static KEY_NET _Eutron; #pragma pack(1) 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! }; #pragma pack() #include "connect.h" #include "server.h" #include "tracing.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // @doc INTERNAL // @rdesc Ritorna il valore corrispondente alla chiave appartenente // ad una sezione del file di configurazione CString GetIniString(LPCSTR sec, // @parm Sezione LPCSTR key, // @parm Chiave LPCSTR def) // @parm Valore di default { // Nome del file .ini static CString m_strIniFile; // Lunghezza massima di un nome di directory // o di un valore del file .ini const DWORD dwSize = _MAX_DIR + 1; // Costruisce il nome del file .ini se necessario if (m_strIniFile.IsEmpty()) { GetCurrentDirectory(dwSize, m_strIniFile.GetBuffer(dwSize)); m_strIniFile.ReleaseBuffer(); m_strIniFile += "\\prawin.ini"; } // Legge il valore della chiave nella sezione specificata CString tmp; char* buf = tmp.GetBuffer(dwSize); GetPrivateProfileString(sec, key, def, buf, dwSize, m_strIniFile); tmp.ReleaseBuffer(); return tmp; } // @doc EXTERNAL // @func Permette di criptare una parola // // @rdesc Ritorna la stringa criptata const char* Encode( const char* strin, // @parm Stringa da criptare char* strout) // @parm Stringa criptata // @xref { const char * const encryption_key = "QSECOFR-"; for (int i = 0; strin[i]; i++) strout[i] = strin[i] + (i < 8 ? encryption_key[i] : strin[i-8]); strout[i] = '\0'; return strout; } BOOL TDongleServer::ReadEutronWords(unsigned short reg, unsigned short num, unsigned short* data) { ASSERT(num > 0 && num <= 16); _Eutron.net_command = NET_KEY_ACCESS; memcpy(&_Eutron.command, BLOCK_READING_MODE, 2); unsigned short* pointer = (unsigned short*)(&_Eutron.data[0]); unsigned short* number = (unsigned short*)(&_Eutron.data[2]); *pointer = reg; *number = num; smartlink(&_Eutron); BOOL ok = _Eutron.status == ST_OK; if (ok) memcpy(data, &_Eutron.data[4], num*2); return ok; } BOOL TDongleServer::ReadHardlockWords(unsigned short reg, unsigned short num, unsigned short* data) { BOOL ok = HL_AVAIL() == STATUS_OK; if (ok) { for (unsigned short n = 0; n < num; n++) HL_READ(reg+n, EYECAST &data[n]); HL_CODE(EYECAST data, 1); } return ok; } BOOL TDongleServer::HardlockLogin() { const char* const REFKEY = "CAMPOKEY"; const char* const VERKEY = "ìpÙˆ¬cê<"; unsigned char ref[9]; strcpy((char*)ref, REFKEY); unsigned char ver[9]; strcpy((char*)ver, VERKEY); const int status = HL_LOGIN(26952, LOCAL_DEVICE, ref, ver); Trace(-1, "Login Hardlock %s: %d", status == STATUS_OK ? "OK" : "FALLITO", status); _SerNo = 0xFFFF; if (status == STATUS_OK) { Word Val[4] = { 0, 0, 0, 0 }; ReadHardlockWords(0, 4, Val); if (Val[0] == 0xFAE8) _SerNo = Val[1]; else _SerNo = 0; if (_SerNo != 0) { ReadHardlockWords(60, 4, Val); _AssistanceYear = Val[0]; _MaxUsers = Val[1]; int index = 0; for (unsigned short reg = 48; reg < 60; reg += 4) { ReadHardlockWords(reg, 4, Val); Val[0] ^= _SerNo; Val[1] ^= _SerNo; Val[2] ^= _SerNo; memcpy(&_int_tab[index], Val, 3); index += 3; } } } return status == STATUS_OK; } BOOL TDongleServer::EutronLogin() { BOOL ok = FALSE; memset(&_Eutron, 0, sizeof(_Eutron)); _Eutron.net_command = NET_KEY_OPEN; const char* labels[2] = { "AGA.CAMPO", "25EBAI" }; for (int k = 0; k < 2; k++) { memset(_Eutron.label, 0, LABEL_LENGTH); memcpy(_Eutron.label, labels[k], strlen(labels[k])); memset(_Eutron.password, 0, PASSWORD_LENGTH); if (k == 0) { char pwd[PASSWORD_LENGTH]; Encode(labels[k], pwd); memcpy(_Eutron.password, pwd, strlen(pwd)); } smartlink(&_Eutron); ok = _Eutron.status == ST_OK; if (ok) { if (k == 1) _SerNo = 0; break; } } Trace(-1, "Login Eutron %s: %d", ok ? "OK" : "FALLITO", _Eutron.status); if (ok && _SerNo != 0) { TEutronHeader eh; if (ReadEutronWords(0, sizeof(TEutronHeader)/2, (unsigned short*)&eh)) { char serno[16]; strncpy(serno, eh._serno, 8); serno[8] = '\0'; _SerNo = (unsigned long)atol(serno); if (eh._max_users > 0) { _MaxUsers = eh._max_users; _AssistanceYear = eh._year_assist; ReadEutronWords(16, 16, _int_tab); } } } return _Eutron.status == ST_OK; } BOOL TDongleServer::Login() { BOOL ok = HardlockLogin() || EutronLogin(); if (ok) { if (_SerNo == 0 || _MaxUsers == 0) { const CTime tNow = CTime::GetCurrentTime(); _AssistanceYear = tNow.GetYear(); if (_SerNo == 0) { _MaxUsers = 4; memset(_int_tab, 0xFF, sizeof(_int_tab)); } else { _MaxUsers = 1; memset(_int_tab, 0x00, sizeof(_int_tab)); } } Trace(-1, "Numero di serie %u", _SerNo); Trace(-1, "Anno assistenza %u", _AssistanceYear); Trace(-1, "Numero utenti %u", _MaxUsers); CString modules = "Moduli attivi: "; if (_SerNo > 0 && _SerNo != 0xFFFF) { for (int n = 0; n < MAX_MODULES; n++) { const unsigned short index = n / 16; if (index < 4) { if ((_int_tab[index] >> (n % 16)) & 0x1) { char buff[24]; sprintf(buff, "%d ", n+1); modules += buff; } } } } else { if (_SerNo == 0) modules += "Tutti"; else modules += "Nessuno"; } Trace(-1, modules); } return ok; } void TDongleServer::Logout() { if (_Eutron.label[0]) { _Eutron.net_command = NET_KEY_CLOSE; smartlink(&_Eutron); } else { HL_LOGOUT(); } _SerNo = 0xFFFF; _MaxUsers = 0; _AssistanceYear = 0; memset(_int_tab, 0, sizeof(_int_tab)); } BOOL TDongleServer::OnConnect(const CString& topic) { BOOL ok = Users() < MaxUsers(); if (!ok) Trace(0, "Refusing Topic %s", (const char*)topic); return ok; } TConnection* TDongleServer::OnCreateConnection(DWORD id) { TConnection* c = NULL; CString strPeer; GetPeerName(id, strPeer); const int n = GetPeerConnections(strPeer); if (n > 0 || Peers() < MaxUsers()) { Trace(0, "Connecting %lu from %s", id, strPeer); c = new TPrassiConnection(this, id, strPeer); } else Trace(0, "Refusing Connection %lu from %s", id, strPeer); return c; } BOOL TDongleServer::OnRemoveConnection(DWORD id) { CString strPeer; GetPeerName(id, strPeer); Trace(0, "Disconnecting %lu from %s", id, strPeer); return BASE_SERVER::OnRemoveConnection(id); } static int CountUsers(TConnection& conn, void* pJolly) { CMapStringToOb& users = *(CMapStringToOb*)pJolly; const TPrassiConnection& c = (TPrassiConnection&)conn; const CString& name = c.User(); BOOL ok = name != "******"; if (ok) users.SetAt(name, NULL); return ok; } unsigned short TDongleServer::Users() const { CMapStringToOb u; ((TDongleServer*)this)->ForEachConnection(CountUsers, &u); unsigned short nTotal = (unsigned short)u.GetCount(); return nTotal; } static int CountPeerConnections(TConnection& conn, void* pJolly) { const CString& name = *(const CString*)pJolly; const TPrassiConnection& c = (TPrassiConnection&)conn; return c.PeerName() == name; } int TDongleServer::GetPeerConnections(const CString& strPeer) const { int nTotal = ((TDongleServer*)this)->ForEachConnection(CountPeerConnections, (void*)&strPeer); return nTotal; } static int CountPeers(TConnection& conn, void* pJolly) { CMapStringToOb& users = *(CMapStringToOb*)pJolly; const TPrassiConnection& c = (TPrassiConnection&)conn; const CString& name = c.PeerName(); users.SetAt(name, NULL); return 1; } unsigned short TDongleServer::Peers() const { CMapStringToOb u; ((TDongleServer*)this)->ForEachConnection(CountPeers, &u); unsigned short nTotal = (unsigned short)u.GetCount(); return nTotal; } TDongleServer::TDongleServer() : BASE_SERVER("DONGLE") { _SerNo = 0xFFFF; _MaxUsers = 0; _AssistanceYear = 0; memset(_int_tab, 0, sizeof(_int_tab)); Login(); } TDongleServer::~TDongleServer() { if (_SerNo != 0xFFFF) Logout(); } /////////////////////////////////////////////////////////// // Start/Stop server static TDongleServer* pDDE = NULL; BOOL StopServer() { BOOL ok = pDDE != NULL; if (ok) { delete pDDE; pDDE = NULL; } return ok; } TDongleServer& GetServer() { ASSERT(pDDE); return *pDDE; } BOOL StartServer() { BOOL ok = pDDE == NULL; if (ok) pDDE = new TDongleServer; return ok; }