PageRenderTime 29ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/module-scam.c

https://github.com/nx111/oscam-nx111
C | 1197 lines | 975 code | 194 blank | 28 comment | 197 complexity | f5e3c0849f63c375073fa5b69da7c951 MD5 | raw file
  1. #define MODULE_LOG_PREFIX "scam"
  2. #include "globals.h"
  3. #ifdef MODULE_SCAM
  4. #include "oscam-client.h"
  5. #include "oscam-ecm.h"
  6. #include "oscam-net.h"
  7. #include "oscam-string.h"
  8. #include "oscam-reader.h"
  9. #include "oscam-lock.h"
  10. #include "oscam-time.h"
  11. #include "oscam-chk.h"
  12. #include "cscrypt/des.h"
  13. struct scam_data
  14. {
  15. uint8_t enckey[8];
  16. uint8_t deckey[8];
  17. uint8_t enc_xor_offset;
  18. uint8_t dec_xor_offset;
  19. uint8_t login_pending;
  20. char login_username[64];
  21. uint16_t version;
  22. };
  23. static inline void xxor(uint8_t *data, int32_t len, const uint8_t *v1, const uint8_t *v2)
  24. {
  25. uint32_t i;
  26. switch(len)
  27. {
  28. case 16:
  29. for(i = 0; i < 16; ++i)
  30. {
  31. data[i] = v1[i] ^ v2[i];
  32. }
  33. break;
  34. case 8:
  35. for(i = 0; i < 8; ++i)
  36. {
  37. data[i] = v1[i] ^ v2[i];
  38. }
  39. break;
  40. case 4:
  41. for(i = 0; i < 4; ++i)
  42. {
  43. data[i] = v1[i] ^ v2[i];
  44. }
  45. break;
  46. default:
  47. while(len--)
  48. {
  49. *data++ = *v1++ ^ *v2++;
  50. }
  51. break;
  52. }
  53. }
  54. static void scam_generate_deskey(char *keyString, uint8_t *desKey)
  55. {
  56. uint8_t iv[8], *tmpKey;
  57. int32_t i, passLen, alignedPassLen;
  58. uint32_t key_schedule[32];
  59. memset(iv, 0, 8);
  60. memset(desKey, 0, 8);
  61. passLen = keyString == NULL ? 0 : cs_strlen(keyString);
  62. if(passLen > 1024) {
  63. passLen = 1024;
  64. }
  65. alignedPassLen = (passLen + 7) & -8;
  66. if(alignedPassLen == 0) alignedPassLen = 8;
  67. if(!cs_malloc(&tmpKey, alignedPassLen))
  68. {
  69. return;
  70. }
  71. if(passLen == 0)
  72. {
  73. memset(tmpKey, 0xAA, 8);
  74. passLen = 8;
  75. }
  76. else
  77. {
  78. memcpy(tmpKey, keyString, passLen);
  79. }
  80. for(i = 0; i < alignedPassLen - passLen; i++)
  81. {
  82. tmpKey[passLen + i] = (uint8_t)i;
  83. }
  84. xxor(desKey, 8, tmpKey, iv);
  85. for(i = 0; i < alignedPassLen; i += 8)
  86. {
  87. des_set_key(&tmpKey[i], key_schedule);
  88. des(&tmpKey[i], key_schedule, 1);
  89. xxor(desKey, 8, desKey, &tmpKey[i]);
  90. }
  91. NULLFREE(tmpKey);
  92. }
  93. static void scam_encrypt_packet(uint8_t *packet, uint32_t packetLength, uint8_t *key, uint32_t dataLength, uint32_t dataOffset, uint8_t *xorOffset)
  94. {
  95. uint8_t iv[8];
  96. uint32_t i;
  97. memset(iv, 0, 8);
  98. des_cbc_encrypt(packet + dataOffset, iv, key, dataLength);
  99. for(i = 0; i < packetLength; i++)
  100. {
  101. key[*xorOffset] ^= packet[i];
  102. *xorOffset = (*xorOffset + 1) & 7;
  103. }
  104. }
  105. static void scam_decrypt_packet(uint8_t *packet, uint32_t packetLength, uint8_t *key, uint32_t dataLength, uint32_t dataOffset, uint8_t *xorOffset)
  106. {
  107. uint8_t tmpKey[8], iv[8];
  108. uint32_t i;
  109. memcpy(tmpKey, key, 8);
  110. memset(iv, 0, 8);
  111. for(i = 0; i < packetLength; i++)
  112. {
  113. tmpKey[*xorOffset] ^= packet[i];
  114. *xorOffset = (*xorOffset + 1) & 7;
  115. }
  116. des_cbc_decrypt(packet + dataOffset, iv, key, dataLength);
  117. memcpy(key, tmpKey, 8);
  118. }
  119. static void scam_decode_length(uint8_t *packet, uint32_t *dataLength, uint32_t *dataOffset)
  120. {
  121. uint32_t i, n;
  122. if(packet[1] & 0x80)
  123. {
  124. n = packet[1] & ~0x80;
  125. *dataLength = 0;
  126. for(i = 0; i < n; i++)
  127. {
  128. *dataLength = (*dataLength << 8) | packet[2 + i];
  129. }
  130. *dataOffset = 2 + n;
  131. }
  132. else
  133. {
  134. *dataLength = packet[1];
  135. *dataOffset = 2;
  136. }
  137. }
  138. static uint32_t scam_get_length_data_length(uint8_t *packet)
  139. {
  140. if(packet[1] & 0x80)
  141. {
  142. return packet[1] & ~0x80;
  143. }
  144. else
  145. {
  146. return 1;
  147. }
  148. }
  149. static void scam_encode_length(uint32_t len, uint8_t *data, uint8_t *dataLen)
  150. {
  151. if(len < 128)
  152. {
  153. data[0] = (uint8_t)len;
  154. *dataLen = 1;
  155. }
  156. else if(len < 256)
  157. {
  158. data[0] = 0x81;
  159. data[1] = (uint8_t)len;
  160. *dataLen = 2;
  161. }
  162. else if(len < 65536)
  163. {
  164. data[0] = 0x82;
  165. data[1] = (uint8_t)(len >> 8);
  166. data[2] = (uint8_t)(len & 0xFF);
  167. *dataLen = 3;
  168. }
  169. else if(len < 16777216)
  170. {
  171. data[0] = 0x83;
  172. data[1] = (uint8_t)(len >> 16);
  173. data[2] = (uint8_t)((len >> 8) & 0xFF);
  174. data[3] = (uint8_t)(len & 0xFF);
  175. *dataLen = 4;
  176. }
  177. else
  178. {
  179. data[0] = 0x84;
  180. data[1] = (uint8_t)(len >> 24);
  181. data[2] = (uint8_t)((len >> 16) & 0xFF);
  182. data[3] = (uint8_t)((len >> 8) & 0xFF);
  183. data[4] = (uint8_t)(len & 0xFF);
  184. *dataLen = 5;
  185. }
  186. }
  187. static void scam_client_close(struct s_client *cl, int32_t call_conclose)
  188. {
  189. struct s_reader *rdr = cl->reader;
  190. if(!rdr) { return; }
  191. if(rdr) { rdr->tcp_connected = 0; }
  192. if(rdr) { rdr->card_status = NO_CARD; }
  193. if(rdr) { rdr->last_s = rdr->last_g = 0; }
  194. if(cl) { cl->last = 0; }
  195. if(call_conclose) // clears also pending ecms!
  196. { network_tcp_connection_close(rdr, "close"); }
  197. else
  198. {
  199. if(cl->udp_fd)
  200. {
  201. close(cl->udp_fd);
  202. cl->udp_fd = 0;
  203. cl->pfd = 0;
  204. }
  205. }
  206. }
  207. static int32_t scam_send(struct s_client *cl, uint8_t *buf, uint32_t len)
  208. {
  209. uint8_t *mbuf, lenData[5];
  210. uint8_t lenDataLen = 0, paddingLen = 0;
  211. uint16_t crc = 0;
  212. int32_t result, packetLen;
  213. struct scam_data *scam = cl->scam;
  214. if(scam == NULL) { return 0; }
  215. if(len == 0) { return 0; }
  216. paddingLen = 8 - ((4 + len) % 8);
  217. if(paddingLen == 8)
  218. {
  219. paddingLen = 0;
  220. }
  221. else if(paddingLen > 0 && paddingLen < 3)
  222. {
  223. paddingLen += 8;
  224. }
  225. scam_encode_length(4 + len + paddingLen, lenData, &lenDataLen);
  226. if(lenDataLen == 0) { return -1; }
  227. packetLen = 1 + lenDataLen + 4 + len + paddingLen;
  228. if(!cs_malloc(&mbuf, packetLen)) { return -1; }
  229. mbuf[0] = 0x0F;
  230. memcpy(&mbuf[1], lenData, lenDataLen);
  231. mbuf[1 + lenDataLen] = 0x10;
  232. mbuf[1 + lenDataLen + 1] = 0x02;
  233. memcpy(&mbuf[1 + lenDataLen + 4], buf, len);
  234. if(paddingLen > 0)
  235. {
  236. mbuf[1 + lenDataLen + 4 + len] = 0x7F;
  237. mbuf[1 + lenDataLen + 4 + len + 1] = paddingLen - 2;
  238. get_random_bytes(mbuf + 1 + lenDataLen + 4 + len + 2, paddingLen - 2);
  239. }
  240. crc = ccitt_crc(mbuf + 1 + lenDataLen + 4, len + paddingLen, 0xFFFF, 0);
  241. i2b_buf(2, crc, &mbuf[1 + lenDataLen + 2]);
  242. scam_encrypt_packet(mbuf, packetLen, scam->enckey, 4 + len + paddingLen, 1 + lenDataLen, &scam->enc_xor_offset);
  243. result = send(cl->pfd, mbuf, packetLen, 0);
  244. NULLFREE(mbuf);
  245. return (result);
  246. }
  247. static int32_t scam_msg_recv(struct s_client *cl, uint8_t *buf, int32_t maxlen)
  248. {
  249. int32_t len;
  250. int32_t handle = cl->udp_fd;
  251. struct scam_data *scam = cl->scam;
  252. if(scam == NULL) { return 0; }
  253. if(handle <= 0 || maxlen < 3)
  254. { cs_log("scam_msg_recv: fd is 0"); return -1; }
  255. len = cs_recv(handle, buf, 2, MSG_WAITALL);
  256. if(len != 2) // invalid header length read
  257. {
  258. if(len <= 0)
  259. { cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "disconnected by remote server"); }
  260. else
  261. { cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "invalid header length (expected 2, read %d)", len); }
  262. return -1;
  263. }
  264. if(buf[0] != 0x0F)
  265. {
  266. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "invalid packet tag");
  267. return 0;
  268. }
  269. int32_t headerSize = buf[1] & 0x80 ? (2 + (buf[1] & ~0x80)) : 2;
  270. if(headerSize > 2)
  271. {
  272. if(maxlen < headerSize + 1) { return -1; }
  273. len = cs_recv(handle, buf + 2, headerSize - 2, MSG_WAITALL);
  274. if(len != headerSize - 2) // invalid header length read
  275. {
  276. if(len <= 0)
  277. { cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "disconnected by remote server"); }
  278. else
  279. { cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "invalid header length (expected %d, read %d)", headerSize, 2+len); }
  280. return -1;
  281. }
  282. }
  283. uint32_t dataLength, dataOffset;
  284. scam_decode_length(buf, &dataLength, &dataOffset);
  285. if(dataLength) // check if any data is expected in msg
  286. {
  287. if(dataLength % 8 != 0)
  288. {
  289. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "message data has invalid size (size=%d)", dataLength);
  290. return 0;
  291. }
  292. if(headerSize + dataLength > (uint32_t)maxlen)
  293. {
  294. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "message too big (size=%d max=%d)", headerSize+dataLength, maxlen);
  295. return 0;
  296. }
  297. len = cs_recv(handle, buf + dataOffset, dataLength, MSG_WAITALL);
  298. if((uint32_t)len != dataLength)
  299. {
  300. if(len <= 0)
  301. {
  302. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "disconnected by remote");
  303. }
  304. else
  305. {
  306. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "invalid message length read (expected %d, read %d)", dataLength, len);
  307. }
  308. return -1;
  309. }
  310. scam_decrypt_packet(buf, headerSize + dataLength, scam->deckey, dataLength, dataOffset, &scam->dec_xor_offset);
  311. }
  312. return headerSize+dataLength;
  313. }
  314. static int32_t scam_recv(struct s_client *cl, uint8_t *buf, int32_t len)
  315. {
  316. int32_t n;
  317. struct s_reader *rdr = (cl->typ == 'c') ? NULL : cl->reader;
  318. if(buf == NULL || len <= 0)
  319. { return -1; }
  320. n = scam_msg_recv(cl, buf, len); // recv and decrypt msg
  321. if(n <= 0)
  322. {
  323. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "connection closed by %s, n=%d.", remote_txt(), n);
  324. if(rdr)
  325. {
  326. scam_client_close(cl, 1);
  327. }
  328. else
  329. {
  330. cs_disconnect_client(cl);
  331. }
  332. cs_sleepms(150);
  333. n = -1;
  334. }
  335. else
  336. {
  337. cl->last = time(NULL); // last client action is now
  338. if(rdr) { rdr->last_g = time(NULL); } // last reader receive is now
  339. }
  340. return n;
  341. }
  342. // scam client functions
  343. static int32_t scam_client_init(struct s_client *cl);
  344. static int32_t scam_client_connect(void)
  345. {
  346. struct s_client *cl = cur_client();
  347. if(cl->reader->tcp_connected < 2 && scam_client_init(cl) < 0)
  348. { return 0; }
  349. if(!cl->udp_fd)
  350. { return 0; }
  351. return 1;
  352. }
  353. static void scam_client_idle(void)
  354. {
  355. struct s_client *client = cur_client();
  356. struct s_reader *rdr = client->reader;
  357. time_t now = time(NULL);
  358. if(!rdr) { return; }
  359. if(rdr->tcp_ito > 0)
  360. {
  361. int32_t time_diff;
  362. time_diff = llabs(now - rdr->last_s);
  363. if(time_diff > (rdr->tcp_ito))
  364. {
  365. network_tcp_connection_close(rdr, "inactivity");
  366. return;
  367. }
  368. }
  369. else if(rdr->tcp_ito == -1)
  370. {
  371. scam_client_connect();
  372. return;
  373. }
  374. }
  375. static void scam_client_recv_caid(uint8_t *buf, uint32_t len)
  376. {
  377. uint16_t caid;
  378. if(len < 3)
  379. {
  380. return;
  381. }
  382. caid = buf[1] << 8 | buf[2];
  383. if(buf[0])
  384. {
  385. cs_log("scam server has card: %04X", caid);
  386. }
  387. else
  388. {
  389. cs_log("scam server no longer has card: %04X", caid);
  390. }
  391. }
  392. static void scam_client_recv_server_version(uint8_t *buf, uint32_t len)
  393. {
  394. uint32_t pos = 0, dataLength = 0, dataOffset = 0, usedLen = 0;
  395. char versionString[128];
  396. uint16_t versionShort = 0;
  397. versionString[0] = 0;
  398. scam_decode_length(buf, &dataLength, &dataOffset);
  399. while(pos + dataOffset + dataLength - 1 < len)
  400. {
  401. switch(buf[pos])
  402. {
  403. case 0x01: // version string
  404. usedLen = dataLength;
  405. if(usedLen > 127)
  406. {
  407. usedLen = 127;
  408. }
  409. memcpy(versionString, buf + dataOffset, usedLen);
  410. versionString[usedLen] = 0;
  411. break;
  412. case 0x0A: // version short
  413. if(dataLength != 2) break;
  414. versionShort = (buf[pos + dataOffset] << 8) | buf[pos + dataOffset + 1];
  415. break;
  416. default:
  417. cs_log_dbg(D_READER, "unknown server version packet tag %X", buf[pos]);
  418. break;
  419. }
  420. pos += dataOffset + dataLength;
  421. if((pos + 2 < len) && (pos + 1 + scam_get_length_data_length(buf + pos)) < len)
  422. {
  423. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  424. }
  425. else
  426. {
  427. break;
  428. }
  429. }
  430. cs_log("scam server version: %s (%d)", versionString, versionShort);
  431. }
  432. static void scam_client_recv_dcw(struct s_client *cl, uint8_t *buf, uint32_t len, uint8_t *dcw, int32_t *ecm_task_idx, int32_t *rc)
  433. {
  434. // 00C00000 enigma namespace
  435. // 0455 tsid
  436. // 0001 onid
  437. // 151A srvid
  438. // 200081 ???
  439. // 943E85577035C469 dcw1
  440. // C73882811721E31B dcw2
  441. if(len != 29)
  442. {
  443. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "unknown server dcw packet length %d", len);
  444. return;
  445. }
  446. *ecm_task_idx = b2i(4, &buf[0]); // we store idx here instead of ens
  447. memcpy(dcw, &buf[13], 16);
  448. *rc = 1;
  449. }
  450. static void scam_client_send_hello(struct s_client *cl)
  451. {
  452. uint8_t mbuf[70];
  453. uint32_t usernameLen, i = 0;
  454. struct s_reader *rdr = cl->reader;
  455. struct scam_data *scam = cl->scam;
  456. if(scam == NULL) { return; }
  457. if(!rdr) { return; }
  458. usernameLen = cs_strlen(rdr->r_usr);
  459. if(usernameLen > 63) // because rdr->r_usr is max. 63+1 chars
  460. {
  461. usernameLen = 63;
  462. }
  463. mbuf[i++] = 0x46; // client hello data type
  464. mbuf[i++] = 6 + usernameLen; // will never exceed 63+6 = 69 bytes (<127 bytes)
  465. // client version
  466. mbuf[i++] = 0xA0; // client version data type
  467. mbuf[i++] = 0x02; // data length (2)
  468. mbuf[i++] = 0x00; // version ( 0x0007)
  469. mbuf[i++] = 0x07;
  470. // username
  471. mbuf[i++] = 0xA1; // username data type
  472. mbuf[i++] = (uint8_t)usernameLen;
  473. memcpy(mbuf + i, rdr->r_usr, usernameLen);
  474. mbuf[i + usernameLen] = 0;
  475. scam_send(cl, mbuf, 8 + usernameLen);
  476. scam_generate_deskey(rdr->r_pwd, scam->enckey);
  477. scam_generate_deskey(rdr->r_pwd, scam->deckey);
  478. scam->enc_xor_offset = 0;
  479. scam->dec_xor_offset = 0;
  480. }
  481. static int32_t scam_client_send_ecm(struct s_client *cl, ECM_REQUEST *er)
  482. {
  483. // 2481A5 310A
  484. // 00C00000 enigma namespace
  485. // 0455 tsid
  486. // 0001 onid
  487. // 151A srvid
  488. // 3002
  489. // 1843 caid
  490. // 3304
  491. // 66A1AE16 pat/pmt crc? we currently fill it with chid
  492. // 348189
  493. // 8130.. ecm
  494. // 3501
  495. // 02 needed dcws?
  496. uint8_t *mbuf, packetLenData[5], ecmLenData[5];
  497. uint32_t i = 0, ret = 0, dataLength = 0, packetLength = 0;
  498. uint8_t pLenDataLen = 0, eLenDataLen = 0;
  499. if(!scam_client_connect())
  500. { return (-1); }
  501. scam_encode_length(er->ecmlen, ecmLenData, &eLenDataLen);
  502. dataLength = 23 + eLenDataLen + er->ecmlen + 3;
  503. scam_encode_length(dataLength, packetLenData, &pLenDataLen);
  504. packetLength = 1 + pLenDataLen + dataLength;
  505. if(!cs_malloc(&mbuf, packetLength))
  506. { return -1; }
  507. mbuf[i++] = 0x24; // ecm request data type
  508. memcpy(mbuf + i, packetLenData, pLenDataLen); i += pLenDataLen;
  509. mbuf[i++] = 0x31; // channel info data type
  510. mbuf[i++] = 0x0A; // size is always 0x0A
  511. //i2b_buf(4, er->ens, mbuf+i); i += 4;
  512. i2b_buf(4, er->idx, mbuf+i); i += 4; // we store idx instead of ens here
  513. i2b_buf(2, er->tsid, mbuf + i); i += 2;
  514. i2b_buf(2, er->onid, mbuf + i); i += 2;
  515. i2b_buf(2, er->srvid, mbuf + i); i += 2;
  516. mbuf[i++] = 0x30; // caid data type
  517. mbuf[i++] = 0x02; // size is always 0x02
  518. i2b_buf(2, er->caid, mbuf + i); i += 2;
  519. mbuf[i++] = 0x33; // ??? data type
  520. mbuf[i++] = 0x04; // size is always 0x04
  521. i2b_buf(2, er->chid, mbuf + i); i += 4;
  522. mbuf[i++] = 0x34; // ecm data type
  523. memcpy(mbuf + i, ecmLenData, eLenDataLen); i += eLenDataLen;
  524. memcpy(mbuf + i, er->ecm, er->ecmlen); i += er->ecmlen;
  525. mbuf[i++] = 0x35; // ??? data type
  526. mbuf[i++] = 0x01; // size is always 0x01
  527. mbuf[i++] = 0x02; // unknown value
  528. ret = scam_send(cl, mbuf, packetLength);
  529. cs_log_dbg(D_TRACE, "scam: sending ecm");
  530. cs_log_dump_dbg(D_CLIENT, mbuf, packetLength, "ecm:");
  531. NULLFREE(mbuf);
  532. return ((ret < 1) ? (-1) : 0);
  533. }
  534. static int32_t scam_client_init(struct s_client *cl)
  535. {
  536. int32_t handle;
  537. handle = network_tcp_connection_open(cl->reader);
  538. if(handle < 0) {
  539. cl->reader->last_s = 0; // set last send to zero
  540. cl->reader->last_g = 0; // set last receive to zero
  541. cl->last = 0; // set last client action to zero
  542. return (0);
  543. }
  544. if(cl->scam) {
  545. memset(cl->scam, 0, sizeof(struct scam_data));
  546. }
  547. if(!cl->scam && !cs_malloc(&cl->scam, sizeof(struct scam_data))) {
  548. return 0;
  549. }
  550. cs_log("scam: proxy %s:%d (fd=%d)",
  551. cl->reader->device, cl->reader->r_port, cl->udp_fd);
  552. cl->reader->tcp_connected = 2;
  553. cl->reader->card_status = CARD_INSERTED;
  554. cl->reader->last_g = cl->reader->last_s = time((time_t *)0);
  555. cs_log_dbg(D_CLIENT, "scam: last_s=%ld, last_g=%ld", cl->reader->last_s, cl->reader->last_g);
  556. cl->pfd = cl->udp_fd;
  557. scam_client_send_hello(cl);
  558. return (0);
  559. }
  560. static int32_t scam_client_handle(struct s_client *cl, uint8_t *dcw, int32_t *rc, uint8_t *buf, int32_t n)
  561. {
  562. uint32_t pos = 0, packetLength = 0, packetOffset = 0, dataLength = 0, dataOffset = 0;
  563. int32_t ret = -1;
  564. if(n < 3)
  565. {
  566. return (-1);
  567. }
  568. scam_decode_length(buf, &packetLength, &packetOffset);
  569. pos += packetOffset;
  570. if((pos + 2 < (uint32_t)n) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)n))
  571. {
  572. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  573. }
  574. else
  575. {
  576. return (-1);
  577. }
  578. while(pos + dataOffset + dataLength - 1 < (uint32_t)n)
  579. {
  580. switch(buf[pos])
  581. {
  582. case 0x10: // checksum
  583. if(dataLength != 2) { break; }
  584. if(b2i(2, &buf[pos + dataOffset]) != ccitt_crc(buf + pos + dataOffset + 2, n - pos - dataOffset - 2, 0xFFFF, 0))
  585. {
  586. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "sent packet with invalid checksum");
  587. return (-1);
  588. }
  589. break;
  590. case 0x20: // caid list
  591. scam_client_recv_caid(buf + pos + dataOffset, dataLength);
  592. break;
  593. case 0x45: // server version
  594. scam_client_recv_server_version(buf + pos + dataOffset, dataLength);
  595. break;
  596. case 0x63: // dcw
  597. scam_client_recv_dcw(cl, buf + pos + dataOffset, dataLength, dcw, &ret, rc);
  598. break;
  599. case 0x7F: // padding
  600. break;
  601. default:
  602. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "unknown scam server packet %X", buf[pos]);
  603. break;
  604. }
  605. pos += dataOffset + dataLength;
  606. if((pos + 2 < (uint32_t)n) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)n))
  607. {
  608. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  609. }
  610. else
  611. {
  612. break;
  613. }
  614. }
  615. return ret;
  616. }
  617. // scam server functions
  618. static uint8_t scam_server_authip_client(struct s_client *cl)
  619. {
  620. if(cfg.scam_allowed && !check_ip(cfg.scam_allowed, cl->ip))
  621. {
  622. cs_log("scam: IP not allowed");
  623. cs_auth_client(cl, (struct s_auth *)0, NULL);
  624. cs_disconnect_client(cl);
  625. return 0;
  626. }
  627. return 1;
  628. }
  629. static void scam_server_init(struct s_client *cl)
  630. {
  631. if(!cl->init_done)
  632. {
  633. if(IP_ISSET(cl->ip))
  634. { cs_log("scam: new connection from %s", cs_inet_ntoa(cl->ip)); }
  635. if(scam_server_authip_client(cl))
  636. {
  637. if(cl->scam)
  638. {
  639. memset(cl->scam, 0, sizeof(struct scam_data));
  640. }
  641. if(cl->scam || cs_malloc(&cl->scam, sizeof(struct scam_data)))
  642. {
  643. cl->init_done = 1;
  644. }
  645. }
  646. }
  647. return;
  648. }
  649. static void scam_server_recv_ecm(struct s_client *cl, uint8_t *buf, int32_t len)
  650. {
  651. uint32_t pos = 0, dataLength = 0, dataOffset = 0, usedLen = 0;
  652. ECM_REQUEST *er;
  653. uint8_t gotCaid = 0, gotEcm = 0;
  654. if(len < 1)
  655. {
  656. return;
  657. }
  658. if(!(er = get_ecmtask()))
  659. { return; }
  660. scam_decode_length(buf, &dataLength, &dataOffset);
  661. while(pos + dataOffset + dataLength - 1 < (uint32_t)len)
  662. {
  663. switch(buf[pos]) {
  664. case 0x31: // channel data
  665. if(dataLength != 0x0A) break;
  666. er->ens = b2i(4, buf + pos + dataOffset);
  667. er->tsid = b2i(2, buf + pos + dataOffset + 4);
  668. er->onid = b2i(2, buf + pos + dataOffset + 6);
  669. er->srvid = b2i(2, buf + pos + dataOffset + 8);
  670. break;
  671. case 0x30: // caid
  672. if(dataLength != 0x02) break;
  673. er->caid = b2i(2, buf + pos + dataOffset);
  674. gotCaid = 1;
  675. break;
  676. case 0x33: // unknown
  677. break;
  678. case 0x34: // ecm
  679. usedLen = dataLength;
  680. if(usedLen > MAX_ECM_SIZE)
  681. {
  682. break;
  683. }
  684. er->ecmlen = usedLen;
  685. memcpy(er->ecm, buf + pos + dataOffset, usedLen);
  686. gotEcm = 1;
  687. break;
  688. case 0x35: // unknown
  689. break;
  690. default:
  691. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "sent unknown scam client ecm tag %X", buf[pos]);
  692. break;
  693. }
  694. pos += dataOffset + dataLength;
  695. if((pos + 2 < (uint32_t)len) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)len))
  696. {
  697. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  698. }
  699. else
  700. {
  701. break;
  702. }
  703. }
  704. if(gotCaid && gotEcm)
  705. {
  706. get_cw(cl, er);
  707. }
  708. else
  709. {
  710. NULLFREE(er);
  711. cs_log("WARNING: ECM-request corrupt");
  712. }
  713. }
  714. static void scam_caidlist_add(uint16_t *caidlist, uint32_t listsize, uint32_t *count, uint16_t caid)
  715. {
  716. uint32_t i;
  717. uint8_t exists = 0;
  718. if(*count >= listsize)
  719. {
  720. return;
  721. }
  722. for(i = 0; i < *count; i++)
  723. {
  724. if(caidlist[i] == caid)
  725. {
  726. exists = 1;
  727. break;
  728. }
  729. }
  730. if(!exists)
  731. {
  732. caidlist[*count] = caid;
  733. (*count)++;
  734. }
  735. }
  736. static void scam_server_send_caidlist(struct s_client *cl)
  737. {
  738. uint8_t mbuf[5];
  739. int32_t j;
  740. uint32_t i = 0;
  741. uint16_t caids[55];
  742. uint32_t cardcount = 0;
  743. struct s_reader *rdr = NULL;
  744. cs_readlock(__func__, &readerlist_lock);
  745. for(rdr = first_active_reader; rdr; rdr = rdr->next)
  746. {
  747. if(rdr->caid && chk_ctab(rdr->caid, &cl->ctab))
  748. {
  749. scam_caidlist_add(caids, ARRAY_SIZE(caids), &cardcount, rdr->caid);
  750. }
  751. for(j = 0; j < rdr->ctab.ctnum; j++)
  752. {
  753. CAIDTAB_DATA *d = &rdr->ctab.ctdata[j];
  754. if(d->caid && chk_ctab(d->caid, &cl->ctab))
  755. {
  756. scam_caidlist_add(caids, ARRAY_SIZE(caids), &cardcount, d->caid);
  757. }
  758. }
  759. }
  760. cs_readunlock(__func__, &readerlist_lock);
  761. for(j = 0; j < (int32_t)cardcount; j++)
  762. {
  763. i = 0;
  764. mbuf[i++] = 0x20; // caid data type
  765. mbuf[i++] = 0x03; // length
  766. mbuf[i++] = 0x01; // active card
  767. i2b_buf(2, caids[j], mbuf + i);
  768. scam_send(cl, mbuf, 5);
  769. }
  770. }
  771. static void scam_server_send_serverversion(struct s_client *cl)
  772. {
  773. uint8_t mbuf[64];
  774. uint32_t i = 0;
  775. char *version = "scam/3.60 oscam";
  776. uint8_t vlen = cs_strlen(version);
  777. mbuf[i++] = 0x45; // server version data type
  778. mbuf[i++] = 2 + vlen + 4; // will never exceed 127 bytes
  779. mbuf[i++] = 0x01; // server version string data type
  780. mbuf[i++] = vlen; // will never exceed 127 bytes
  781. memcpy(mbuf + i, version, vlen); i += vlen;
  782. mbuf[i++] = 0x0A; // server version short data type
  783. mbuf[i++] = 0x02; // is always 0x02
  784. i2b_buf(2, 0x7, mbuf + i);
  785. scam_send(cl, mbuf, 2 + 2 + vlen + 4);
  786. }
  787. static void scam_server_recv_auth(struct s_client *cl, uint8_t *buf, int32_t len)
  788. {
  789. uint32_t pos = 0, dataLength = 0, dataOffset = 0, usedLen = 0;
  790. uint8_t userok = 0;
  791. struct s_auth *account;
  792. struct scam_data *scam = cl->scam;
  793. if(scam == NULL) { return; }
  794. scam->login_username[0] = 0;
  795. if(len < 1)
  796. {
  797. return;
  798. }
  799. scam_decode_length(buf, &dataLength, &dataOffset);
  800. while(pos + dataOffset + dataLength - 1 < (uint32_t)len)
  801. {
  802. switch(buf[pos])
  803. {
  804. case 0xA0: // version short
  805. if(dataLength != 2) break;
  806. scam->version = (buf[pos + dataOffset] << 8) | buf[pos + dataOffset + 1];
  807. break;
  808. case 0xA1: // username string
  809. usedLen = dataLength;
  810. if(usedLen > 64) {
  811. usedLen = 63;
  812. }
  813. memcpy(scam->login_username, buf + pos + dataOffset, usedLen);
  814. scam->login_username[usedLen] = 0;
  815. break;
  816. default:
  817. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "unknown client auth packet tag %X", buf[pos]);
  818. break;
  819. }
  820. pos += dataOffset + dataLength;
  821. if((pos + 2 < (uint32_t)len) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)len))
  822. {
  823. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  824. }
  825. else
  826. {
  827. break;
  828. }
  829. }
  830. for(account = cfg.account; account; account = account->next)
  831. {
  832. if(streq(scam->login_username, account->usr))
  833. {
  834. userok = 1;
  835. break;
  836. }
  837. }
  838. if(!userok)
  839. {
  840. cs_auth_client(cl, (struct s_auth *)0, NULL);
  841. cs_disconnect_client(cl);
  842. return;
  843. }
  844. scam->login_pending = 1;
  845. scam_generate_deskey(account->pwd, scam->enckey);
  846. scam_generate_deskey(account->pwd, scam->deckey);
  847. scam->enc_xor_offset = 0;
  848. scam->dec_xor_offset = 0;
  849. scam_server_send_caidlist(cl);
  850. scam_server_send_serverversion(cl);
  851. }
  852. static void scam_server_send_dcw(struct s_client *cl, ECM_REQUEST *er)
  853. {
  854. uint8_t mbuf[31];
  855. uint32_t i = 0;
  856. if(!(er->rc < E_NOTFOUND))
  857. {
  858. return;
  859. }
  860. mbuf[i++] = 0x63; // dcw data type
  861. mbuf[i++] = 0x1D; // fixed sized < 127
  862. i2b_buf(4, er->ens, mbuf + i); i += 4;
  863. i2b_buf(2, er->tsid, mbuf + i); i += 2;
  864. i2b_buf(2, er->onid, mbuf + i); i += 2;
  865. i2b_buf(2, er->srvid, mbuf + i); i += 2;
  866. mbuf[i++] = 0x20; // unknown
  867. mbuf[i++] = 0x00; // unknown
  868. mbuf[i++] = 0x81; // unknown
  869. memcpy(mbuf + i, er->cw, 16);
  870. scam_send(cl, mbuf, 31);
  871. }
  872. static void *scam_server_handle(struct s_client *cl, uint8_t *buf, int32_t n)
  873. {
  874. uint32_t pos = 0, packetLength = 0, packetOffset = 0, dataLength = 0, dataOffset = 0;
  875. struct s_auth *account;
  876. struct scam_data *scam;
  877. if(n < 3)
  878. { return NULL; }
  879. if(!cl->init_done)
  880. {
  881. if(!scam_server_authip_client(cl)) { return NULL; }
  882. if(cl->scam)
  883. {
  884. memset(cl->scam, 0, sizeof(struct scam_data));
  885. }
  886. if(cl->scam == NULL && !cs_malloc(&cl->scam, sizeof(struct scam_data)))
  887. {
  888. return NULL;
  889. }
  890. cl->init_done = 1;
  891. }
  892. scam = cl->scam;
  893. if(scam == NULL)
  894. {
  895. return NULL;
  896. }
  897. scam_decode_length(buf, &packetLength, &packetOffset);
  898. pos += packetOffset;
  899. if(scam->login_pending && packetLength > 1 && (buf[pos] != 0x10 || buf[pos + 1] != 0x02))
  900. {
  901. scam->login_pending = 0;
  902. cs_auth_client(cl, (struct s_auth *)0, NULL);
  903. cs_disconnect_client(cl);
  904. return NULL;
  905. }
  906. if((pos + 2 < (uint32_t)n) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)n))
  907. {
  908. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  909. }
  910. else
  911. {
  912. return NULL;
  913. }
  914. while(pos + dataOffset + dataLength - 1 < (uint32_t)n)
  915. {
  916. switch(buf[pos])
  917. {
  918. case 0x10: // checksum
  919. if(dataLength != 2) { break; }
  920. if(b2i(2, &buf[pos + dataOffset]) != ccitt_crc(buf + pos + dataOffset + 2, n - pos - dataOffset - 2, 0xFFFF, 0))
  921. {
  922. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "sent packet with invalid checksum");
  923. return NULL;
  924. }
  925. if(scam->login_pending)
  926. {
  927. for(account = cfg.account; account; account = account->next)
  928. {
  929. if(streq(scam->login_username, account->usr))
  930. {
  931. scam->login_pending = 0;
  932. if(!cs_auth_client(cl, account, NULL))
  933. {
  934. cs_log("scam client login: %s version: %d", scam->login_username, scam->version);
  935. }
  936. else
  937. {
  938. cs_disconnect_client(cl);
  939. }
  940. break;
  941. }
  942. }
  943. if(scam->login_pending)
  944. {
  945. scam->login_pending = 0;
  946. cs_auth_client(cl, (struct s_auth *)0, NULL);
  947. cs_disconnect_client(cl);
  948. return NULL;
  949. }
  950. }
  951. break;
  952. case 0x46: // client auth
  953. scam_server_recv_auth(cl, buf + pos + dataOffset, dataLength);
  954. break;
  955. case 0x24: // ecm request
  956. scam_server_recv_ecm(cl, buf + pos + dataOffset, dataLength);
  957. break;
  958. case 0x7F: // padding
  959. break;
  960. default:
  961. cs_log_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, "sent unknown scam client packet %X", buf[pos]);
  962. break;
  963. }
  964. pos += dataOffset + dataLength;
  965. if((pos + 2 < (uint32_t)n) && (pos + 1 + scam_get_length_data_length(buf + pos) < (uint32_t)n))
  966. {
  967. scam_decode_length(buf + pos, &dataLength, &dataOffset);
  968. }
  969. else
  970. {
  971. break;
  972. }
  973. }
  974. return NULL;
  975. }
  976. void scam_cleanup(struct s_client *cl)
  977. {
  978. NULLFREE(cl->scam);
  979. }
  980. void module_scam(struct s_module *ph)
  981. {
  982. ph->desc = "scam";
  983. ph->type = MOD_CONN_TCP;
  984. ph->listenertype = LIS_SCAM;
  985. ph->num = R_SCAM;
  986. ph->large_ecm_support = 1;
  987. IP_ASSIGN(ph->s_ip, cfg.scam_srvip);
  988. ph->ptab.nports = 1;
  989. ph->ptab.ports[0].s_port = cfg.scam_port;
  990. // server + client
  991. ph->recv = scam_recv;
  992. ph->cleanup = scam_cleanup;
  993. // server
  994. ph->s_init = scam_server_init;
  995. ph->s_handler = scam_server_handle;
  996. ph->send_dcw = scam_server_send_dcw;
  997. // client
  998. ph->c_init = scam_client_init;
  999. ph->c_idle = scam_client_idle;
  1000. ph->c_recv_chk = scam_client_handle;
  1001. ph->c_send_ecm = scam_client_send_ecm;
  1002. }
  1003. #endif