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
); }
42 if (ack
== PEER_AU_READY
)
43 { cs_log("<- send ACCEPT REMM msg to peer %04X for caid: %04X", peer
->gbox
.id
, caid
); }
44 if (ack
== PEER_AU_UNREADY
)
45 { cs_log("<- send WARNING to peer %04X: my dvbapi unready for AU caid: %04X", peer
->gbox
.id
, caid
); }
49 static void gbox_recvd_remm_ack_msg(struct s_client
*cli
, uchar
*buf
, int32_t n
)
51 if (!cli
|| !cli
->gbox
|| !buf
|| n
!= 27) { return; }
52 struct gbox_peer
*peer
;
55 uint8_t ack
= buf
[15];
56 uint8_t dvbapi_stat
= buf
[16];
57 uint16_t rpeer
= b2i(2, buf
+11);
58 uint16_t rcaid
= b2i(2, buf
+17);
59 //uint32_t rprovid = b2i(4, buf +19);
62 if (ack
== PEER_AU_BLOCKED
)
63 { cs_log("-> Peer %04X %s rejected REMM for caid %04X - requesting peer %04X blocked", peer
->gbox
.id
, cli
->reader
->label
, rcaid
, rpeer
); }
64 if (ack
== PEER_AU_READY
)
65 { cs_log("-> MSG from peer %04X %s: Accept REMM REQ for caid %04X", peer
->gbox
.id
, cli
->reader
->label
, rcaid
); }
66 if (ack
== PEER_AU_UNREADY
)
68 cs_log("-> WARNING: Peer %04X %s dvbapi AU unready for caid %04X", peer
->gbox
.id
, cli
->reader
->label
, rcaid
);
69 cs_log_dbg(D_EMM
," Peer %04X dvbapi AU status: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",
70 peer
->gbox
.id
, (dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
74 static uint8_t check_dvbapi_au_ready( void)
78 uint8_t dvbapi_stat
= 0;
79 if (module_dvbapi_enabled())
85 cs_readlock(__func__
, &clientlist_lock
);
86 for(cl
= first_client
; cl
; cl
= cl
->next
)
88 if(cl
->typ
== 'c' && cl
->account
&& is_dvbapi_usr(cl
->account
->usr
))
90 if(cl
->account
->autoau
)
95 if(ll_count(cl
->account
->aureader_list
))
102 cs_readunlock(__func__
, &clientlist_lock
);
110 static int8_t check_valid_remm_peer(uint16_t peer_id
)
112 if (cfg
.accept_remm_peer_num
> 0)
115 for (i
= 0; i
< cfg
.accept_remm_peer_num
; i
++)
117 if (cfg
.accept_remm_peer
[i
] == peer_id
)
124 static void gbox_recvd_remm_req(struct s_client
*cli
, uchar
*buf
, int32_t n
)
126 if (!cli
|| !cli
->gbox
|| !buf
|| !cli
->reader
|| n
!= 122) { return; }
128 struct gbox_peer
*peer
;
131 uint16_t rcaid
= b2i(2, buf
+23);
132 uint32_t rprovid
= b2i(4, buf
+17);
133 //uint16_t tcli_peer = b2i(2, buf +11);
134 //uint16_t tsrv_peer = b2i(2, buf +13);
136 uint8_t dvbapi_stat
= check_dvbapi_au_ready();
138 if (!check_valid_remm_peer( peer
->gbox
.id
))
140 gbox_send_remm_ack_msg(cli
, rcaid
, rprovid
, dvbapi_stat
, PEER_AU_BLOCKED
);
141 handle_attack(cli
, GBOX_ATTACK_REMM_REQ_BLOCKED
, peer
->gbox
.id
);
142 cs_log("Reject REMM REQ for caid %04X) - peer %04X blocked for AU", rcaid
, peer
->gbox
.id
);
147 if (tcli_peer != local_gbox.id)
148 { forward remm req to target client peer}
150 struct s_reader
*rdr
= cli
->reader
;
151 rdr
->last_g
= time(NULL
); // last receive is now
153 rdr
->auprovid
= rprovid
;
156 memcpy(rdr
->hexserial
, buf
+29, 6);
157 rdr
->hexserial
[6] = 0;
158 rdr
->hexserial
[7] = 0;
159 rdr
->nprov
= buf
[37];
162 for(i
= 0; i
< rdr
->nprov
; i
++)
164 if(caid_is_betacrypt(rdr
->caid
) || caid_is_irdeto(rdr
->caid
))
166 rdr
->prid
[i
][0] = buf
[38 + (i
* 5)];
167 memcpy(&rdr
->prid
[i
][1], &buf
[40 + (i
* 5)], 3);
171 rdr
->prid
[i
][2] = buf
[38 + (i
* 5)];
172 rdr
->prid
[i
][3] = buf
[39 + (i
* 5)];
173 memcpy(&rdr
->sa
[i
][0], &buf
[40 + (i
* 5)], 4);
178 rdr
->blockemm
|= (buf
[118] == 1) ? 0 : EMM_GLOBAL
;
179 rdr
->blockemm
|= (buf
[119] == 1) ? 0 : EMM_SHARED
;
180 rdr
->blockemm
|= (buf
[120] == 1) ? 0 : EMM_UNIQUE
;
181 rdr
->blockemm
|= (buf
[121] == 1) ? 0 : EMM_UNKNOWN
;
183 cs_log("-> REMM REQ for caid %04X from peer %04X:%s", rdr
->caid
, peer
->gbox
.id
, rdr
->label
);
185 if (dvbapi_stat
== 3 || dvbapi_stat
== 5)
187 gbox_send_remm_ack_msg(cli
, rdr
->caid
, rdr
->auprovid
, dvbapi_stat
, PEER_AU_READY
);
188 cs_log_dbg(D_EMM
,"my dvbapi ready for AU: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",(dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
192 gbox_send_remm_ack_msg(cli
, rdr
->caid
, rdr
->auprovid
, dvbapi_stat
, PEER_AU_UNREADY
);
193 cs_log_dbg(D_EMM
,"dvbapi status: dvbapi_au: %1d - dvbapi_usr_autoau: %1d - dvbapi_usr_aulist: %1d",(dvbapi_stat
& 1) ? 1 : 0, (dvbapi_stat
& 2) ? 1 : 0, (dvbapi_stat
& 4) ? 1 : 0 );
198 static void gbox_recvd_remm_data(struct s_client
*cli
, uchar
*buf
, int32_t buflen
, int32_t emmlen
)
200 if(!cli
|| !cli
->gbox
|| !buf
|| buflen
< 30 || emmlen
+27 > buflen
|| emmlen
< 3 || emmlen
+ 27 > MAX_EMM_SIZE
)
203 struct gbox_peer
*peer
;
206 uint16_t rcaid
= b2i(2, buf
+ 15);
207 uint32_t recvd_remm_crc
= b2i(4, buf
+ 23);
208 uint32_t calc_remm_crc
= gbox_get_checksum(&buf
[0] +27, emmlen
);
209 cs_log_dbg(D_EMM
,"received remm from peer: %04X caid: %04X (remm_crc = %08X - calc_remm_crc = %08X)",
210 peer
->gbox
.id
, rcaid
, recvd_remm_crc
, calc_remm_crc
);
211 if(recvd_remm_crc
== calc_remm_crc
)
214 memset(&remm
, 0, sizeof(remm
));
215 remm
.emmlen
= emmlen
;
216 memcpy(remm
.caid
, buf
+15, 2);
217 memcpy(remm
.provid
, buf
+17 , 4);
218 memcpy(remm
.emm
, buf
+27, remm
.emmlen
);
219 do_emm(cur_client(), &remm
);
222 { cs_log_dbg(D_EMM
,"reject received REMM from peer %04X caid: %04X - crc failed - %08X != %08X", peer
->gbox
.id
, rcaid
, recvd_remm_crc
, calc_remm_crc
); }
227 void gbox_recvd_remm_cmd_switch(struct s_client
*cli
, uchar
*buf
, int32_t n
)
229 if (!cli
|| !cli
->gbox
|| !buf
|| n
< 26) { return; }
230 struct gbox_peer
*peer
;
233 uint8_t cmd_id
= buf
[10];
238 cs_log_dbg(D_EMM
,"-> Incoming REMM request (%d bytes) from %04X %s - %s", n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
239 gbox_recvd_remm_req(cli
, buf
, n
);
241 case MSGID_REMM_DATA
:
242 cs_log_dbg(D_EMM
,"-> Incoming gbox remote EMM data (%d bytes total - %d bytes emm-len) from %04X %s - %s", n
,
243 buf
[21], peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
244 gbox_recvd_remm_data(cli
, buf
, n
, buf
[21]); //buf[21]) = emm lenght
247 cs_log_dbg(D_EMM
,"-> Incoming REMM ACK (%d bytes) from %04X %s - %s", n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
248 gbox_recvd_remm_ack_msg(cli
, buf
, n
);
251 cs_log("received unknown remm cmd_id: %d %d bytes from %04X %s - %s", cmd_id
, n
, peer
->gbox
.id
, username(cli
), cli
->reader
->device
);
256 void gbox_send_remm_req(struct s_client
*cli
, ECM_REQUEST
*er
)
258 if (!cli
|| !cli
->gbox
|| !er
) { return; }
261 struct s_client
*cl
= cur_client();
262 struct gbox_peer
*peer
= cli
->gbox
;
263 struct s_reader
*aureader
= NULL
, *rdr
= NULL
;
265 if(er
->selected_reader
&& !er
->selected_reader
->audisabled
&& ll_contains(cl
->aureader_list
, er
->selected_reader
))
266 { aureader
= er
->selected_reader
; }
268 if(!aureader
&& cl
->aureader_list
)
270 LL_ITER itr
= ll_iter_create(cl
->aureader_list
);
271 while((rdr
= ll_iter_next(&itr
)))
273 if(emm_reader_match(rdr
, er
->caid
, er
->prid
))
284 uint16_t au_caid
= aureader
->caid
;
286 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.
287 { au_caid
= er
->caid
; }
289 if(cl
->lastcaid
!= er
->caid
)
290 { cl
->disable_counter
= 0; }
292 cl
->lastcaid
= er
->caid
;
293 cl
->disable_counter
++;
295 if (cl
->disable_counter
< 6) //delay 5 ecm
298 if(!memcmp(cl
->lastserial
, aureader
->hexserial
, 8))
300 cl
->disable_counter
= 0;
304 memcpy(cl
->lastserial
, aureader
->hexserial
, 8);
307 { cl
->disable_counter
= 0; }
311 memset(mbuf
, 0, sizeof(mbuf
));
313 uint16_t local_gbox_id
= gbox_get_local_gbox_id();
314 uint32_t local_gbox_pw
= gbox_get_local_gbox_password();
316 gbox_message_header(mbuf
, MSG_REM_EMM
, peer
->gbox
.password
, local_gbox_pw
);
317 mbuf
[10] = MSGID_REMM_REQ
;
318 i2b_buf(2, peer
->gbox
.id
, mbuf
+ 11);
319 i2b_buf(2, local_gbox_id
, mbuf
+ 13);
320 i2b_buf(2, er
->srvid
, mbuf
+ 15);
322 //override emm provid with auprovid if set in server reader config
323 if(aureader
->auprovid
)
325 if(aureader
->auprovid
!= er
->prid
)
326 { i2b_buf(4, aureader
->auprovid
, mbuf
+17); }
328 { i2b_buf(4, er
->prid
, mbuf
+17); }
331 { i2b_buf(4, er
->prid
, mbuf
+17); }
333 i2b_buf(2, er
->pid
, mbuf
+21);
334 i2b_buf(2, au_caid
, mbuf
+23);
335 memcpy(mbuf
+29, aureader
->hexserial
, 6); // serial 6 bytes
336 mbuf
[37] = aureader
->nprov
;
338 for(i
= 0; i
< aureader
->nprov
; i
++)
340 if(caid_is_betacrypt(au_caid
) || caid_is_irdeto(au_caid
))
342 mbuf
[38 + (i
* 5)] = aureader
->prid
[i
][0];
343 memcpy(&mbuf
[40 + (i
* 5)], &aureader
->prid
[i
][1], 3);
347 mbuf
[38 + (i
* 5)] = aureader
->prid
[i
][2];
348 mbuf
[39 + (i
* 5)] = aureader
->prid
[i
][3];
349 memcpy(&mbuf
[40 + (i
* 5)], &aureader
->sa
[i
][0], 4); // for conax we need at least 4 Bytes
351 if(i
>= 15) { break; }
354 mbuf
[118] = 0; //(aureader->blockemm & EMM_GLOBAL && !(aureader->saveemm & EMM_GLOBAL)) ? 0 : 1;
355 mbuf
[119] = (aureader
->blockemm
& EMM_SHARED
&& !(aureader
->saveemm
& EMM_SHARED
)) ? 0 : 1;
356 mbuf
[120] = (aureader
->blockemm
& EMM_UNIQUE
&& !(aureader
->saveemm
& EMM_UNIQUE
)) ? 0 : 1;
357 mbuf
[121] = (aureader
->blockemm
& EMM_UNKNOWN
&& !(aureader
->saveemm
& EMM_UNKNOWN
)) ? 0 : 1;
359 cs_log("<- send REMM REQ to %s peer-id %04X for reader=%s, caid=%04X, auprovid=%06X",
360 username(cur_client()), peer
->gbox
.id
, aureader
->label
, au_caid
,
361 aureader
->auprovid
? aureader
->auprovid
: b2i(4, aureader
->prid
[0]));
362 cs_log_dump_dbg(D_EMM
, mbuf
, 122, "<- send remm request, (data_len=%d):", 122);
363 gbox_send(cli
, mbuf
, 122);
367 int32_t gbox_send_remm_data(EMM_PACKET
*ep
)
370 struct s_client
*cli
= cur_client();
371 struct gbox_peer
*peer
= cli
->gbox
;
373 if(!cli
->gbox
|| !cli
->reader
->tcp_connected
|| !ep
)
376 if(!cs_malloc(&buf
, ep
->emmlen
+27 +15))
380 memset(buf
+27, 0xff, ep
->emmlen
+ 15);
382 uint32_t remm_crc
= gbox_get_checksum(&ep
->emm
[0], ep
->emmlen
);
383 uint16_t local_gbox_id
= gbox_get_local_gbox_id();
384 uint32_t local_gbox_pw
= gbox_get_local_gbox_password();
386 gbox_message_header(buf
, MSG_REM_EMM
, peer
->gbox
.password
, local_gbox_pw
);
387 buf
[10] = MSGID_REMM_DATA
;
388 i2b_buf(2, peer
->gbox
.id
, buf
+11);
389 i2b_buf(2, local_gbox_id
, buf
+13);
390 memcpy(buf
+15, ep
->caid
, 2);
391 memcpy(buf
+17, ep
->provid
, 4);
392 buf
[21] = ep
->emmlen
;
393 i2b_buf(4, remm_crc
, buf
+23);
394 memcpy(buf
+27, ep
->emm
, ep
->emmlen
);
395 cs_log("<- send remm to: %s peer: %04X emmlength: %d crc: %08X",username(cur_client()), peer
->gbox
.id
, ep
->emmlen
, remm_crc
);
396 cs_log_dump_dbg(D_EMM
, buf
, 27 + ep
->emmlen
, "<- gbox send emm, (data-len=%d):", 27 + ep
->emmlen
);
397 gbox_send(cli
, buf
, 27 + ep
->emmlen
);