1 #define MODULE_LOG_PREFIX "gbox/remm"
6 #include "module-gbox-remm.h"
7 #include "module-gbox.h"
8 #include "module-gbox-helper.h"
9 #include "oscam-string.h"
10 #include "oscam-client.h"
11 #include "oscam-lock.h"
12 #include "oscam-time.h"
13 #include "oscam-reader.h"
14 #include "oscam-files.h"
15 #include "module-dvbapi.h"
16 #include "oscam-emm.h"
18 static void gbox_send_remm_ack_msg(struct s_client
*cli
, uint16_t caid
, uint32_t provider
, uint8_t dvbapi_stat
, uint8_t ack
)
21 struct gbox_peer
*peer
= cli
->gbox
;
22 uint16_t local_gbox_id
= gbox_get_local_gbox_id();
23 uint32_t local_gbox_pw
= gbox_get_local_gbox_password();
25 gbox_message_header(outbuf
, MSG_REM_EMM
, peer
->gbox
.password
, local_gbox_pw
);
26 outbuf
[10] = MSGID_REMM_ACK
;
27 i2b_buf(2, peer
->gbox
.id
, outbuf
+11);
28 i2b_buf(2, local_gbox_id
, outbuf
+ 13);
30 outbuf
[16] = dvbapi_stat
;
31 i2b_buf(2, caid
, outbuf
+17);
32 i2b_buf(4, provider
, outbuf
+19);
38 gbox_send(cli
, outbuf
, 27);
40 if (ack
== PEER_AU_BLOCKED
)
41 { cs_log("<- send REJECT REMM msg to peer %04X for caid: %04X", peer
->gbox
.id
, caid
); }
43 if (ack
== PEER_AU_READY
)
44 { cs_log("<- send ACCEPT REMM msg to peer %04X for caid: %04X", peer
->gbox
.id
, caid
); }
46 if (ack
== PEER_AU_UNREADY
)
47 { cs_log("<- send WARNING to peer %04X: my dvbapi unready for AU caid: %04X", peer
->gbox
.id
, caid
); }
52 static void gbox_recvd_remm_ack_msg(struct s_client
*cli
, uint8_t *buf
, int32_t n
)
54 if (!cli
|| !cli
->gbox
|| !buf
|| n
!= 27) { return; }
55 struct gbox_peer
*peer
;
58 uint8_t ack
= buf
[15];
59 uint8_t dvbapi_stat
= buf
[16];
60 uint16_t rpeer
= b2i(2, buf
+11);
61 uint16_t rcaid
= b2i(2, buf
+17);
62 //uint32_t rprovid = b2i(4, buf +19);
64 if (ack
== PEER_AU_BLOCKED
)
65 { cs_log("-> Peer %04X %s rejected REMM for caid %04X - requesting peer %04X blocked", peer
->gbox
.id
, cli
->reader
->label
, rcaid
, rpeer
); }
67 if (ack
== PEER_AU_READY
)
68 { cs_log("-> MSG from peer %04X %s: Accept REMM REQ for caid %04X", peer
->gbox
.id
, cli
->reader
->label
, rcaid
); }
70 if (ack
== PEER_AU_UNREADY
)
72 cs_log("-> WARNING: Peer %04X %s dvbapi AU unready for caid %04X", peer
->gbox
.id
, cli
->reader
->label
, rcaid
);
73 cs_log_dbg(D_EMM
,"Peer %04X dvbapi AU status: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",
74 peer
->gbox
.id
, (dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
78 static uint8_t check_dvbapi_au_ready( void)
81 uint8_t dvbapi_stat
= 0;
82 if (module_dvbapi_enabled())
88 cs_readlock(__func__
, &clientlist_lock
);
90 for(cl
= first_client
; cl
; cl
= cl
->next
)
92 if(cl
->typ
== 'c' && cl
->account
&& is_dvbapi_usr(cl
->account
->usr
))
94 if(cl
->account
->autoau
)
100 if(ll_count(cl
->account
->aureader_list
))
107 cs_readunlock(__func__
, &clientlist_lock
);
115 uint8_t check_valid_remm_peer(uint16_t peer_id
)
117 if (cfg
.accept_remm_peer_num
> 0)
120 for (i
= 0; i
< cfg
.accept_remm_peer_num
; i
++)
122 if (cfg
.accept_remm_peer
[i
] == peer_id
)
129 static void gbox_recvd_remm_req(struct s_client
*cli
, uint8_t *buf
, int32_t n
)
131 if (!cli
|| !cli
->gbox
|| !buf
|| !cli
->reader
|| n
!= 122) { return; }
133 struct gbox_peer
*peer
;
136 uint16_t rcaid
= b2i(2, buf
+23);
137 uint32_t rprovid
= b2i(4, buf
+17);
138 //uint16_t tcli_peer = b2i(2, buf +11);
139 //uint16_t tsrv_peer = b2i(2, buf +13);
141 uint8_t dvbapi_stat
= check_dvbapi_au_ready();
143 if (!check_valid_remm_peer( peer
->gbox
.id
))
145 gbox_send_remm_ack_msg(cli
, rcaid
, rprovid
, dvbapi_stat
, PEER_AU_BLOCKED
);
146 handle_attack(cli
, GBOX_ATTACK_REMM_REQ_BLOCKED
, peer
->gbox
.id
);
147 cs_log("Reject REMM REQ for caid %04X) - peer %04X blocked for AU", rcaid
, peer
->gbox
.id
);
151 //if (tcli_peer != local_gbox.id)
152 // { forward remm req to target client peer}
154 struct s_reader
*rdr
= cli
->reader
;
155 rdr
->gbox_remm_peer
= peer
->gbox
.id
;
156 rdr
->last_g
= time(NULL
); // last receive is now
158 rdr
->auprovid
= rprovid
;
161 memcpy(rdr
->hexserial
, buf
+ 29, 6);
162 rdr
->hexserial
[6] = 0;
163 rdr
->hexserial
[7] = 0;
164 rdr
->nprov
= buf
[37];
167 for(i
= 0; i
< rdr
->nprov
; i
++)
169 if(caid_is_betacrypt(rdr
->caid
) || caid_is_irdeto(rdr
->caid
))
171 rdr
->prid
[i
][0] = buf
[38 + (i
* 5)];
172 memcpy(&rdr
->prid
[i
][1], &buf
[40 + (i
* 5)], 3);
176 rdr
->prid
[i
][2] = buf
[38 + (i
* 5)];
177 rdr
->prid
[i
][3] = buf
[39 + (i
* 5)];
178 memcpy(&rdr
->sa
[i
][0], &buf
[40 + (i
* 5)], 4);
183 rdr
->blockemm
|= (buf
[117] == 1) ? 0 : 0x80; // remm marker bit
184 rdr
->blockemm
|= (buf
[118] == 1) ? 0 : EMM_GLOBAL
;
185 rdr
->blockemm
|= (buf
[119] == 1) ? 0 : EMM_SHARED
;
186 rdr
->blockemm
|= (buf
[120] == 1) ? 0 : EMM_UNIQUE
;
187 rdr
->blockemm
|= (buf
[121] == 1) ? 0 : EMM_UNKNOWN
;
189 cs_log("-> received REMM REQ for type %s%s%s%s caid %04X from peer %04X:%s",
190 buf
[120]==1 ? "UQ ":"", buf
[119]==1 ? "SH ":"", buf
[118]==1 ? "GL ":"", buf
[121]==1 ? "UK":"",
191 rdr
->caid
, peer
->gbox
.id
, rdr
->label
);
193 if (dvbapi_stat
== 3 || dvbapi_stat
== 5)
195 gbox_send_remm_ack_msg(cli
, rdr
->caid
, rdr
->auprovid
, dvbapi_stat
, PEER_AU_READY
);
196 cs_log_dbg(D_EMM
,"my dvbapi ready for AU: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",
197 (dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
201 gbox_send_remm_ack_msg(cli
, rdr
->caid
, rdr
->auprovid
, dvbapi_stat
, PEER_AU_UNREADY
);
202 cs_log_dbg(D_EMM
,"dvbapi status: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",
203 (dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
205 write_msg_info(cli
, MSGID_REMM
, 0, 1);
208 static void gbox_recvd_remm_data(struct s_client
*cli
, uint8_t *buf
, int32_t buflen
, int32_t emmlen
)
210 if(!cli
|| !cli
->gbox
|| !buf
|| buflen
< 30 || emmlen
+27 > buflen
|| emmlen
< 3 || emmlen
+ 27 > MAX_EMM_SIZE
)
213 struct gbox_peer
*peer
;
216 uint16_t rcaid
= b2i(2, buf
+ 15);
217 uint32_t recvd_remm_crc
= b2i(4, buf
+ 23);
218 uint32_t calc_remm_crc
= gbox_get_checksum(&buf
[0] +27, emmlen
);
219 cs_log_dbg(D_EMM
,"received remm from peer: %04X caid: %04X (remm_crc = %08X - calc_remm_crc = %08X)",
220 peer
->gbox
.id
, rcaid
, recvd_remm_crc
, calc_remm_crc
);
222 if(recvd_remm_crc
== calc_remm_crc
)
225 memset(&remm
, 0, sizeof(remm
));
226 remm
.emmlen
= emmlen
;
227 memcpy(remm
.caid
, buf
+15, 2);
228 memcpy(remm
.provid
, buf
+17 , 4);
229 memcpy(remm
.emm
, buf
+27, remm
.emmlen
);
230 do_emm(cur_client(), &remm
);
234 cs_log_dbg(D_EMM
,"reject received REMM from peer %04X caid: %04X - crc failed - %08X != %08X",
235 peer
->gbox
.id
, rcaid
, recvd_remm_crc
, calc_remm_crc
);
241 void gbox_recvd_remm_cmd_switch(struct s_client
*cli
, uint8_t *buf
, int32_t n
)
243 if (!cli
|| !cli
->gbox
|| !buf
|| n
< 26) { return; }
245 struct gbox_peer
*peer
;
247 uint8_t cmd_id
= buf
[10];
252 cs_log_dbg(D_EMM
,"-> Incoming REMM request (%d bytes) from %04X %s - %s",
253 n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
254 gbox_recvd_remm_req(cli
, buf
, n
);
257 case MSGID_REMM_DATA
:
258 cs_log_dbg(D_EMM
,"-> Incoming gbox remote EMM data (%d bytes total - %d bytes emm-len) from %04X %s - %s",
259 n
, buf
[21], peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
260 gbox_recvd_remm_data(cli
, buf
, n
, buf
[21]); // buf[21]) = emm length
264 cs_log_dbg(D_EMM
,"-> Incoming REMM ACK (%d bytes) from %04X %s - %s",
265 n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
266 gbox_recvd_remm_ack_msg(cli
, buf
, n
);
270 cs_log("received unknown remm cmd_id: %d %d bytes from %04X %s - %s",
271 cmd_id
, n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
276 void gbox_send_remm_req(struct s_client
*cli
, ECM_REQUEST
*er
)
278 if (!cli
|| !cli
->gbox
|| !er
) { return; }
281 struct s_client
*cl
= cur_client();
282 struct gbox_peer
*peer
= cli
->gbox
;
283 struct s_reader
*aureader
= NULL
, *rdr
= NULL
;
285 if(er
->selected_reader
&& !er
->selected_reader
->audisabled
&& ll_contains(cl
->aureader_list
, er
->selected_reader
))
286 { aureader
= er
->selected_reader
; }
288 if(!aureader
&& cl
->aureader_list
)
290 LL_ITER itr
= ll_iter_create(cl
->aureader_list
);
291 while((rdr
= ll_iter_next(&itr
)))
293 if(emm_reader_match(rdr
, er
->caid
, er
->prid
))
304 uint16_t au_caid
= aureader
->caid
;
306 if(!au_caid
&& caid_is_bulcrypt(er
->caid
)) // Bulcrypt has 2 caids and aureader->caid can't be used. Use ECM_REQUEST caid for AU.
307 { au_caid
= er
->caid
; }
309 if(cl
->lastcaid
!= er
->caid
)
310 { cl
->disable_counter
= 0; }
312 cl
->lastcaid
= er
->caid
;
313 cl
->disable_counter
++;
315 if (!cli
->reader
->gbox_force_remm
&& cl
->disable_counter
< 6) // delay 6 ecm
318 if(!memcmp(cl
->lastserial
, aureader
->hexserial
, 8))
320 cl
->disable_counter
= 0;
324 memcpy(cl
->lastserial
, aureader
->hexserial
, 8);
327 { cl
->disable_counter
= 0; }
331 uint8_t total_ent
= 0;
332 uint8_t active_ent
= 0;
334 if(aureader
->ll_entitlements
) // check for active entitlements
336 time_t now
= time((time_t *)0);
337 LL_ITER itr
= ll_iter_create(aureader
->ll_entitlements
);
340 while((ent
= ll_iter_next(&itr
)))
343 if((ent
->end
> now
) && (ent
->type
!= 7))
348 //cs_log("AU card %s: Total entitlements: %d - active entitlements: %d", aureader->label, total_ent, active_ent);
351 if(total_ent
&& cli
->reader
->gbox_force_remm
)
353 if(active_ent
>= cli
->reader
->gbox_force_remm
)
355 cs_log("WARNING: Card '%s' got %d active entitlements - consider to disable 'force_remm'", aureader
->label
, active_ent
);
359 memset(mbuf
, 0, sizeof(mbuf
));
361 uint16_t local_gbox_id
= gbox_get_local_gbox_id();
362 uint32_t local_gbox_pw
= gbox_get_local_gbox_password();
364 gbox_message_header(mbuf
, MSG_REM_EMM
, peer
->gbox
.password
, local_gbox_pw
);
365 mbuf
[10] = MSGID_REMM_REQ
;
366 i2b_buf(2, peer
->gbox
.id
, mbuf
+ 11);
367 i2b_buf(2, local_gbox_id
, mbuf
+ 13);
368 i2b_buf(2, er
->srvid
, mbuf
+ 15);
370 // override emm provid with auprovid if set in server reader config
371 if(aureader
->auprovid
)
373 if(aureader
->auprovid
!= er
->prid
)
374 { i2b_buf(4, aureader
->auprovid
, mbuf
+17); }
376 { i2b_buf(4, er
->prid
, mbuf
+17); }
380 i2b_buf(4, er
->prid
, mbuf
+17);
383 i2b_buf(2, er
->pid
, mbuf
+21);
384 i2b_buf(2, au_caid
, mbuf
+23);
386 memcpy(mbuf
+29, aureader
->hexserial
, 6); // serial 6 bytes
387 mbuf
[37] = aureader
->nprov
;
389 for(i
= 0; i
< aureader
->nprov
; i
++)
391 if(caid_is_betacrypt(au_caid
) || caid_is_irdeto(au_caid
))
393 mbuf
[38 + (i
* 5)] = aureader
->prid
[i
][0];
394 memcpy(&mbuf
[40 + (i
* 5)], &aureader
->prid
[i
][1], 3);
398 mbuf
[38 + (i
* 5)] = aureader
->prid
[i
][2];
399 mbuf
[39 + (i
* 5)] = aureader
->prid
[i
][3];
400 memcpy(&mbuf
[40 + (i
* 5)], &aureader
->sa
[i
][0], 4); // for conax we need at least 4 Bytes
402 if(i
>= 15) { break; }
405 mbuf
[117] = aureader
->blockemm
| 0x80; // set remm marker bit
407 if(au_caid
== 0x0D96 || au_caid
== 0x0D98 ) // these caids needs globals
408 { mbuf
[118] = (aureader
->blockemm
& EMM_GLOBAL
&& !(aureader
->saveemm
& EMM_GLOBAL
)) ? 0 : 1; }
412 mbuf
[119] = (aureader
->blockemm
& EMM_SHARED
&& !(aureader
->saveemm
& EMM_SHARED
)) ? 0 : 1;
413 mbuf
[120] = (aureader
->blockemm
& EMM_UNIQUE
&& !(aureader
->saveemm
& EMM_UNIQUE
)) ? 0 : 1;
414 mbuf
[121] = (aureader
->blockemm
& EMM_UNKNOWN
&& !(aureader
->saveemm
& EMM_UNKNOWN
)) ? 0 : 1;
416 cs_log("<- %04X sends REMM REQ for type = %s%s%s%s to %s peer-id=%04X for reader=%s, caid=%04X", local_gbox_id
,
417 mbuf
[120] == 1 ? "UQ " : "", mbuf
[119] == 1 ? "SH " : "", mbuf
[118] == 1 ? "GL " : "", mbuf
[121] == 1 ? "UK" : "",
418 username(cur_client()), peer
->gbox
.id
, aureader
->label
, au_caid
);
420 cs_log_dump_dbg(D_EMM
, mbuf
, 122, "<- send remm request, (data_len=%d):", 122);
421 gbox_send(cli
, mbuf
, 122);
425 int32_t gbox_send_remm_data(EMM_PACKET
*ep
)
427 struct s_client
*cli
= cur_client();
428 struct gbox_peer
*peer
= cli
->gbox
;
430 if(!cli
->gbox
|| !cli
->reader
->tcp_connected
|| !ep
|| !cli
->reader
->gbox_remm_peer
)
433 uint32_t remm_crc
= gbox_get_checksum(&ep
->emm
[0], ep
->emmlen
);
435 if(remm_crc
== peer
->last_remm_crc
)
438 peer
->last_remm_crc
= remm_crc
;
442 if(!cs_malloc(&buf
, ep
->emmlen
+27 +15))
446 memset(buf
+27, 0xff, ep
->emmlen
+ 15);
448 uint16_t local_gbox_id
= gbox_get_local_gbox_id();
449 uint32_t local_gbox_pw
= gbox_get_local_gbox_password();
451 gbox_message_header(buf
, MSG_REM_EMM
, peer
->gbox
.password
, local_gbox_pw
);
452 buf
[10] = MSGID_REMM_DATA
;
453 i2b_buf(2, peer
->gbox
.id
, buf
+11);
454 i2b_buf(2, local_gbox_id
, buf
+13);
455 memcpy(buf
+15, ep
->caid
, 2);
456 memcpy(buf
+17, ep
->provid
, 4);
457 buf
[21] = ep
->emmlen
;
458 i2b_buf(4, remm_crc
, buf
+23);
459 memcpy(buf
+27, ep
->emm
, ep
->emmlen
);
460 cs_log("<- send remm to: %s peer: %04X emmlength: %d crc: %08X",
461 username(cur_client()), peer
->gbox
.id
, ep
->emmlen
, remm_crc
);
462 cs_log_dump_dbg(D_EMM
, buf
, 27 + ep
->emmlen
, "<- gbox send emm, (data-len=%d):", 27 + ep
->emmlen
);
463 gbox_send(cli
, buf
, 27 + ep
->emmlen
);