source: trunk/module-newcamd.c@ 3172

Last change on this file since 3172 was 3172, checked in by _network, 10 years ago

remove global mbuf

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