campo-sirio/include/smartcard.cpp
alex d030bbabe2 Patch level : 4.0 667
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

Riportata la versione 3.1 patch 766


git-svn-id: svn://10.65.10.50/trunk@14628 c028cbd2-c16b-5b4b-a496-9718f37d4682
2006-12-13 16:22:33 +00:00

513 lines
13 KiB
C++
Executable File

#define __SMARTCARD_CPP
#ifdef WIN32
#include <windows.h>
#endif
#include <config.h>
#include <diction.h>
#include <recarray.h>
#include <smartcard.h>
#include <tabutil.h>
#include <utility.h>
#ifdef WIN32
#include <ase/include/ASEMemCard.h>
typedef unsigned long (ASEMEM_API FASEListReaders)(char * readersList, unsigned long * length);
typedef unsigned long (ASEMEM_API FASEWaitForCardEvent)(char * reader, unsigned char inOut, unsigned long timeOut);
typedef unsigned long (ASEMEM_API FASEMemConnect)(ASEMEM_HANDLE * hCard, char * reader, unsigned long connectMode, unsigned long * cardType);
typedef unsigned long (ASEMEM_API FASEMemDisconnect)(ASEMEM_HANDLE hCard, char mode);
typedef unsigned long (ASEMEM_API FASEMemWrite)(ASEMEM_HANDLE hCard, unsigned long address, unsigned char * writeBuffer, unsigned long lenWrite, char protect);
typedef unsigned long (ASEMEM_API FASEMemRead)(ASEMEM_HANDLE hCard, unsigned long address, unsigned char * readBuffer, unsigned char * protReadBuffer, unsigned long lenRead);
typedef unsigned long (ASEMEM_API FASEMemVerifyPassword)(ASEMEM_HANDLE hCard, unsigned char * password, unsigned long length, int * attempts);
typedef unsigned long (ASEMEM_API FASEMemChangePassword)(ASEMEM_HANDLE hCard,unsigned char * oldPassword, unsigned char * newPassword, unsigned long length, int * attempts);
typedef FASEListReaders * LPASEListReaders;
typedef FASEWaitForCardEvent * LPASEWaitForCardEvent;
typedef FASEMemConnect * LPASEMemConnect;
typedef FASEMemDisconnect * LPASEMemDisconnect;
typedef FASEMemWrite * LPASEMemWrite;
typedef FASEMemRead * LPASEMemRead;
typedef FASEMemVerifyPassword * LPASEMemVerifyPassword;
typedef FASEMemChangePassword * LPASEMemChangePassword;
HINSTANCE _hlibASE = NULL;
LPASEListReaders lpfnASEListReaders = NULL;
LPASEWaitForCardEvent lpfnASEWaitForCardEvent = NULL;
LPASEMemConnect lpfnASEMemConnect = NULL;
LPASEMemDisconnect lpfnASEMemDisconnect = NULL;
LPASEMemWrite lpfnASEMemWrite = NULL;
LPASEMemRead lpfnASEMemRead = NULL;
LPASEMemVerifyPassword lpfnASEMemVerifyPassword = NULL;
LPASEMemChangePassword lpfnASEMemChangePassword = NULL;
#endif
bool TSmart_card::ASEloadlibrary()
{
#ifdef WIN32
if (_hlibASE) // Check in already loaded
return TRUE;
UINT fuError = SetErrorMode(SEM_NOOPENFILEERRORBOX);
_hlibASE = LoadLibrary("ASEMemory.dll");
SetErrorMode(fuError);
if (_hlibASE == NULL)
return error_box(TR("ASEMemory.dll mancante"));
if (_hlibASE < (HINSTANCE)HINSTANCE_ERROR)
{
DWORD err = *((DWORD*)_hlibASE) & 0xFFFF;
_hlibASE = NULL;
return error_box(FR("Errore di caricamento di ASEMemory.dll: %lu"), err);
}
if (!(lpfnASEListReaders = (LPASEListReaders)GetProcAddress (_hlibASE, "ASEListReaders"))) return FALSE;
if (!(lpfnASEWaitForCardEvent = (LPASEWaitForCardEvent)GetProcAddress (_hlibASE, "ASEWaitForCardEvent"))) return FALSE;
if (!(lpfnASEMemConnect = (LPASEMemConnect)GetProcAddress (_hlibASE, "ASEMemConnect"))) return FALSE;
if (!(lpfnASEMemDisconnect = (LPASEMemDisconnect)GetProcAddress (_hlibASE, "ASEMemDisconnect"))) return FALSE;
if (!(lpfnASEMemWrite = (LPASEMemWrite)GetProcAddress (_hlibASE, "ASEMemWrite"))) return FALSE;
if (!(lpfnASEMemRead = (LPASEMemRead)GetProcAddress (_hlibASE, "ASEMemRead"))) return FALSE;
if (!(lpfnASEMemVerifyPassword = (LPASEMemVerifyPassword)GetProcAddress (_hlibASE, "ASEMemVerifyPassword"))) return FALSE;
if (!(lpfnASEMemChangePassword = (LPASEMemChangePassword)GetProcAddress (_hlibASE, "ASEMemChangePassword"))) return FALSE;
#endif
return TRUE;
}
TSmart_card::TSmart_card()
{
init();
}
unsigned long TSmart_card::ASEsearch()
{
_ASE_reader_name.cut(0);
unsigned long len;
unsigned long status = lpfnASEListReaders(NULL, &len);
if (status != ASEMEM_S_SUCCESS)
return status;
char * readerList = new(char[len]);
if (readerList == NULL)
return ASEMEM_E_NO_MEMORY;
status = lpfnASEListReaders(readerList, &len);
if (status == ASEMEM_S_SUCCESS)
{
_ASE_reader_name = readerList;
if (_ASE_reader_name.empty())
status = ASEMEM_E_NO_READERS_AVAILABLE;
}
_has_pwd = false;
delete readerList;
return status;
}
unsigned long TSmart_card::ASEread(char ** buffer)
{
ASEMEM_HANDLE hcard;
unsigned long type;
unsigned long status = lpfnASEMemConnect(&hcard, (char *)(const char *)_ASE_reader_name, ASEMEM_SHARE_SHARED, &type);
unsigned char stdpassword[3] = {0xFF, 0xFF, 0xFF};
if (status != ASEMEM_S_SUCCESS)
return status;
_has_pwd = type == ASEMEM_CARD_TYPE_2BUS || type != ASEMEM_CARD_TYPE_3BUS;
if (_has_pwd)
{
unsigned long passwordLength = (type == ASEMEM_CARD_TYPE_2BUS) ? ASEMEM_2BUS_PASSWORD_LENGTH : ASEMEM_3BUS_PASSWORD_LENGTH;
int attempts = 0;
status = lpfnASEMemVerifyPassword(hcard, stdpassword, passwordLength, &attempts);
if (status == ASEMEM_E_PASSWORD_VERIFICATION_FAILED)
{
lpfnASEMemDisconnect(&hcard, ASEMEM_RESET_CARD);
return status;
}
}
unsigned char len;
const int offset = _has_pwd ? 32 : 0;
status = lpfnASEMemRead(hcard, offset, &len, NULL, 1);
if (status == ASEMEM_S_SUCCESS && len == 1)
{
status = lpfnASEMemRead(hcard, offset+1, &len, NULL, 1);
if (status == ASEMEM_S_SUCCESS)
{
if (*buffer == NULL)
*buffer = new(char[len+1]);
status = lpfnASEMemRead(hcard, offset+2, (unsigned char *) *buffer, NULL, (int) len);
if (status == ASEMEM_S_SUCCESS)
(*buffer)[len] = '\0';
else
(*buffer)[0] = '\0';
}
}
else
ASEwrite("0");
lpfnASEMemDisconnect(&hcard, ASEMEM_LEAVE_CARD);
return status;
}
unsigned long TSmart_card::ASEwrite(char * buffer) const
{
ASEMEM_HANDLE hcard;
unsigned long type;
unsigned long status = lpfnASEMemConnect(&hcard, (char *)(const char *)_ASE_reader_name, ASEMEM_SHARE_SHARED, &type);
if (status != ASEMEM_S_SUCCESS)
return status;
unsigned char len = 1;
const int offset = _has_pwd ? 32 : 0;
status = lpfnASEMemWrite(hcard, offset, &len, 1, ASEMEM_WRITE_MODE);
if (status == ASEMEM_S_SUCCESS)
{
len = strlen(buffer);
status = lpfnASEMemWrite(hcard, offset+1, &len, 1, ASEMEM_WRITE_MODE);
if (status == ASEMEM_S_SUCCESS)
status = lpfnASEMemWrite(hcard, offset+2, (unsigned char *)buffer, (int) len, ASEMEM_WRITE_MODE);
}
lpfnASEMemDisconnect(&hcard, ASEMEM_LEAVE_CARD);
return status;
}
static smartcard_error ASEmap_error(unsigned long error)
{
switch (error)
{
case ASEMEM_S_SUCCESS:
return no_smarterror;
case ASEMEM_E_FUNCTION_NOT_SUPPORTED:
return wrong_function;
case ASEMEM_E_REMOVED_CARD:
return card_removed;
case ASEMEM_E_UNPOWERED_CARD:
return no_power;
case ASEMEM_E_UNSUPPORTED_CARD:
return wrong_card;
case ASEMEM_E_PASSWORD_VERIFICATION_FAILED:
return wrong_password;
case ASEMEM_E_PASSWORD_BLOCKED:
return password_blocked;
case ASEMEM_E_INVALID_HANDLE:
return invelid_handle;
case ASEMEM_E_INVALID_PARAMETER:
return invalid_parameter;
case ASEMEM_E_NO_SMARTCARD:
return no_card;
case ASEMEM_E_RESET_CARD:
return reset_card;
case ASEMEM_E_SHARING_VIOLATION:
return protection_error;
case ASEMEM_E_UNKNOWN_READER:
return unknown_reader;
case ASEMEM_E_NO_READERS_AVAILABLE:
return no_reader;
case ASEMEM_E_INSUFFICIENT_BUFFER:
return buffer_overflow;
case ASEMEM_E_SERVICE_STOPPED:
return sevice_stopped;
case ASEMEM_E_TIMEOUT :
return timeout_err;
case ASEMEM_E_NO_MEMORY:
return no_memory;
case ASEMEM_E_UNKNOWN_ERROR:
default:
return unknown_err;
}
}
void TSmart_card::display_error(smartcard_error error) const
{
switch (error)
{
case no_smarterror:
break;
case wrong_function:
error_box(TR("Funzione errata"));
break;
case card_removed:
error_box(TR("Smartcard rimossa"));
break;
case no_power:
error_box(TR("Smartcard non alimentata"));
break;
case wrong_card:
error_box(TR("Smartcard errata"));
break;
case wrong_password:
error_box(TR("Password errata"));
break;
case password_blocked:
error_box(TR("Password bloccata"));
break;
case invelid_handle:
error_box(TR("Handle errata"));
break;
case invalid_parameter:
error_box(TR("Parametro errato"));
break;
case no_card:
error_box(TR("Smartcard rimossa"));
break;
case reset_card:
error_box(TR("Smartcard rinizializzata"));
break;
case protection_error:
error_box(TR("Errore di protezione"));
break;
case unknown_reader:
error_box(TR("Lettore sconosciuto"));
break;
case no_reader:
error_box(TR("Nessun lettore rilevato"));
break;
case buffer_overflow:
error_box(TR("Buffer overflow"));
break;
case sevice_stopped:
error_box(TR("Servizio fermato"));
break;
case timeout_err:
error_box(TR("Timeout"));
break;
case no_memory:
error_box(TR("No memory"));
break;
case new_card:
message_box(TR("Smartcard nuova"));
break;
case unknown_err:
error_box(TR("Errore sconosciuto"));
default:
break;
}
}
smartcard_error TSmart_card::read()
{
_values.destroy();
smartcard_error error = no_smarterror;
if (_type == ase_smartcard)
{
char * buffer = NULL;
error = ASEmap_error(ASEread(&buffer));
if (error == no_smarterror)
{
TToken_string t((const char *)buffer);
for (const char * s = t.get(); s && *s != '\0'; s = t.get())
_values.add(s);
if (t.empty())
error = new_card;
}
int i;
for (i = _values.items(); i < _last_smart_field; i++)
_values.add("");
const TRectype & tabrec = cache().get("SMC", _values.row(_key_field));
for (; i < _num_fields; i++)
{
const TString & val = tabrec.get(_tab_field.row(i));
_values.add(val);
}
if (buffer != NULL)
delete buffer;
}
_card_connected = (error == no_smarterror || error == new_card);
return error;
}
smartcard_error TSmart_card::connect_card()
{
return read();
}
smartcard_error TSmart_card::disconnect_card()
{
_card_connected = false;
return no_smarterror;
}
smartcard_error TSmart_card::write() const
{
TToken_string t;
int i;
smartcard_error error;
for (i = 0; i < _last_smart_field; i++)
t.add(_values.row(i));
TTable tab("SMC");
tab.put("CODTAB", _values.row(_key_field));
bool new_rec = tab.read(_isequal, _lock) != NOERR;
for (i = 0 ; i < _num_fields; i++)
if (!_tab_field.row(i).empty())
{
if (i == _anno_field || i == _ndoc_field)
{
if (tab.get_int(_tab_field.row(i)) < atoi(_values.row(i)))
tab.put(_tab_field.row(i), _values.row(i));
}
else
tab.put(_tab_field.row(i), _values.row(i));
}
if (new_rec)
tab.write();
else
tab.rewrite();
if (_type == ase_smartcard)
error = ASEmap_error(ASEwrite((char *)(const char *)t));
return error;
}
void TSmart_card::mask2card(const TMask & m)
{
_values.destroy();
for (int i = 0; i < _num_fields; i++)
{
const TString & val = m.get(_output_field[i]);
_values.add(val, i);
}
}
smartcard_error TSmart_card::check_key(const TMask & m)
{
const TString & card_key = _values.row(_key_field);
const TString & mask_key = m.get(_input_field[_key_field]);
const bool ok = (mask_key.empty() || card_key == mask_key);
if (!ok)
disconnect_card();
return ok ? no_smarterror : wrong_card;
}
void TSmart_card::card2mask(TMask & m)
{
for (int i = 0; i < _num_fields; i++)
if (_input_field[i] >= 0)
{
if (_prog_field[i] > 0)
{
const int anno_fld = anno_field();
const int ndoc_fld = ndoc_field();
const int last_anno = get_int(anno_fld);
const int last_ndoc = get_int(ndoc_fld);
const int anno = m.get_int(_output_field[anno_fld]);
const int ndoc = m.get_int(_output_field[ndoc_fld]);
if (anno > last_anno)
sub2field(i, m.get_real(_prog_field[i]));
if (anno == last_anno && ndoc <= last_ndoc)
sub2field(i, m.get_real(_prog_field[i]));
}
const TString & val = _values.row(i);
m.set(_input_field[i], val, 3);
}
m.set(_check_field, card_connected());
}
void TSmart_card::enable_prot_fields(TMask & m, bool on) const
{
for (int i = 0; i < _num_fields; i++)
if (_prot_field[i])
m.enable(_input_field[i], on);
}
void TSmart_card::add2field(int field, real & val)
{
real field_val(_values.row(field));
field_val += val;
_values.add(field_val.string(), field);
}
bool TSmart_card::init()
{
// Identify card
_card_connected = false;
TFilename f("smartcard.ini");
if (f.custom_path())
{
TConfig c(f, "ve0100");
switch (c.get_int("Type"))
{
case 0:
_type = no_smartcard;
break;
case 1:
{
if (ASEloadlibrary())
{
smartcard_error err = ASEmap_error(ASEsearch());
if (err == no_reader)
_type = no_smartcard;
else
_type = ase_smartcard;
}
else
_type = no_smartcard;
}
break;
default:
_type = no_smartcard;
break;
}
_last_smart_field = c.get_int("FieldsOnCard");
_password = c.get("Password").left(3);
_anno_field = c.get_int("AnnoField");
_ndoc_field = c.get_int("NDocField");
_check_field = c.get_int("CheckField");
for (_num_fields = 0; _num_fields < MAX_SM_FIELDS; _num_fields++)
{
_input_field[_num_fields] = c.get_int("InputFld", NULL, _num_fields);
if (_input_field[_num_fields] != 0)
{
_output_field[_num_fields] = c.get_int("OutputFld", NULL, _num_fields, _input_field[_num_fields]);
_prog_field[_num_fields] = c.get_int("ProgFld", NULL, _num_fields);
_prot_field.set(_num_fields, c.get_bool("ProtFld", NULL, _num_fields));
_tab_field.add(c.get("TabFld", NULL, _num_fields, ""), _num_fields);
if (_tab_field.row(_num_fields) == "CODTAB")
_key_field = _num_fields;
}
else
break;
}
}
return true;
}