source: trunk/module-newcamd.c@ 1741

Last change on this file since 1741 was 1741, checked in by merek, 13 years ago

Ident fixes for newcamd and cccam, thanks to equeorto

File size: 36.1 KB
Line 
1#include "globals.h"
2
3#define CWS_NETMSGSIZE 272
4
5#define CWS_FIRSTCMDNO 0xe0
6typedef enum
7{
8 MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
9 MSG_CLIENT_2_SERVER_LOGIN_ACK,
10 MSG_CLIENT_2_SERVER_LOGIN_NAK,
11 MSG_CARD_DATA_REQ,
12 MSG_CARD_DATA,
13 MSG_SERVER_2_CLIENT_NAME,
14 MSG_SERVER_2_CLIENT_NAME_ACK,
15 MSG_SERVER_2_CLIENT_NAME_NAK,
16 MSG_SERVER_2_CLIENT_LOGIN,
17 MSG_SERVER_2_CLIENT_LOGIN_ACK,
18 MSG_SERVER_2_CLIENT_LOGIN_NAK,
19 MSG_ADMIN,
20 MSG_ADMIN_ACK,
21 MSG_ADMIN_LOGIN,
22 MSG_ADMIN_LOGIN_ACK,
23 MSG_ADMIN_LOGIN_NAK,
24 MSG_ADMIN_COMMAND,
25 MSG_ADMIN_COMMAND_ACK,
26 MSG_ADMIN_COMMAND_NAK,
27 MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d
28} net_msg_type_t;
29
30typedef enum
31{
32 COMMTYPE_CLIENT,
33 COMMTYPE_SERVER
34} comm_type_t;
35
36#define REQ_SIZE 2
37static uchar *req=0;
38static int ncd_proto=NCD_AUTO;
39
40static int network_message_send(int handle, uint16 *netMsgId, uint8 *buffer,
41 int len, uint8 *deskey, comm_type_t commType,
42 ushort sid)
43{
44 uint8 netbuf[CWS_NETMSGSIZE];
45 int head_size;
46 head_size = (ncd_proto==NCD_524)?8:12;
47
48 if (len < 3 || len + head_size > CWS_NETMSGSIZE || handle < 0)
49 return -1;
50 buffer[1] = (buffer[1] & 0xf0) | (((len - 3) >> 8) & 0x0f);
51 buffer[2] = (len - 3) & 0xff;
52 memcpy(netbuf+head_size, buffer, len);
53 len += head_size;
54 if (netMsgId) {
55 switch(commType)
56 {
57 case COMMTYPE_CLIENT:
58 (*netMsgId)++;
59 break;
60 case COMMTYPE_SERVER:
61 if( *netMsgId == 0xFFFE ) *netMsgId = 0; // ??? 0xFFFF ?
62 break;
63 }
64 netbuf[2] = (*netMsgId) >> 8;
65 netbuf[3] = (*netMsgId) & 0xff;
66 }
67 else
68 netbuf[2] = netbuf[3] = 0;
69 memset(netbuf+4, 0, (ncd_proto==NCD_524)?4:8);
70 if( sid ) {
71 netbuf[(ncd_proto==NCD_524)?6:4] = (uchar)(sid>>8); //sid
72 netbuf[(ncd_proto==NCD_524)?7:5] = (uchar)(sid);
73 }
74 netbuf[0] = (len - 2) >> 8;
75 netbuf[1] = (len - 2) & 0xff;
76 cs_ddump(netbuf, len, "send %d bytes to %s", len, remote_txt());
77 if ((len = des_encrypt(netbuf, len, deskey)) < 0)
78 return -1;
79 netbuf[0] = (len - 2) >> 8;
80 netbuf[1] = (len - 2) & 0xff;
81 return send(handle, netbuf, len, 0);
82}
83
84static int network_message_receive(int handle, uint16 *netMsgId, uint8 *buffer,
85 uint8 *deskey, comm_type_t commType)
86{
87 int len, ncd_off, msgid;
88 uint8 netbuf[CWS_NETMSGSIZE];
89 int returnLen;
90
91 if (!buffer || handle < 0)
92 return -1;
93 len = recv(handle, netbuf, 2, 0);
94 cs_debug("nmr(): len=%d, errno=%d", len, (len==-1)?errno:0);
95 if (!len) {
96 cs_debug("nmr: 1 return 0");
97 network_tcp_connection_close(handle);
98 return 0;
99 }
100 if (len != 2) {
101 cs_debug("nmr: len!=2");
102 network_tcp_connection_close(handle);
103 return -1;
104 }
105 if (((netbuf[0] << 8) | netbuf[1]) > CWS_NETMSGSIZE - 2) {
106 cs_debug("nmr: 1 return -1");
107 return -1;
108 }
109
110 len = recv(handle, netbuf+2, (netbuf[0] << 8) | netbuf[1], 0);
111 if (!len) {
112 cs_debug("nmr: 2 return 0");
113 return 0;
114 }
115 if (len != ((netbuf[0] << 8) | netbuf[1])) {
116 cs_debug("nmr: 2 return -1");
117 return -1;
118 }
119 len += 2;
120 if ((len = des_decrypt(netbuf, len, deskey)) < 11 ) { // 15(newcamd525) or 11 ???
121 cs_debug("nmr: can't decrypt, invalid des key?");
122 cs_sleepms(2000);
123 return -1;
124 }
125 //cs_ddump(netbuf, len, "nmr: decrypted data, len=%d", len);
126 msgid = (netbuf[2] << 8) | netbuf[3];
127
128 if( ncd_proto==NCD_AUTO ) {
129 // auto detect
130 int l5 = (((netbuf[13] & 0x0f) << 8) | netbuf[14]) + 3;
131 int l4 = (((netbuf[9] & 0x0f) << 8) | netbuf[10]) + 3;
132
133 if( (l5<=len-12) && ((netbuf[12]&0xF0)==0xE0 || (netbuf[12]&0xF0)==0x80) )
134 ncd_proto = NCD_525;
135 else if( (l4<=len-8) && ((netbuf[8]&0xF0)==0xE0 || (netbuf[9]&0xF0)==0x80) )
136 ncd_proto = NCD_524;
137 else {
138 cs_debug("nmr: 4 return -1");
139 return -1;
140 }
141
142 cs_debug("nmr: autodetect: newcamd52%d used", (ncd_proto==NCD_525)?5:4);
143 }
144
145 ncd_off=(ncd_proto==NCD_525)?4:0;
146
147 returnLen = (((netbuf[9+ncd_off] & 0x0f) << 8) | netbuf[10+ncd_off]) + 3;
148 if ( returnLen > (len-(8+ncd_off)) ) {
149 cs_debug("nmr: 4 return -1");
150 return -1;
151 }
152
153// cs_ddump(netbuf, len, "nmr: decrypted data");
154 if (netMsgId)
155 {
156 switch (commType)
157 {
158 case COMMTYPE_SERVER:
159 *netMsgId = msgid;
160 break;
161
162 case COMMTYPE_CLIENT:
163 //if (*netMsgId != ((netbuf[2] << 8) | netbuf[3])) {
164 cs_debug("nmr: netMsgId=%d, from server=%d, ", *netMsgId, msgid );
165 //return -2;
166 //}
167 break;
168
169 default:
170 cs_debug("nmr: 5 return -1");
171 return -1;
172 break;
173 }
174 }
175 switch(commType)
176 {
177 case COMMTYPE_SERVER:
178 buffer[0]=(ncd_proto==NCD_525)?netbuf[4]:netbuf[6]; // sid
179 buffer[1]=(ncd_proto==NCD_525)?netbuf[5]:netbuf[7];
180 break;
181 case COMMTYPE_CLIENT:
182 buffer[0]=netbuf[2]; // msgid
183 buffer[1]=netbuf[3];
184 break;
185 }
186
187 memcpy(buffer+2, netbuf+(8+ncd_off), returnLen);
188 return returnLen+2;
189}
190
191static void network_cmd_no_data_send(int handle, uint16 *netMsgId,
192 net_msg_type_t cmd, uint8 *deskey,
193 comm_type_t commType)
194{
195 uint8 buffer[CWS_NETMSGSIZE];
196
197 buffer[0] = cmd; buffer[1] = 0;
198 network_message_send(handle, netMsgId, buffer, 3, deskey, commType, 0);
199}
200
201static int network_cmd_no_data_receive(int handle, uint16 *netMsgId,
202 uint8 *deskey, comm_type_t commType)
203{
204 uint8 buffer[CWS_NETMSGSIZE];
205
206 if (network_message_receive(handle, netMsgId, buffer, deskey, commType) != 3+2)
207 return -1;
208 return buffer[2];
209}
210
211void newcamd_reply_ka()
212{
213 if(!client[cs_idx].udp_fd)
214 {
215 cs_debug("invalid client fd=%d", client[cs_idx].udp_fd);
216 return;
217 }
218
219 cs_debug("send keepalive to client fd=%d", client[cs_idx].udp_fd);
220
221 network_cmd_no_data_send(client[cs_idx].udp_fd, &client[cs_idx].ncd_msgid,
222 MSG_KEEPALIVE, client[cs_idx].ncd_skey,COMMTYPE_SERVER);
223}
224
225static int connect_newcamd_server()
226{
227 int i;
228 uint8 buf[CWS_NETMSGSIZE];
229 uint8 keymod[14];
230 uint8 *key;
231 int handle=0;
232
233 uint32 index;
234 uint8 *passwdcrypt;
235 uint8 login_answer;
236 int bytes_received;
237
238 if(reader[ridx].device[0] == 0 || reader[ridx].r_pwd[0] == 0 ||
239 reader[ridx].r_usr[0] == 0 || reader[ridx].r_port == 0)
240 return -5;
241
242 // 1. Connect
243 //
244 handle = network_tcp_connection_open();
245 if(handle < 0) return -1;
246
247 // 2. Get init sequence
248 //
249 reader[ridx].ncd_msgid = 0;
250 if( read(handle, keymod, sizeof(keymod)) != sizeof(keymod)) {
251 cs_log("server does not return 14 bytes");
252 network_tcp_connection_close(handle);
253 return -2;
254 }
255 cs_ddump(keymod, 14, "server init sequence:");
256 key = des_login_key_get(keymod, reader[ridx].ncd_key, 14);
257
258 // 3. Send login info
259 //
260 index = 3;
261 buf[0] = MSG_CLIENT_2_SERVER_LOGIN;
262 buf[1] = 0;
263 strcpy((char *)buf+index, reader[ridx].r_usr);
264 passwdcrypt = (uint8*)__md5_crypt(reader[ridx].r_pwd, "$1$abcdefgh$");
265 index += strlen(reader[ridx].r_usr)+1;
266 strcpy((char *)buf+index, (const char *)passwdcrypt);
267
268 //cs_debug("login to server %s:%d user=%s, pwd=%s, len=%d", reader[ridx].device,
269 // reader[ridx].r_port, reader[ridx].r_usr, reader[ridx].r_pwd,
270 // index+strlen(passwdcrypt)+1);
271 network_message_send(handle, 0, buf, index+strlen((char *)passwdcrypt)+1, key,
272 COMMTYPE_CLIENT, 0x8888);
273
274 // 3.1 Get login answer
275 //
276 login_answer=network_cmd_no_data_receive(handle, &reader[ridx].ncd_msgid,
277 key, COMMTYPE_CLIENT);
278 if( login_answer == MSG_CLIENT_2_SERVER_LOGIN_NAK )
279 {
280 cs_log("login failed for user '%s'", reader[ridx].r_usr);
281 network_tcp_connection_close(handle);
282 return -3;
283 }
284 if( login_answer != MSG_CLIENT_2_SERVER_LOGIN_ACK )
285 {
286 cs_log("expected MSG_CLIENT_2_SERVER_LOGIN_ACK (%02X), received %02X",
287 MSG_CLIENT_2_SERVER_LOGIN_ACK, login_answer);
288 network_tcp_connection_close(handle);
289 return -3;
290 }
291
292 // 4. Send MSG_CARD_DATE_REQ
293 //
294 key = des_login_key_get(reader[ridx].ncd_key, passwdcrypt, strlen((char *)passwdcrypt));
295
296 network_cmd_no_data_send(handle, &reader[ridx].ncd_msgid, MSG_CARD_DATA_REQ,
297 key, COMMTYPE_CLIENT);
298 bytes_received = network_message_receive(handle, &reader[ridx].ncd_msgid, buf,
299 key, COMMTYPE_CLIENT);
300 if( bytes_received < 16 || buf[2] != MSG_CARD_DATA ) {
301 cs_log("expected MSG_CARD_DATA (%02X), received %02X",
302 MSG_CARD_DATA, buf[2]);
303 network_tcp_connection_close(handle);
304 return -4;
305 }
306
307 // 5. Parse CAID and PROVID(s)
308 //
309 reader[ridx].caid[0] = (ushort)((buf[4+2]<<8) | buf[5+2]);
310 memcpy(&reader[ridx].hexserial, buf+6+2, 8);
311 cs_log("Newcamd Server: %s:%d - UserID: %i", reader[ridx].device, reader[ridx].r_port, buf[3+2]);
312 cs_log("CAID: %04X - UA: %02X%02X%02X%02X%02X%02X%02X%02X - Provider # %i", reader[ridx].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]);
313 reader[ridx].nprov = buf[14+2];
314 memset(reader[ridx].prid, 0xff, sizeof(reader[ridx].prid));
315 for (i=0; i < reader[ridx].nprov; i++) {
316 reader[ridx].availkeys[i][0] = 1;
317 reader[ridx].prid[i][0] = buf[15+2+11*i];
318 reader[ridx].prid[i][1] = buf[16+2+11*i];
319 reader[ridx].prid[i][2] = buf[17+2+11*i];
320 memcpy(&reader[ridx].sa[i], buf+22+2+11*i, 4); // the 4 first bytes are not read
321 cs_log("Provider ID: %02X%02X%02X - SA: %02X%02X%02X%02X", reader[ridx].prid[i][0], reader[ridx].prid[i][1], reader[ridx].prid[i][2], reader[ridx].sa[i][0], reader[ridx].sa[i][1], reader[ridx].sa[i][2], reader[ridx].sa[i][3]);
322 }
323 memcpy(reader[ridx].ncd_skey, key, 16);
324
325 // 6. Set connected info
326 //
327 reader[ridx].tcp_connected=1;
328 reader[ridx].last_g = reader[ridx].last_s = time((time_t *)0);
329
330// cs_log("last_s=%d, last_g=%d", reader[ridx].last_s, reader[ridx].last_g);
331
332 // !!! Only after connect() on client[cs_idx].udp_fd (Linux)
333 pfd=client[cs_idx].udp_fd;
334
335 return 0;
336}
337
338static int newcamd_connect()
339{
340 if (!reader[ridx].tcp_connected && connect_newcamd_server() < 0 ) return 0;
341 if (!client[cs_idx].udp_fd) return 0;
342
343 return 1;
344}
345
346
347static int newcamd_send(uchar *buf, int ml, ushort sid)
348{
349 if( !newcamd_connect() ) return(-1);
350
351 //cs_ddump(buf, ml, "send %d bytes to %s", ml, remote_txt());
352 return(network_message_send(client[cs_idx].udp_fd, &reader[ridx].ncd_msgid,
353 buf, ml, reader[ridx].ncd_skey, COMMTYPE_CLIENT, sid));
354}
355
356static int newcamd_recv(uchar *buf)
357{
358 int rc, rs;
359
360 if (is_server)
361 {
362 rs=network_message_receive(client[cs_idx].udp_fd,
363 &client[cs_idx].ncd_msgid, buf,
364 client[cs_idx].ncd_skey, COMMTYPE_SERVER);
365 }
366 else
367 {
368 if (!client[cs_idx].udp_fd) return(-1);
369 rs=network_message_receive(client[cs_idx].udp_fd,
370 &reader[ridx].ncd_msgid,buf,
371 reader[ridx].ncd_skey, COMMTYPE_CLIENT);
372 }
373
374 if (rs<5) rc=(-1);
375 else rc=rs;
376
377 cs_ddump(buf, rs, "received %d bytes from %s", rs, remote_txt());
378 client[cs_idx].last = time((time_t *) 0);
379
380 if( rc==-1 )
381 {
382 if (rs > 0)
383 cs_log("packet to small (%d bytes)", rs);
384 else
385 cs_log("Connection closed to %s", remote_txt());
386 }
387 return(rc);
388}
389
390static unsigned int seed;
391static uchar fast_rnd()
392{
393 unsigned int offset = 12923;
394 unsigned int multiplier = 4079;
395
396 seed = seed * multiplier + offset;
397 return (uchar)(seed % 0xFF);
398}
399
400static FILTER mk_user_au_ftab(int au)
401{
402 int i,j,found;
403 FILTER filt;
404 FILTER *pufilt;
405
406 filt.caid = reader[au].caid[0];
407 if (filt.caid == 0) filt.caid = client[cs_idx].ftab.filts[0].caid;
408 filt.nprids = 0;
409 memset(&filt.prids, 0, sizeof(filt.prids));
410 pufilt = &client[cs_idx].ftab.filts[0];
411
412 for( i=0; i<reader[au].nprov; i++ )
413 filt.prids[filt.nprids++] = b2i(3, &reader[au].prid[i][1]);
414
415 for( i=0; i<pufilt->nprids; i++ )
416 {
417 for( j=found=0; (!found)&&(j<filt.nprids); j++ )
418 if (pufilt->prids[i] == filt.prids[j]) found=1;
419 if( !found )
420 filt.prids[filt.nprids++] = pufilt->prids[i];
421 }
422
423 return filt;
424}
425
426static FILTER mk_user_ftab()
427{
428 FILTER *psfilt = 0;
429 FILTER filt;
430 int port_idx,i,j,k,c;
431
432 filt.caid = 0;
433 filt.nprids = 0;
434 memset(&filt.prids, 0, sizeof(filt.prids));
435
436 port_idx = client[cs_idx].port_idx;
437 psfilt = &cfg->ncd_ptab.ports[port_idx].ftab.filts[0];
438
439 // 1. CAID
440 // search server CAID in client CAID
441 for( c=i=0; i<CS_MAXCAIDTAB; i++ )
442 {
443 int ctab_caid;
444 ctab_caid = client[cs_idx].ctab.caid[i]&client[cs_idx].ctab.mask[i];
445 if( ctab_caid ) c++;
446
447 if( psfilt->caid==ctab_caid )
448 {
449 filt.caid=ctab_caid;
450 break;
451 }
452 }
453 if( c && !filt.caid )
454 {
455 cs_log("no valid CAID found in CAID for user '%s'", client[cs_idx].usr);
456 return filt;
457 }
458
459 // search CAID in client IDENT
460 cs_debug("client[%d].%s nfilts=%d, filt.caid=%04X", cs_idx,
461 client[cs_idx].usr, client[cs_idx].ftab.nfilts, filt.caid);
462
463 if( !filt.caid && client[cs_idx].ftab.nfilts )
464 {
465 int fcaids;
466 for( i=fcaids=0; i<client[cs_idx].ftab.nfilts; i++ )
467 {
468 ushort ucaid=client[cs_idx].ftab.filts[i].caid;
469 if( ucaid ) fcaids++;
470 if( ucaid && psfilt->caid==ucaid )
471 {
472 filt.caid = ucaid;
473 break;
474 }
475 }
476 if( fcaids==client[cs_idx].ftab.nfilts && !filt.caid )
477 {
478 cs_log("no valid CAID found in IDENT for user '%s'", client[cs_idx].usr);
479 //cs_disconnect_client();
480 return filt;
481 }
482 }
483 // empty client CAID - use server CAID
484 if( !filt.caid ) filt.caid=psfilt->caid;
485
486 // 2. PROVID
487 if( !client[cs_idx].ftab.nfilts )
488 {
489 int r, add;
490 for (i=0; i<psfilt->nprids; i++) {
491 // use server PROVID(s) (and only those which are in user's groups)
492 add = 0;
493 for (r=0; !add && r<CS_MAXREADER; r++) {
494 if (reader[r].grp & client[cs_idx].grp) {
495 if (!reader[r].ftab.nfilts) {
496 if (reader[r].typ & R_IS_NETWORK) add = 1;
497 for (j=0; !add && j<reader[r].nprov; j++)
498 if (b2i(3, &reader[r].prid[j][1]) == psfilt->prids[i]) add = 1;
499 } else {
500 for (j=0; !add && j<reader[r].ftab.nfilts; j++) {
501 ulong rcaid = reader[r].ftab.filts[j].caid;
502 if (!rcaid || rcaid == filt.caid) {
503 for (k=0; !add && k<reader[r].ftab.filts[j].nprids; k++)
504 if (reader[r].ftab.filts[j].prids[k] == psfilt->prids[i]) add = 1;
505 }
506 }
507 }
508 }
509 }
510 if (add) filt.prids[filt.nprids++] = psfilt->prids[i];
511 }
512 return filt;
513 }
514
515 // search in client IDENT
516 for( j=0; j<client[cs_idx].ftab.nfilts; j++ )
517 {
518 ulong ucaid = client[cs_idx].ftab.filts[j].caid;
519 cs_debug("client caid #%d: %04X", j, ucaid);
520 if( !ucaid || ucaid==filt.caid )
521 {
522 for (i=0; i<psfilt->nprids; i++)
523 {
524 cs_debug("search server provid #%d: %06X", i, psfilt->prids[i]);
525 if( client[cs_idx].ftab.filts[j].nprids )
526 {
527 for( k=0; k<client[cs_idx].ftab.filts[j].nprids; k++ )
528 if (client[cs_idx].ftab.filts[j].prids[k] == psfilt->prids[i])
529 filt.prids[filt.nprids++]=client[cs_idx].ftab.filts[j].prids[k];
530 } else {
531 filt.prids[filt.nprids++] = psfilt->prids[i];
532 // allow server PROVID(s) if no PROVID(s) specified in IDENT
533 }
534 }
535 }
536 }
537
538 if( !filt.nprids )
539 {
540 cs_log("no valid PROVID(s) found in CAID for user '%s'", client[cs_idx].usr);
541 //cs_disconnect_client();
542 }
543
544 return filt;
545}
546
547static void newcamd_auth_client(in_addr_t ip)
548{
549 int i, ok;
550 uchar *usr=NULL, *pwd=NULL;
551 struct s_auth *account;
552 uchar buf[14];
553 uchar *key=0;
554 uint8 *passwdcrypt = NULL;
555 int au=0;
556 struct s_ip *p_ip;
557
558 ok = cfg->ncd_allowed ? 0 : 1;
559 for (p_ip=cfg->ncd_allowed; (p_ip) && (!ok); p_ip=p_ip->next)
560 ok=((ip>=p_ip->ip[0]) && (ip<=p_ip->ip[1]));
561
562 if (!ok)
563 {
564 cs_auth_client((struct s_auth *)0, NULL);
565 cs_exit(0);
566 }
567
568 // make random 14 bytes
569 seed = (unsigned int) time((time_t*)0);
570 for( i=0; i<14; i++ ) buf[i]=fast_rnd();
571
572 // send init sequence
573 send(client[cs_idx].udp_fd, buf, 14, 0);
574 key = des_login_key_get(buf, cfg->ncd_key, 14);
575 memcpy(client[cs_idx].ncd_skey, key, 16);
576 client[cs_idx].ncd_msgid = 0;
577
578 i=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle);
579 if ( i>0 )
580 {
581 if( mbuf[2] != MSG_CLIENT_2_SERVER_LOGIN )
582 {
583 cs_debug("expected MSG_CLIENT_2_SERVER_LOGIN (%02X), received %02X",
584 MSG_CLIENT_2_SERVER_LOGIN, mbuf[2]);
585 if(req)
586 {
587 free(req);
588 req=0;
589 }
590 cs_exit(0);
591 }
592 usr=mbuf+5;
593 pwd=usr+strlen((char *)usr)+1;
594 //cs_debug("usr=%s,pwd=%s", usr, pwd);
595 }
596 else
597 {
598 cs_debug("bad client login request");
599 if(req)
600 {
601 free(req);
602 req=0;
603 }
604 cs_exit(0);
605 }
606
607 for (ok=0, account=cfg->account; (usr) && (account) && (!ok); account=account->next)
608 {
609 cs_debug("account->usr=%s", account->usr);
610 if (strcmp((char *)usr, account->usr) == 0)
611 {
612 passwdcrypt = (uint8*)__md5_crypt(account->pwd, "$1$abcdefgh$");
613 cs_debug("account->pwd=%s", passwdcrypt);
614 if (strcmp((char *)pwd, (const char *)passwdcrypt) == 0)
615 {
616 client[cs_idx].crypted=1;
617 cs_auth_client(account, NULL);
618 cs_log("user %s authenticated successfully (using client %02X%02X)", usr, mbuf[0], mbuf[1]);
619 ok = 1;
620 break;
621 }
622 else
623 {
624 cs_log("user %s is providing a wrong password (using client %02X%02X)", usr, mbuf[0], mbuf[1]);
625 }
626 }
627 }
628
629 if (!ok && !account)
630 {
631 cs_log("user %s is trying to connect but doesnt exist ! (using client %02X%02X)", usr, mbuf[0], mbuf[1]);
632 usr = 0;
633 }
634
635 if (ok)
636 {
637 au = client[cs_idx].au;
638 if (au != -1)
639 {
640 if (cfg->ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid != reader[au].caid[0]
641 && cfg->ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid != reader[au].ftab.filts[0].caid)
642 {
643 cs_log("AU wont be used on this port -> disable AU");
644 au = -1;
645 }
646 else if (reader[au].card_system <= 0 && !(reader[au].typ & R_IS_CASCADING))
647 {
648 // Init for AU enabled card not finished, reject Client
649 ok=0;
650 au = -2; // Flag zur Logausgabe
651 }
652 else
653 {
654 cs_log("AU flag %d for user %s",au,usr);
655 }
656 }
657 else
658 {
659 cs_log("AU disabled for user %s",usr);
660 }
661 }
662
663 network_cmd_no_data_send(client[cs_idx].udp_fd, &client[cs_idx].ncd_msgid,
664 (ok)?MSG_CLIENT_2_SERVER_LOGIN_ACK:MSG_CLIENT_2_SERVER_LOGIN_NAK,
665 client[cs_idx].ncd_skey, COMMTYPE_SERVER);
666
667 // we need to add a test to make sure all card reader are ready before allowing more interaction with the user.
668 // cfg->ncd_ptab.ports[client[cs_idx].port_idx].ftab.filts[0].caid old the CAID for this port
669 // we need to check all ready for a match and check if they are ready
670 // if they arent ready, disconnect the user.
671 // it will reconnect in a few second.
672
673 if (ok)
674 {
675 FILTER pufilt_noau;
676 FILTER *pufilt = 0;
677
678 key = des_login_key_get(cfg->ncd_key, passwdcrypt, strlen((char *)passwdcrypt));
679 memcpy(client[cs_idx].ncd_skey, key, 16);
680
681 i=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle);
682 if( i>0 )
683 {
684 int j,len=15;
685 if( mbuf[2] != MSG_CARD_DATA_REQ)
686 {
687 cs_debug("expected MSG_CARD_DATA_REQ (%02X), received %02X",
688 MSG_CARD_DATA_REQ, mbuf[2]);
689 if(req)
690 {
691 free(req); req=0;
692 }
693 cs_exit(0);
694 }
695
696 client[cs_idx].ftab.filts[0] = mk_user_ftab();
697 pufilt = &client[cs_idx].ftab.filts[0];
698
699 if (au != -1)
700 {
701 unsigned char equal = 1;
702
703 // remember user filter
704 memcpy(&pufilt_noau, pufilt, sizeof(FILTER));
705
706 client[cs_idx].ftab.filts[0] = mk_user_au_ftab(au);
707 pufilt = &client[cs_idx].ftab.filts[0];
708
709 // check if user filter CAID and PROVID is the same as CAID and PROVID of the AU reader
710
711 if ((pufilt->caid != pufilt_noau.caid))
712 {
713 // cs_log("CAID server: %04X, CAID card: %04X, not equal, AU disabled",pufilt_noau.caid,pufilt->caid);
714 // equal = 0;
715 }
716
717 for( j=0; equal && j<pufilt_noau.nprids && j<pufilt->nprids; j++)
718 {
719 if (pufilt->prids[j] != pufilt_noau.prids[j])
720 {
721 // cs_log("PROVID%d server: %04X, PROVID%d card: %04X, not equal, AU disabled",j,pufilt_noau.prids[j],j,pufilt->prids[j]);
722 //weird// equal = 0;
723 }
724 }
725
726 if (!equal)
727 {
728 // Not equal -> AU must set to disabled -> set back to user filter
729 memcpy(pufilt, &pufilt_noau, sizeof(FILTER));
730 au = -1;
731 }
732 }
733
734 client[cs_idx].ftab.nfilts = 1;
735 mbuf[0] = MSG_CARD_DATA;
736 mbuf[1] = 0x00;
737 mbuf[2] = 0x00;
738
739 // AU always set to true because some clients cannot handle "non-AU"
740 // For security reason don't send the real hexserial (see below)
741 // if a non-AU-client sends an EMM-request it will be thrown away
742 // (see function "newcamd_process_emm")
743 //mbuf[3] = 1;
744 if( au!=-1 )
745 mbuf[3] = 1;
746 else
747 mbuf[3] = cs_idx+10; // Unique user number
748
749 mbuf[4] = (uchar)(pufilt->caid>>8);
750 mbuf[5] = (uchar)(pufilt->caid);
751 mbuf[6] = 0x00;
752 mbuf[7] = 0x00;
753
754 if (au != -1)
755 {
756 if (((pufilt->caid >> 8) == 0x17) || ((pufilt->caid >> 8) == 0x06)) // Betacrypt or Irdeto
757 {
758 // only 4 Bytes Hexserial for newcamd clients (Hex Base + Hex Serial)
759 // first 2 Byte always 00
760 mbuf[8]=0x00; //serial only 4 bytes
761 mbuf[9]=0x00; //serial only 4 bytes
762 // 1 Byte Hex Base (see reader-irdeto.c how this is stored in "reader[au].hexserial")
763 mbuf[10]=reader[au].hexserial[3];
764 // 3 Bytes Hex Serial (see reader-irdeto.c how this is stored in "reader[au].hexserial")
765 mbuf[11]=reader[au].hexserial[0];
766 mbuf[12]=reader[au].hexserial[1];
767 mbuf[13]=reader[au].hexserial[2];
768 }
769 else if (((pufilt->caid >> 8) == 0x05) || ((pufilt->caid >> 8) == 0x0D))
770 {
771 mbuf[8] = 0x00;
772 mbuf[9] = reader[au].hexserial[0];
773 mbuf[10] = reader[au].hexserial[1];
774 mbuf[11] = reader[au].hexserial[2];
775 mbuf[12] = reader[au].hexserial[3];
776 mbuf[13] = reader[au].hexserial[4];
777 }
778 else
779 {
780 mbuf[8] = reader[au].hexserial[0];
781 mbuf[9] = reader[au].hexserial[1];
782 mbuf[10] = reader[au].hexserial[2];
783 mbuf[11] = reader[au].hexserial[3];
784 mbuf[12] = reader[au].hexserial[4];
785 mbuf[13] = reader[au].hexserial[5];
786 }
787 }
788 else
789 {
790 client[cs_idx].au = -1;
791 mbuf[8] = 0x00;
792 mbuf[9] = 0x00;
793 mbuf[10] = 0x00;
794 mbuf[11] = 0x00;
795 mbuf[12] = 0x00;
796 mbuf[13] = 0x00;
797 // send "faked" Hexserial to client
798 /*
799 if (((pufilt->caid >= 0x1700) && (pufilt->caid <= 0x1799)) || // Betacrypt
800 ((pufilt->caid >= 0x0600) && (pufilt->caid <= 0x0699))) // Irdeto
801 {
802 mbuf[6] = 0x00;
803 mbuf[7] = 0x00;
804 mbuf[8] = 0x00;
805 mbuf[9] = 0x00;
806 mbuf[10] = fast_rnd();
807 mbuf[11] = fast_rnd();
808 mbuf[12] = fast_rnd();
809 mbuf[13] = fast_rnd();
810 }
811 else
812 {
813 mbuf[6] = fast_rnd();
814 mbuf[7] = fast_rnd();
815 mbuf[8] = fast_rnd();
816 mbuf[9] = fast_rnd();
817 mbuf[10] = fast_rnd();
818 mbuf[11] = fast_rnd();
819 mbuf[12] = fast_rnd();
820 mbuf[13] = fast_rnd();
821 }
822 */
823 }
824
825 mbuf[14] = pufilt->nprids;
826 for( j=0; j<pufilt->nprids; j++)
827 {
828 if ((pufilt->caid >= 0x0600) && (pufilt->caid <= 0x0699)) // Irdeto
829 {
830 mbuf[15+11*j] = 0;
831 mbuf[16+11*j] = 0;
832 mbuf[17+11*j] = j;
833 }
834 else
835 {
836 mbuf[15+11*j] = (uchar)(pufilt->prids[j]>>16);
837 mbuf[16+11*j] = (uchar)(pufilt->prids[j]>>8);
838 mbuf[17+11*j] = (uchar)(pufilt->prids[j]);
839 }
840 mbuf[18+11*j] = 0x00;
841 mbuf[19+11*j] = 0x00;
842 mbuf[20+11*j] = 0x00;
843 mbuf[21+11*j] = 0x00;
844 if( au!=-1 )
845 { // check if user provid from IDENT exists on card
846 int k, found;
847 ulong rprid;
848 found=0;
849 if( pufilt->caid==reader[au].caid[0] )
850 {
851 for( k=0; (k<reader[au].nprov); k++ )
852 {
853 rprid=b2i(3, &reader[au].prid[k][1]);
854 if( rprid==pufilt->prids[j] )
855 {
856 if ((pufilt->caid >= 0x0600) && (pufilt->caid <= 0x0699)) // Irdeto
857 {
858 mbuf[22+11*j] = reader[au].prid[k][0];
859 mbuf[23+11*j] = reader[au].prid[k][1];
860 mbuf[24+11*j] = reader[au].prid[k][2];
861 mbuf[25+11*j] = reader[au].prid[k][3];
862 }
863 else
864 {
865 mbuf[22+11*j] = reader[au].sa[k][0];
866 mbuf[23+11*j] = reader[au].sa[k][1];
867 mbuf[24+11*j] = reader[au].sa[k][2];
868 mbuf[25+11*j] = reader[au].sa[k][3];
869 }
870 found=1;
871 break;
872 }
873 }
874 }
875 if( !found )
876 {
877 mbuf[22+11*j] = 0x00;
878 mbuf[23+11*j] = 0x00;
879 mbuf[24+11*j] = 0x00;
880 mbuf[25+11*j] = 0x00;
881 }
882 }
883 else
884 {
885 if ((pufilt->caid >= 0x0600) && (pufilt->caid <= 0x0699)) // Irdeto
886 {
887 mbuf[22+11*j] = 0x00;
888 mbuf[23+11*j] = (uchar)(pufilt->prids[j]>>16);
889 mbuf[24+11*j] = (uchar)(pufilt->prids[j]>>8);
890 mbuf[25+11*j] = (uchar)(pufilt->prids[j]);
891 }
892 else
893 {
894 mbuf[22+11*j] = 0x00;
895 mbuf[23+11*j] = 0x00;
896 mbuf[24+11*j] = 0x00;
897 mbuf[25+11*j] = 0x00;
898 }
899 }
900 len+=11;
901 }
902
903 if( network_message_send(client[cs_idx].udp_fd, &client[cs_idx].ncd_msgid, mbuf, len, key, COMMTYPE_SERVER, 0 ) <0 )
904 {
905 if(req)
906 {
907 free(req);
908 req=0;
909 }
910 cs_exit(0);
911 }
912 }
913 }
914 else
915 {
916 if (au == -2)
917 cs_auth_client(0, "Init for AU enabled card not finished");
918 else
919 cs_auth_client(0, usr ? "login failure" : "no such user");
920 if(req)
921 {
922 free(req);
923 req=0;
924 }
925 cs_exit(0);
926 }
927}
928
929static void newcamd_send_dcw(ECM_REQUEST *er)
930{
931 int len;
932 ushort cl_msgid;
933
934 if (!client[cs_idx].udp_fd) {
935 cs_debug("ncd_send_dcw: error: client[cs_idx].udp_fd=%d", client[cs_idx].udp_fd);
936 return;
937 }
938 memcpy(&cl_msgid, req+(er->cpti*REQ_SIZE), 2); // get client ncd_msgid + 0x8x
939 mbuf[0] = er->ecm[0];
940 if( client[cs_idx].ftab.filts[0].nprids==0 || er->rc>3 /*not found*/)
941 {
942 len=3;
943 mbuf[1] = mbuf[2] = 0x00;
944 }
945 else
946 {
947 len = 19;
948 mbuf[1] = mbuf[2] = 0x10;
949 memcpy(mbuf+3, er->cw, 16);
950 }
951
952 cs_debug("ncd_send_dcw: er->cpti=%d, cl_msgid=%d, %02X", er->cpti, cl_msgid, mbuf[0]);
953
954 network_message_send(client[cs_idx].udp_fd, &cl_msgid, mbuf, len,
955 client[cs_idx].ncd_skey, COMMTYPE_SERVER, 0);
956}
957
958static void newcamd_process_ecm(uchar *buf)
959{
960 int pi;
961 ECM_REQUEST *er;
962 if (!(er=get_ecmtask())) {
963 return;
964 }
965 // save client ncd_msgid
966 memcpy(req+(er->cpti*REQ_SIZE), &client[cs_idx].ncd_msgid, 2);
967 cs_debug("ncd_process_ecm: er->cpti=%d, cl_msgid=%d, %02X", er->cpti,
968 client[cs_idx].ncd_msgid, buf[2]);
969 er->l=buf[4]+3;
970 er->srvid = (buf[0]<<8)|buf[1];
971 er->caid = 0;
972 pi = client[cs_idx].port_idx;
973 if( cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
974 er->caid=cfg->ncd_ptab.ports[pi].ftab.filts[0].caid;
975 memcpy(er->ecm, buf+2, er->l);
976 get_cw(er);
977}
978
979static void newcamd_process_emm(uchar *buf)
980{
981 int au, ok=1;
982 ushort caid;
983
984 memset(&epg, 0, sizeof(epg));
985 au=client[cs_idx].au;
986
987 // if client is not allowed to do AU just send back the OK-answer to
988 // the client and do nothing else with the received data
989 if ((au>=0) && (au<=CS_MAXREADER))
990 {
991 epg.l=buf[2]+3;
992 caid = client[cs_idx].ftab.filts[0].caid;
993 epg.caid[0] = (uchar)(caid>>8);
994 epg.caid[1] = (uchar)(caid);
995/* if (caid == 0x0500)
996 {
997 ushort emm_head;
998
999 emm_head = (buf[0]<<8) | buf[1];
1000 switch( emm_head )
1001 {
1002 case 0x8e70: // EMM-S
1003 memcpy(epg.hexserial+1, buf+3, 4);
1004 epg.hexserial[4]=reader[au].hexserial[4];
1005 break;
1006 case 0x8870: // EMM-U
1007 case 0x8c70: // confidential ?
1008 default:
1009 cs_log("unsupported emm type: %04X", emm_head);
1010 ok=0;
1011 }
1012 if( !ok ) cs_log("only EMM-S supported");
1013 }
1014 else*/
1015 memcpy(epg.hexserial, reader[au].hexserial, 8); // dummy
1016
1017 memcpy(epg.emm, buf, epg.l);
1018 if( ok )
1019 do_emm(&epg);
1020 }
1021
1022 // Should always send an answer to client (also if au is disabled),
1023 // some clients will disconnect if they get no answer
1024 buf[1] = 0x10;
1025 buf[2] = 0x00;
1026 network_message_send(client[cs_idx].udp_fd, &client[cs_idx].ncd_msgid, buf, 3,
1027 client[cs_idx].ncd_skey, COMMTYPE_SERVER, 0);
1028}
1029
1030static void newcamd_server()
1031{
1032 int rc;
1033
1034 req=(uchar *)malloc(CS_MAXPENDING*REQ_SIZE);
1035 if (!req)
1036 {
1037 cs_log("Cannot allocate memory (errno=%d)", errno);
1038 cs_exit(1);
1039 }
1040
1041 memset(req, 0, CS_MAXPENDING*REQ_SIZE);
1042 client[cs_idx].ncd_server = 1;
1043 cs_debug("client connected to %d port", cfg->ncd_ptab.ports[client[cs_idx].port_idx].s_port);
1044 newcamd_auth_client(client[cs_idx].ip);
1045
1046 // check for clienttimeout, if timeout occurs try to send keepalive / wait for answer
1047 // befor client was disconnected. If keepalive was disabled, exit after clienttimeout
1048 rc=-9;
1049 while(rc==-9)
1050 {
1051 // process_input returns -9 on clienttimeout
1052 while ((rc=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle))>0)
1053 {
1054 switch(mbuf[2])
1055 {
1056 case 0x80:
1057 case 0x81:
1058 newcamd_process_ecm(mbuf);
1059 break;
1060
1061 case MSG_KEEPALIVE:
1062 newcamd_reply_ka();
1063 break;
1064
1065 default:
1066 if(mbuf[2]>0x81 && mbuf[2]<0x90)
1067 newcamd_process_emm(mbuf+2);
1068 else
1069 cs_debug("unknown newcamd command! (%d)", mbuf[2]);
1070 }
1071 }
1072
1073 if(rc==-9)
1074 {
1075 if (client[cs_idx].ncd_keepalive)
1076 newcamd_reply_ka();
1077 else
1078 rc=0;
1079 }
1080 }
1081
1082 if(req)
1083 {
1084 free(req);
1085 req=0;
1086 }
1087
1088 cs_disconnect_client();
1089}
1090
1091/*
1092* client functions
1093*/
1094
1095int newcamd_client_init()
1096{
1097 static struct sockaddr_in loc_sa;
1098 struct protoent *ptrp;
1099 int p_proto;
1100 char ptxt[16];
1101
1102 pfd=0;
1103 if (reader[ridx].r_port<=0)
1104 {
1105 cs_log("invalid port %d for server %s", reader[ridx].r_port, reader[ridx].device);
1106 return(1);
1107 }
1108 if( (ptrp=getprotobyname("tcp")) )
1109 p_proto=ptrp->p_proto;
1110 else
1111 p_proto=6;
1112
1113 client[cs_idx].ip=0;
1114 memset((char *)&loc_sa,0,sizeof(loc_sa));
1115 loc_sa.sin_family = AF_INET;
1116#ifdef LALL
1117 if (cfg->serverip[0])
1118 loc_sa.sin_addr.s_addr = inet_addr(cfg->serverip);
1119 else
1120#endif
1121 loc_sa.sin_addr.s_addr = INADDR_ANY;
1122 loc_sa.sin_port = htons(reader[ridx].l_port);
1123
1124 if ((client[cs_idx].udp_fd=socket(PF_INET, SOCK_STREAM, p_proto))<0)
1125 {
1126 cs_log("Socket creation failed (errno=%d)", errno);
1127 cs_exit(1);
1128 }
1129
1130#ifdef SO_PRIORITY
1131 if (cfg->netprio)
1132 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_PRIORITY,
1133 (void *)&cfg->netprio, sizeof(ulong));
1134#endif
1135 if (!reader[ridx].tcp_ito) {
1136 ulong keep_alive = reader[ridx].tcp_ito?1:0;
1137 setsockopt(client[cs_idx].udp_fd, SOL_SOCKET, SO_KEEPALIVE,
1138 (void *)&keep_alive, sizeof(ulong));
1139 }
1140
1141 if (reader[ridx].l_port>0)
1142 {
1143 if (bind(client[cs_idx].udp_fd, (struct sockaddr *)&loc_sa, sizeof (loc_sa))<0)
1144 {
1145 cs_log("bind failed (errno=%d)", errno);
1146 close(client[cs_idx].udp_fd);
1147 return(1);
1148 }
1149 sprintf(ptxt, ", port=%d", reader[ridx].l_port);
1150 }
1151 else
1152 ptxt[0]='\0';
1153
1154 memset((char *)&client[cs_idx].udp_sa,0,sizeof(client[cs_idx].udp_sa));
1155 client[cs_idx].udp_sa.sin_family = AF_INET;
1156 client[cs_idx].udp_sa.sin_port = htons((u_short)reader[ridx].r_port);
1157
1158 ncd_proto = reader[ridx].ncd_proto;
1159
1160 cs_log("proxy %s:%d newcamd52%d (fd=%d%s)",
1161 reader[ridx].device, reader[ridx].r_port,
1162 (ncd_proto==NCD_525)?5:4, client[cs_idx].udp_fd, ptxt);
1163 //pfd=client[cs_idx].udp_fd; // !!! we set it after connect() (linux)
1164 return(0);
1165}
1166
1167static int newcamd_send_ecm(ECM_REQUEST *er, uchar *buf)
1168{
1169 //int rc=(-1);
1170 if (!client[cs_idx].udp_sa.sin_addr.s_addr) // once resolved at least
1171 return(-1);
1172
1173 // check server filters
1174 if( !newcamd_connect() ) return (-1);
1175
1176 if( !chk_rsfilter(er, reader[ridx].ncd_disable_server_filt) ) return(-1);
1177
1178 memcpy(buf, er->ecm, er->l);
1179
1180 return((newcamd_send(buf, er->l, er->srvid)<1) ? (-1) : 0);
1181}
1182
1183static int newcamd_recv_chk(uchar *dcw, int *rc, uchar *buf, int n)
1184{
1185 ushort idx;
1186
1187 if( n<21 ) // no cw, ignore others
1188 return(-1);
1189 *rc = 1;
1190 idx = (buf[0] << 8) | buf[1];
1191 memcpy(dcw, buf+5, 16);
1192 return(idx);
1193}
1194
1195void module_newcamd(struct s_module *ph)
1196{
1197 strcpy(ph->desc, "newcamd");
1198 ph->type=MOD_CONN_TCP;
1199 ph->logtxt = ", crypted";
1200 ph->multi=1;
1201 ph->watchdog=1;
1202 ph->s_ip=cfg->ncd_srvip;
1203 ph->s_handler=newcamd_server;
1204 ph->recv=newcamd_recv;
1205 ph->send_dcw=newcamd_send_dcw;
1206 ph->ptab=&cfg->ncd_ptab;
1207 if( ph->ptab->nports==0 )
1208 ph->ptab->nports=1; // show disabled in log
1209 ph->c_multi=1;
1210 ph->c_init=newcamd_client_init;
1211 ph->c_recv_chk=newcamd_recv_chk;
1212 ph->c_send_ecm=newcamd_send_ecm;
1213
1214}
Note: See TracBrowser for help on using the repository browser.