Ako ste delphi programer kontaktirajte me i ukjucite se u novim projectima .
unit module-newcamd-0rginal_c;
interface
uses
Windows, Messages, SysUtils, Classes;
const CWS_NETMSGSIZE = 272;
{$EXTERNALSYM CWS_NETMSGSIZE}
type
uint8 = type Byte;
{$EXTERNALSYM uint8}
Puint8 = ^uint8;
{$EXTERNALSYM Puint8}
type
uint16 = type WORD;
{$EXTERNALSYM uint16}
Puint16 = ^uint16;
{$EXTERNALSYM Puint16}
type
uint32 = type WORD;
{$EXTERNALSYM uint32}
Puint32 = ^uint32;
{$EXTERNALSYM Puint32}
type
LongIntuint64 = type Cardinal;
{$EXTERNALSYM LongIntuint64}
PLongIntuint64 = ^LongIntuint64;
{$EXTERNALSYM PLongIntuint64}
const CWS_FIRSTCMDNO = $e0;
{$EXTERNALSYM CWS_FIRSTCMDNO}
type const
(**** Convert following enum types to constants. ****
**** e.g. v1 = n, where v1 is constant and n is the value ****
**** if a constant has a value, do not assign a new value ****)
begin
MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
MSG_CLIENT_2_SERVER_LOGIN_ACK,
MSG_CLIENT_2_SERVER_LOGIN_NAK,
MSG_CARD_DATA_REQ,
MSG_CARD_DATA,
MSG_SERVER_2_CLIENT_NAME,
MSG_SERVER_2_CLIENT_NAME_ACK,
MSG_SERVER_2_CLIENT_NAME_NAK,
MSG_SERVER_2_CLIENT_LOGIN,
MSG_SERVER_2_CLIENT_LOGIN_ACK,
MSG_SERVER_2_CLIENT_LOGIN_NAK,
MSG_ADMIN,
MSG_ADMIN_ACK,
MSG_ADMIN_LOGIN,
MSG_ADMIN_LOGIN_ACK,
MSG_ADMIN_LOGIN_NAK,
MSG_ADMIN_COMMAND,
MSG_ADMIN_COMMAND_ACK,
MSG_ADMIN_COMMAND_NAK,
MSG_KEEPALIVE = CWS_FIRSTCMDNO + $1d
end; net_msg_type
= type ;
{$EXTERNALSYM }
P = ^;
{$EXTERNALSYM P}t
(**** Convert following enum types to constants. ****
**** e.g. v1 = n, where v1 is constant and n is the value ****
**** if a constant has a value, do not assign a new value ****)
begin
COMMTYPE_CLIENT,
COMMTYPE_SERVER
end; comm_type
= type ;
{$EXTERNALSYM }
P = ^;
{$EXTERNALSYM P}EQ_SIZE 2
uchar *req:=0;
integer ncd_proto:=NCD_AUTO;
integer network_message_send(integer handle, uint16 *netMsgId, uint8 *buffer,
integer len, uint8 *deskey, comm_type_t commType,
ushort sid)
begin
netbuf: array[0..CWS_NETMSGSIZE-1] of uint8;
integer head_size;
head_size := (ncd_proto = NCD_524)?8:12;
if (len < 3 or len + head_size > CWS_NETMSGSIZE or handle < 0) then
result:= -1;
buffer[1] := (buffer[1] and $f0) or (((len - 3) shr
and $0f);
buffer[2] := (len - 3) and $ff;
memcpy(netbuf+head_size, buffer, len);
len:= mod + head_size;
if (netMsgId) then begin
case(commType) of
begin
COMMTYPE_CLIENT:
(netMsgId):= mod + 1;
break;
COMMTYPE_SERVER:
if( *netMsgId := $FFFE ) *netMsgId = 0; // èëè 0xFFFF ?
break;
end;
netbuf[2] := (netMsgId) shr 8;
netbuf[3] := (netMsgId) and $ff;
end;
else
netbuf[2] := netbuf[3] = 0;
FillChar(netbuf+4, 0, (ncd_proto := NCD_524)?4:
;
if( sid ) then begin
netbuf[(ncd_proto := NCD_524)?6:4] = (uchar((sid shr
; //sid
netbuf[(ncd_proto := NCD_524)?7:5] = (uchar((sid);
end;
netbuf[0] := (len - 2) shr 8;
netbuf[1] := (len - 2) and $ff;
cs_ddump(netbuf, len, 'send mod d bytes to mod s', len, remote_txt());
if ((len = des_encrypt(netbuf, len, deskey)) < 0) then
result:= -1;
netbuf[0] := (len - 2) shr 8;
netbuf[1] := (len - 2) and $ff;
result:= send(handle, netbuf, len, 0);
end;
integer network_message_receive(integer handle, uint16 *netMsgId, uint8 *buffer,
uint8 *deskey, comm_type_t commType)
begin
integer len, ncd_off, msgid;
netbuf: array[0..CWS_NETMSGSIZE-1] of uint8;
integer returnLen;
if ( not buffer or handle < 0) then
result:= -1;
len := recv(handle, netbuf, 2, 0);
cs_debug('nmr(): len:= mod d, errno= mod d', len, (len = -1)?errno:0);
if ( not len) then begin
cs_debug('nmr: 1 result:= 0');
network_tcp_connection_close(handle);
result:= 0;
end;
if (len <> 2) then begin
cs_debug('nmr: len <> 2');
network_tcp_connection_close(handle);
result:= -1;
end;
if (((netbuf[0] shl
or netbuf[1]) > CWS_NETMSGSIZE - 2) then begin
cs_debug('nmr: 1 result:= -1');
result:= -1;
end;
len := recv(handle, netbuf+2, (netbuf[0] shl
or netbuf[1], 0);
if ( not len) then begin
cs_debug('nmr: 2 result:= 0');
result:= 0;
end;
if (len <> ((netbuf[0] shl
or netbuf[1])) then begin
cs_debug('nmr: 2 result:= -1');
result:= -1;
end;
len:= mod + 2;
if ((len = des_decrypt(netbuf, len, deskey)) < 11 ) begin // 15(newcamd525) then or 11
cs_debug('nmr: can't decrypt, invalid des key?');
sleep(2);
result:= -1;
end;
//cs_ddump(netbuf, len, "nmr: decrypted data, len=%d", len);
msgid := (netbuf[2] shl
or netbuf[3];
if( ncd_proto = NCD_AUTO ) then begin
// auto detect
integer l5 := (((netbuf[13] and $0f) shl
or netbuf[14]) + 3;
integer l4 := (((netbuf[9] and $0f) shl
or netbuf[10]) + 3;
if( (l5<=len-12) and ((netbuf[12] and $F0) = $E0 or (netbuf[12] and $F0) = $80) )
ncd_proto := NCD_525;
else if( (l4<=len-8) and ((netbuf[8] and $F0) = $E0 or (netbuf[9] and $F0) = $80) )
ncd_proto := NCD_524;
else begin
cs_debug('nmr: 4 result:= -1');
result:= -1;
end;
cs_debug('nmr: autodetect: newcamd52 mod d used', (ncd_proto := NCD_525)?5:4);
end;
ncd_off:=(ncd_proto = NCD_525)?4:0;
returnLen := (((netbuf[9+ncd_off] and $0f) shl
or netbuf[10+ncd_off]) + 3;
if ( returnLen > (len-(8+ncd_off)) ) then begin
cs_debug('nmr: 4 result:= -1');
result:= -1;
end;
// cs_ddump(netbuf, len, "nmr: decrypted data");
if (netMsgId) then
begin
case (commType) of
begin
COMMTYPE_SERVER:
*netMsgId := msgid;
break;
COMMTYPE_CLIENT:
//if (*netMsgId != ((netbuf[2] <<
| netbuf[3])) {
cs_debug('nmr: netMsgId:= mod d, from server= mod d, ', *netMsgId, msgid );
//return -2;
//}
break;
default:
cs_debug('nmr: 5 result:= -1');
result:= -1;
break;
end;
end;
case(commType) of
begin
COMMTYPE_SERVER:
buffer[0]:=(ncd_proto = NCD_525)?netbuf[4]:netbuf[6]; // sid
buffer[1]:=(ncd_proto = NCD_525)?netbuf[5]:netbuf[7];
break;
COMMTYPE_CLIENT:
buffer[0]:=netbuf[2]; // msgid
buffer[1]:=netbuf[3];
break;
end;
memcpy(buffer+2, netbuf+(8+ncd_off), returnLen);
result:= returnLen+2;
end;
procedure network_cmd_no_data_send(handle: integer; var netMsgId: uint16; cmd: net_msg_type_t; var deskey: uint8; commType: comm_type_t)
begin
buffer: array[0..CWS_NETMSGSIZE-1] of uint8;
buffer[0] := cmd; buffer[1] = 0;
network_message_send(handle, netMsgId, buffer, 3, deskey, commType, 0);
end;
integer network_cmd_no_data_receive(integer handle, uint16 *netMsgId,
uint8 *deskey, comm_type_t commType)
begin
buffer: array[0..CWS_NETMSGSIZE-1] of uint8;
if (network_message_receive(handle, netMsgId, buffer, deskey, commType) <> 3+2) then
result:= -1;
result:= buffer[2];
end;
integer
connect_nonb(integer sockfd, struct sockaddr *saptr, socklen_t salen, integer nsec)
begin
integer flags, n, error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;
flags := fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags or O_NONBLOCK);
error := 0;
cs_debug('conn_nb 1 (fd:= mod d)', sockfd);
if ( (n = connect(sockfd, saptr, salen)) < 0) then begin
if( errno = EALREADY ) then begin
cs_debug('conn_nb in progress, errno:= mod d', errno);
result:= (-1);
end;
else if( errno = EISCONN ) then begin
cs_debug('conn_nb already connected, errno:= mod d', errno);
goto done;
end;
cs_debug('conn_nb 2 (fd:= mod d)', sockfd);
if (errno <> EINPROGRESS) then begin
cs_debug('conn_nb 3 (fd:= mod d)', sockfd);
result:= (-1);
end;
end;
(* Do whatever we want while the connect is taking place. *)
if (n = 0) then
goto done; (* connect completed immediately *)
FD_ZERO( and rset);
FD_SET(sockfd, and rset);
wset := rset;
tval.tv_sec := nsec;
tval.tv_usec := 0;
if ( (n = select(sockfd+1, and rset, and wset, 0, nsec ? and tval : 0)) = 0) then begin
//close(sockfd); // timeout
cs_debug('conn_nb 4 (fd:= mod d)', sockfd);
errno := ETIMEDOUT;
result:= (-1);
end;
cs_debug('conn_nb 5 (fd:= mod d)', sockfd);
if (FD_ISSET(sockfd, and rset) or FD_ISSET(sockfd, and wset)) then begin
cs_debug('conn_nb 6 (fd:= mod d)', sockfd);
len := SizeOf(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, and error, and len) < 0) then begin
cs_debug('conn_nb 7 (fd:= mod d)', sockfd);
result:= (-1); // Solaris pending error
end;
end; else begin
cs_debug('conn_nb 8 (fd:= mod d)', sockfd);
result:= -2;
end;
done:
cs_debug('conn_nb 9 (fd:= mod d)', sockfd);
fcntl(sockfd, F_SETFL, flags); (* restore file status flags *)
if (error) then begin
cs_debug('conn_nb 10 (fd:= mod d)', sockfd);
//close(sockfd); /* just in case */
errno := error;
result:= (-1);
end;
result:=(0);
end;
integer network_tcp_connection_open(uint8 *hostname, uint16 port)
begin
integer flags;
if( connect_nonb(client[cs_idx].udp_fd, then
(struct sockaddr ) and client[cs_idx].udp_sa,
SizeOf(client[cs_idx].udp_sa), 5) < 0)
begin
cs_log('connect(fd:= mod d) failed: (errno= mod d)', client[cs_idx].udp_fd, errno);
result:= -1;
end;
flags := fcntl(client[cs_idx].udp_fd, F_GETFL, 0);
flags and :=~ O_NONBLOCK;
fcntl(client[cs_idx].udp_fd, F_SETFL, flags );
result:= client[cs_idx].udp_fd;
end;
procedure newcamd_reply_ka()
begin
if( not client[cs_idx].udp_fd ) then
begin
cs_debug('invalid client fd:= mod d', client[cs_idx].udp_fd);
Exit;
end;
cs_debug('send keep_alive');
network_cmd_no_data_send(client[cs_idx].udp_fd, and client[cs_idx].ncd_msgid,
MSG_KEEPALIVE, client[cs_idx].ncd_skey,
COMMTYPE_SERVER);
end;
integer connect_newcamd_server()
begin
uint32 i;
buf: array[0..CWS_NETMSGSIZE-1] of uint8;
keymod: array[0..14-1] of uint8;
uint8 *key;
integer handle:=0;
uint32 index;
uint8 *passwdcrypt;
uint8 login_answer;
integer bytes_received;
if(reader[ridx].device[0] = 0 or reader[ridx].r_pwd[0] = 0 or then
reader[ridx].r_usr[0] = 0 or reader[ridx].r_port = 0)
result:= -5;
// 1. Connect
//
handle := network_tcp_connection_open((uint8 )reader[ridx].device, reader[ridx].r_port);
if(handle < 0) then result:= -1;
// 2. Get init sequence
//
reader[ridx].ncd_msgid := 0;
if( read(handle, keymod, SizeOf(keymod)) <> SizeOf(keymod)) then begin
cs_log('server does not result:= 14 bytes');
network_tcp_connection_close(handle);
result:= -2;
end;
cs_ddump(keymod, 14, 'server init sequence:');
key := des_login_key_get(keymod, reader[ridx].ncd_key, 14);
// 3. Send login info
//
index := 3;
buf[0] := MSG_CLIENT_2_SERVER_LOGIN;
buf[1] := 0;
StrCopy((Char )buf+index, reader[ridx].r_usr);
passwdcrypt := (uint8*)__md5_crypt(reader[ridx].r_pwd, "$1$abcdefgh$");
index:= mod + strlen(reader[ridx].r_usr)+1;
StrCopy((function )buf+index, ( Char )passwdcrypt): Char;
//cs_debug("login to server %s:%d user=%s, pwd=%s, len=%d", reader[ridx].device,
// reader[ridx].r_port, reader[ridx].r_usr, reader[ridx].r_pwd,
// index+strlen(passwdcrypt)+1);
network_message_send(handle, 0, buf, index+strlen((Char )passwdcrypt)+1, key,
COMMTYPE_CLIENT, $8888);
// 3.1 Get login answer
//
login_answer=network_cmd_no_data_receive(handle, and reader[ridx].ncd_msgid,
key, COMMTYPE_CLIENT);
if( login_answer = MSG_CLIENT_2_SERVER_LOGIN_NAK ) then
begin
cs_log('login failed for user ' mod s'', reader[ridx].r_usr);
network_tcp_connection_close(handle);
result:= -3;
end;
if( login_answer <> MSG_CLIENT_2_SERVER_LOGIN_ACK ) then
begin
cs_log('expected MSG_CLIENT_2_SERVER_LOGIN_ACK ( mod 02X), received mod 02X',
MSG_CLIENT_2_SERVER_LOGIN_ACK, login_answer);
network_tcp_connection_close(handle);
result:= -3;
end;
// 4. Send MSG_CARD_DATE_REQ
//
key := des_login_key_get(reader[ridx].ncd_key, passwdcrypt, strlen((Char )passwdcrypt));
network_cmd_no_data_send(handle, and reader[ridx].ncd_msgid, MSG_CARD_DATA_REQ,
key, COMMTYPE_CLIENT);
bytes_received = network_message_receive(handle, and reader[ridx].ncd_msgid, buf,
key, COMMTYPE_CLIENT);
if( bytes_received < 16 or buf[2] <> MSG_CARD_DATA ) then begin
cs_log('expected MSG_CARD_DATA ( mod 02X), received mod 02X',
MSG_CARD_DATA, buf[2]);
network_tcp_connection_close(handle);
result:= -4;
end;
// 5. Parse CAID and PROVID(s)
//
reader[ridx].caid[0] := (ushort(((buf[4+2] shl
or buf[5+2]);
memcpy( and reader[ridx].hexserial, buf+6+2,
;
cs_log('Newcamd Server: mod s: mod d - UserID: mod i', reader[ridx].device, reader[ridx].r_port, buf[3+2]);
cs_log('CAID: mod 04X - UA: mod 02X mod 02X mod 02X mod 02X mod 02X mod 02X mod 02X mod 02X - Provider # mod reader: array[0..ridx-1] of i',.caid[0], reader[ridx].hexserial[0], reader[ridx].hexserial[1], reader[ridx].hexserial[2], reader[ridx].hexserial[3], reader[ridx].hexserial[4], reader[ridx].hexserial[5], reader[ridx].hexserial[6], reader[ridx].hexserial[7], buf[14+2]);
reader[ridx].nprov := buf[14+2];
FillChar(reader[ridx].prid, $ff, SizeOf(reader[ridx].prid));
for (i:=0; i < reader[ridx].nprov; i++) begin
reader[ridx].availkeys
[0] := 1;
reader[ridx].prid[0] := buf[15+2+11*i];
reader[ridx].prid[1] := buf[16+2+11*i];
reader[ridx].prid[2] := buf[17+2+11*i];
memcpy( reader: array[0..ridx-1] of and.sa, buf+22+2+11*i, 4); // the 4 first bytes are not read
cs_log('Provider ID: mod 02X mod 02X mod 02X - SA: mod 02X mod 02X mod 02X mod reader: array[0..ridx-1] of 02X',.prid[1], reader[ridx].prid[2], reader[ridx].prid[3], reader[ridx].sa[0], reader[ridx].sa[1], reader[ridx].sa[2], reader[ridx].sa[3]);
end;
memcpy(reader[ridx].ncd_skey, key, 16);
// 6. Set connected info
//
reader[ridx].tcp_connected:=1;
reader[ridx].last_g := reader[ridx].last_s = time((time_t )0);
// cs_log("last_s=%d, last_g=%d", reader[ridx].last_s, reader[ridx].last_g);
// !!! Only after connect() on client[cs_idx].udp_fd (Linux)
pfd:=client[cs_idx].udp_fd;
result:= 0;
end;
integer newcamd_connect()
begin
if ( not reader[ridx].tcp_connected and connect_newcamd_server() < 0 ) then result:= 0;
if ( not client[cs_idx].udp_fd) then result:= 0;
result:= 1;
end;
integer newcamd_send(uchar *buf, integer ml, ushort sid)
begin
if( not newcamd_connect() ) result:= (-1) then ;
//cs_ddump(buf, ml, "send %d bytes to %s", ml, remote_txt());
result:=(network_message_send(client[cs_idx].udp_fd, and reader[ridx].ncd_msgid,
buf, ml, reader[ridx].ncd_skey, COMMTYPE_CLIENT, sid));
end;
integer newcamd_recv(uchar *buf, integer l)
begin
integer rc, rs;
if (is_server) then
rs=network_message_receive(client[cs_idx].udp_fd,
and client[cs_idx].ncd_msgid, buf,
client[cs_idx].ncd_skey, COMMTYPE_SERVER);
else
begin
if ( not client[cs_idx].udp_fd) result:= (-1) then ;
rs=network_message_receive(client[cs_idx].udp_fd,
and reader[ridx].ncd_msgid,buf,
reader[ridx].ncd_skey, COMMTYPE_CLIENT);
end;
if (rs<5) rc:=(-1) then ;
else rc:=rs;
cs_ddump(buf, rs, 'received mod d bytes from mod s', rs, remote_txt());
client[cs_idx].last := time((time_t ) 0);
if( rc = -1 ) then
if (rs > 0) then
cs_log('packet to small ( mod d bytes)', rs);
else
cs_log('Connection closed to mod s', remote_txt());
result:=(rc);
end;
WORD seed;
uchar fast_rnd()
begin
WORD offset := 12923;
WORD multiplier := 4079;
seed := seed * multiplier + offset;
result:= (uchar((seed mod $FF);
end;
FILTER mk_user_au_ftab(integer au)
begin
integer i,j,found;
FILTER filt;
FILTER *pufilt;
filt.caid := reader[au].caid[0];
if (filt.caid := 0) then filt.caid = client[cs_idx].ftab.filts[0].caid;
filt.nprids := 0;
FillChar( and filt.prids, 0, SizeOf(filt.prids));
pufilt := and client[cs_idx].ftab.filts[0];
for( i:=0; i filt.prids[filt.nprids++] := b2i(3, and reader[au].prid[1]);
for( i:=0; i begin
for( j:=found=0; ( not found) and (j if (pufilt^.prids := filt.prids[j]) then found=1;
if( not found ) then
filt.prids[filt.nprids++] := pufilt^.prids;
end;
result:= filt;
end;
FILTER mk_user_ftab()
begin
FILTER *psfilt := 0;
FILTER filt;
integer port_idx,i,j,k,c;
filt.caid := 0;
filt.nprids := 0;
FillChar( and filt.prids, 0, SizeOf(filt.prids));
port_idx := client[cs_idx].port_idx;
psfilt := and cfg^.ncd_ptab.ports[port_idx].ftab.filts[0];
// 1. CAID
// search server CAID in client CAID
for( c:=i=0; i begin
integer ctab_caid;
ctab_caid := client[cs_idx].ctab.caid and client[cs_idx].ctab.mask;
if( ctab_caid ) then c:= mod + 1;
if( psfilt^.caid = ctab_caid ) then
begin
filt.caid:=ctab_caid;
break;
end;
end;
if( c and not filt.caid ) then
begin
cs_log('no valid CAID found in CAID for user ' mod s'', client[cs_idx].usr);
result:= filt;
end;
// search CAID in client IDENT
cs_debug('client[ mod d]. mod s nfilts= mod d, filt.caid= mod 04X', cs_idx,
client[cs_idx].usr, client[cs_idx].ftab.nfilts, filt.caid);
if( not filt.caid and client[cs_idx].ftab.nfilts ) then
begin
integer fcaids;
for( i:=fcaids=0; i begin
ushort ucaid:=client[cs_idx].ftab.filts.caid;
if( ucaid ) then fcaids:= mod + 1;
if( ucaid and psfilt^.caid = ucaid ) then
begin
filt.caid := ucaid;
break;
end;
end;
if( fcaids = client[cs_idx].ftab.nfilts and not filt.caid ) then
begin
cs_log('no valid CAID found in IDENT for user ' mod s'', client[cs_idx].usr);
//cs_disconnect_client();
result:= filt;
end;
end;
// empty client CAID - use server CAID
if( not filt.caid ) then filt.caid:=psfilt^.caid;
// 2. PROVID
if( not client[cs_idx].ftab.nfilts ) then
begin
integer r,f, add;
for (i:=0; i // use server PROVID(s) (and only those which are in user's groups)
add := 0;
for (r:=0; not add and r if (reader[r].grp and client[cs_idx].grp) then begin
if ( not reader[r].ftab.nfilts) then begin
if (reader[r].typ and R_IS_NETWORK) then add := 1;
for (j:=0; not add and j if (b2i(3, and reader[r].prid[j][1]) := psfilt^.prids) then add = 1;
end; else begin
for (j:=0; not add and j ulong rcaid := reader[r].ftab.filts[j].caid;
if ( not rcaid or rcaid = filt.caid) then begin
for (k:=0; not add and k if (reader[r].ftab.filts[j].prids[k] := psfilt^.prids) then add = 1;
end;
end;
end;
end;
end;
if (add) then filt.prids[filt.nprids++] := psfilt^.prids;
end;
result:= filt;
end;
// search in client IDENT
for( j:=0; j begin
ulong ucaid := client[cs_idx].ftab.filts[j].caid;
cs_debug('client caid # mod d: mod 04X', j, ucaid);
if( not ucaid or ucaid = filt.caid ) then
begin
for (i:=0; i begin
cs_debug('search server provid # mod d: mod 06X', i, psfilt^.prids);
if( client[cs_idx].ftab.filts[j].nprids ) then
begin
for( k:=0; k if (client[cs_idx].ftab.filts[j].prids[k] = psfilt^.prids) then
filt.prids[filt.nprids++]:=client[cs_idx].ftab.filts[j].prids[k];
end; else begin
filt.prids[filt.nprids++] := psfilt^.prids;
// allow server PROVID(s) if no PROVID(s) specified in IDENT
end;
end;
end;
end;
if( not filt.nprids ) then
begin
cs_log('no valid PROVID(s) found in CAID for user ' mod s'', client[cs_idx].usr);
//cs_disconnect_client();
end;
result:= filt;
end;
integer newcamd_auth_client(in_addr_t ip)
begin
integer i, ok := 0;
uchar *usr:=0, *pwd=0;
struct s_auth *account;
buf: array[0..14-1] of uchar;
uchar *key:=0;
uint8 *passwdcrypt := 0;
integer au;
// make random 14 bytes
seed := (function) time((time_t)0): WORD;
for( i:=0; i<14; i++ ) buf=fast_rnd();
// send init sequence
send(client[cs_idx].udp_fd, buf, 14, 0);
key := des_login_key_get(buf, cfg^.ncd_key, 14);
memcpy(client[cs_idx].ncd_skey, key, 16);
client[cs_idx].ncd_msgid := 0;
i:=process_input(mbuf, SizeOf(mbuf), cfg^.cmaxidle);
if ( i>0 ) then
begin
if( mbuf[2] <> MSG_CLIENT_2_SERVER_LOGIN ) then
begin
cs_debug('expected MSG_CLIENT_2_SERVER_LOGIN ( mod 02X), received mod 02X',
MSG_CLIENT_2_SERVER_LOGIN, mbuf[2]);
if(req) then
begin
free(req);
req:=0;
end;
cs_exit(0);
end;
usr:=mbuf+5;
pwd:=usr+strlen((Char )usr)+1;
//cs_debug("usr=%s,pwd=%s", usr, pwd);
end;
else
begin
cs_debug('bad client login request');
if(req) then
begin
free(req);
req:=0;
end;
cs_exit(0);
end;
for (ok:=0, account=cfg^.account; (usr) and (account) and ( not ok); account=account^.next)
begin
cs_debug('account^.usr:= mod s', account^.usr);
if (StrComp((Char )usr, account^.usr) = 0) then
begin
passwdcrypt := (uint8*)__md5_crypt(account->pwd, "$1$abcdefgh$");
cs_debug('account^.pwd:= mod s', passwdcrypt);
if (StrComp((Char )pwd, ( Char )passwdcrypt) = 0) then
begin
client[cs_idx].crypted:=1;
cs_auth_client(account, 0);
cs_log('user mod s authenticated successfully (using client mod 02X mod 02X)', mbuf: array[0..0-1] of usr,, mbuf[1]);
ok := 1;
break;
end;
else
begin
cs_log('user mod s is providing a wrong password (using client mod 02X mod 02X)', mbuf: array[0..0-1] of usr,, mbuf[1]);
end;
end;
end;
if ( not ok and not account) then
begin
cs_log('user mod s is trying to connect but doesnt exist not (using client mod 02X mod 02X)', mbuf: array[0..0-1] of usr,, mbuf[1]);
usr := 0;
end;
if (ok) then
begin
au := client[cs_idx].au;
if (au <> -1) then
begin
if (cfg^.ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid <> reader[au].caid[0] then
and cfg^.ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid <> reader[au].ftab.filts[0].caid)
begin
cs_log('AU wont be used on this port ^. disable AU');
au := -1;
end;
else if (reader[au].card_system <= 0 and not (reader[au].typ and R_IS_CASCADING)) then
begin
// Init for AU enabled card not finished, reject Client
ok:=0;
au := -2; // Flag zur Logausgabe
end;
else
begin
cs_log('AU mod d for user mod s',au,usr);
end;
end;
else
begin
cs_log('AU disabled for user mod s',usr);
end;
end;
network_cmd_no_data_send(client[cs_idx].udp_fd, and client[cs_idx].ncd_msgid,
(ok)?MSG_CLIENT_2_SERVER_LOGIN_ACK:MSG_CLIENT_2_SERVER_LOGIN_NAK,
client[cs_idx].ncd_skey, COMMTYPE_SERVER);
// we need to add a test to make sure all card reader are ready before allowing more interaction with the user.
// cfg->ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid old the CAID for this port
// we need to check all ready for a match and check if they are ready
// if they arent ready, disconnect the user.
// it will reconnect in a few second.
if (ok) then
begin
FILTER pufilt_noau := ( 0 );
FILTER *pufilt := 0;
key := des_login_key_get(cfg^.ncd_key, passwdcrypt, strlen((Char )passwdcrypt));
memcpy(client[cs_idx].ncd_skey, key, 16);
i:=process_input(mbuf, SizeOf(mbuf), cfg^.cmaxidle);
if( i>0 ) then
begin
integer j,len:=15;
if( mbuf[2] <> MSG_CARD_DATA_REQ) then
begin
cs_debug('expected MSG_CARD_DATA_REQ ( mod 02X), received mod 02X',
MSG_CARD_DATA_REQ, mbuf[2]);
if(req) then
begin
free(req); req:=0;
end;
cs_exit(0);
end;
client[cs_idx].ftab.filts[0] := mk_user_ftab();
pufilt := and client[cs_idx].ftab.filts[0];
if (au <> -1) then
begin
Byte equal := 1;
// remember user filter
memcpy( and pufilt_noau, pufilt, SizeOf(FILTER));
client[cs_idx].ftab.filts[0] := mk_user_au_ftab(au);
pufilt := and client[cs_idx].ftab.filts[0];
// check if user filter CAID and PROVID is the same as CAID and PROVID of the AU reader
if ((pufilt^.caid <> pufilt_noau.caid)) then
begin
// cs_log("CAID server: %04X, CAID card: %04X, not equal, AU disabled",pufilt_noau.caid,pufilt->caid);
// equal = 0;
end;
for( j:=0; equal and j begin
if (pufilt^.prids[j] <> pufilt_noau.prids[j]) then
begin
// cs_log("PROVID%d server: %04X, PROVID%d card: %04X, not equal, AU disabled",j,pufilt_noau.prids[j],j,pufilt->prids[j]);
//weird// equal = 0;
end;
end;
if ( not equal) then
begin
// Not equal -> AU must set to disabled -> set back to user filter
memcpy(pufilt, and pufilt_noau, SizeOf(FILTER));
au := -1;
end;
end;
client[cs_idx].ftab.nfilts := 1;
mbuf[0] := MSG_CARD_DATA;
mbuf[1] := $00;
mbuf[2] := $00;
// AU always set to true because some clients cannot handle "non-AU"
// For security reason don't send the real hexserial (see below)
// if a non-AU-client sends an EMM-request it will be thrown away
// (see function "newcamd_process_emm")
//mbuf[3] = 1;
if( au <> -1 ) then
mbuf[3] := 1;
else
mbuf[3] := cs_idx+10; // Unique user number
mbuf[4] := (uchar((pufilt^.caid shr ;
mbuf[5] := (uchar((pufilt^.caid);
mbuf[6] := $00;
mbuf[7] := $00;
if (au <> -1) then
begin
if (((pufilt^.caid shr = $17) or ((pufilt^.caid shr = $06)) // Betacrypt or 1rd3t0
begin
// only 4 Bytes Hexserial for newcamd clients (Hex Base + Hex Serial)
// first 2 Byte always 00
mbuf[8]:=$00; //serial only 4 bytes
mbuf[9]:=$00; //serial only 4 bytes
// 1 Byte Hex Base (see reader-1rd3t0.c how this is stored in "reader[au].hexserial")
mbuf[10]:=reader[au].hexserial[3];
// 3 Bytes Hex Serial (see reader-1rd3t0.c how this is stored in "reader[au].hexserial")
mbuf[11]:=reader[au].hexserial[0];
mbuf[12]:=reader[au].hexserial[1];
mbuf[13]:=reader[au].hexserial[2];
end;
else if (((pufilt^.caid shr = $05) or ((pufilt^.caid shr = $0D))
begin
mbuf[8] := $00;
mbuf[9] := reader[au].hexserial[0];
mbuf[10] := reader[au].hexserial[1];
mbuf[11] := reader[au].hexserial[2];
mbuf[12] := reader[au].hexserial[3];
mbuf[13] := reader[au].hexserial[4];
end;
else
begin
mbuf[8] := reader[au].hexserial[0];
mbuf[9] := reader[au].hexserial[1];
mbuf[10] := reader[au].hexserial[2];
mbuf[11] := reader[au].hexserial[3];
mbuf[12] := reader[au].hexserial[4];
mbuf[13] := reader[au].hexserial[5];
end;
end;
else
begin
client[cs_idx].au := -1;
mbuf[8] := $00;
mbuf[9] := $00;
mbuf[10] := $00;
mbuf[11] := $00;
mbuf[12] := $00;
mbuf[13] := $00;
// send "faked" Hexserial to client
(*
if (((pufilt^.caid >= $1700) and (pufilt^.caid <= $1799)) or // Betacrypt
((pufilt^.caid >= $0600) and (pufilt^.caid <= $0699))) // 1rd3t0
begin
mbuf[6] := $00;
mbuf[7] := $00;
mbuf[8] := $00;
mbuf[9] := $00;
mbuf[10] := fast_rnd();
mbuf[11] := fast_rnd();
mbuf[12] := fast_rnd();
mbuf[13] := fast_rnd();
end;
else
begin
mbuf[6] := fast_rnd();
mbuf[7] := fast_rnd();
mbuf[8] := fast_rnd();
mbuf[9] := fast_rnd();
mbuf[10] := fast_rnd();
mbuf[11] := fast_rnd();
mbuf[12] := fast_rnd();
mbuf[13] := fast_rnd();
end;
*)
end;
mbuf[14] := pufilt^.nprids;
for( j:=0; j begin
if ((pufilt^.caid >= $0600) and (pufilt^.caid <= $0699)) // 1rd3t0
begin
mbuf[15+11*j] := 0;
mbuf[16+11*j] := 0;
mbuf[17+11*j] := j;
end;
else
begin
mbuf[15+11*j] := (uchar((pufilt^.prids[j] shr 16);
mbuf[16+11*j] := (uchar((pufilt^.prids[j] shr ;
mbuf[17+11*j] := (uchar((pufilt^.prids[j]);
end;
mbuf[18+11*j] := $00;
mbuf[19+11*j] := $00;
mbuf[20+11*j] := $00;
mbuf[21+11*j] := $00;
if( au <> -1 ) then
begin // check if user provid from IDENT exists on card
integer k, found;
ulong rprid;
found:=0;
if( pufilt^.caid = reader[au].caid[0] ) then
begin
for( k:=0; (k begin
rprid:=b2i(3, and reader[au].prid[k][1]);
if( rprid = pufilt^.prids[j] ) then
begin
if ((pufilt^.caid >= $0600) and (pufilt^.caid <= $0699)) // 1rd3t0
begin
mbuf[22+11*j] := reader[au].prid[k][0];
mbuf[23+11*j] := reader[au].prid[k][1];
mbuf[24+11*j] := reader[au].prid[k][2];
mbuf[25+11*j] := reader[au].prid[k][3];
end;
else
begin
mbuf[22+11*j] := reader[au].sa[k][0];
mbuf[23+11*j] := reader[au].sa[k][1];
mbuf[24+11*j] := reader[au].sa[k][2];
mbuf[25+11*j] := reader[au].sa[k][3];
end;
found:=1;
break;
end;
end;
end;
if( not found ) then
begin
mbuf[22+11*j] := $00;
mbuf[23+11*j] := $00;
mbuf[24+11*j] := $00;
mbuf[25+11*j] := $00;
end;
end;
else
begin
if ((pufilt^.caid >= $0600) and (pufilt^.caid <= $0699)) // 1rd3t0
begin
mbuf[22+11*j] := $00;
mbuf[23+11*j] := (uchar((pufilt^.prids[j] shr 16);
mbuf[24+11*j] := (uchar((pufilt^.prids[j] shr ;
mbuf[25+11*j] := (uchar((pufilt^.prids[j]);
end;
else
begin
mbuf[22+11*j] := $00;
mbuf[23+11*j] := $00;
mbuf[24+11*j] := $00;
mbuf[25+11*j] := $00;
end;
end;
len+:=11;
end;
if( network_message_send(client[cs_idx].udp_fd, and client[cs_idx].ncd_msgid, mbuf, len, key, COMMTYPE_SERVER, 0 ) <0 ) then
begin
if(req) then
begin
free(req);
req:=0;
end;
cs_exit(0);
end;
end;
end;
else
begin
if (au = -2) then
cs_auth_client(0, 'Init for AU enabled card not finished');
else
cs_auth_client(0, usr ? 'login failure' : 'no such user');
if(req) then
begin
free(req);
req:=0;
end;
cs_exit(0);
end;
end;
procedure newcamd_send_dcw(var er: ECM_REQUEST)
begin
integer len;
ushort cl_msgid;
if ( not client[cs_idx].udp_fd) then begin
cs_debug('ncd_send_dcw: error: client[cs_idx].udp_fd:= mod d', client[cs_idx].udp_fd);
Exit;
end;
memcpy( and cl_msgid, req+(er^.cpti*REQ_SIZE), 2); // get client ncd_msgid + 0x8x
mbuf[0] := er^.ecm[0];
if( client[cs_idx].ftab.filts[0].nprids = 0 or er^.rc>3 (*not found*)) then
begin
len:=3;
mbuf[1] := mbuf[2] = $00;
end;
else
begin
len := 19;
mbuf[1] := mbuf[2] = $10;
memcpy(mbuf+3, er^.cw, 16);
end;
cs_debug('ncd_send_dcw: er^.cpti:= mod d, cl_msgid= mod d, mod 02X', er^.cpti, cl_msgid, mbuf[0]);
network_message_send(client[cs_idx].udp_fd, and cl_msgid, mbuf, len,
client[cs_idx].ncd_skey, COMMTYPE_SERVER, 0);
end;
procedure newcamd_process_ecm(var buf: uchar; l: integer)
begin
integer pi;
ECM_REQUEST *er;
if ( not (er=get_ecmtask())) then begin
Exit;
end;
// save client ncd_msgid
memcpy(req+(er^.cpti*REQ_SIZE), and client[cs_idx].ncd_msgid, 2);
cs_debug('ncd_process_ecm: er^.cpti= mod d, cl_msgid= mod d, mod 02X", er^.cpti,
client[cs_idx].ncd_msgid, buf[2]);
er^.l:=buf[4]+3;
er^.srvid := (buf[0] shl or buf[1];
er^.caid := 0;
pi := client[cs_idx].port_idx;
if( cfg^.ncd_ptab.nports and cfg^.ncd_ptab.nports >= pi ) then
er^.caid:=cfg^.ncd_ptab.ports[pi].ftab.filts[0].caid;
memcpy(er^.ecm, buf+2, er^.l);
get_cw(er);
end;
procedure newcamd_process_emm(var buf: uchar; l: integer)
begin
integer au, ok:=1;
ushort caid;
FillChar( and epg, 0, SizeOf(epg));
au:=client[cs_idx].au;
// if client is not allowed to do AU just send back the OK-answer to
// the client and do nothing else with the received data
if ((au>=0) and (au<=CS_MAXREADER)) then
begin
epg.l:=buf[2]+3;
caid := client[cs_idx].ftab.filts[0].caid;
epg.caid[0] := (uchar((caid shr ;
epg.caid[1] := (uchar((caid);
(* if (caid == 0x0500)
begin
ushort emm_head;
emm_head := (buf[0] shl or buf[1];
case( emm_head ) of
begin
$8e70: // EMM-S
memcpy(epg.hexserial+1, buf+3, 4);
epg.hexserial[4]:=reader[au].hexserial[4];
break;
$8870: // EMM-U
$8c70: // confidential ?
default:
cs_log("unsupported emm cType: mod 04X", emm_head);
ok:=0;
end;
if( not ok ) cs_log("only