1 #define MODULE_LOG_PREFIX "client"
5 #include "cscrypt/md5.h"
6 #include "module-anticasc.h"
7 #include "module-cccam.h"
8 #include "module-webif.h"
9 #include "oscam-array.h"
10 #include "oscam-conf-chk.h"
11 #include "oscam-client.h"
12 #include "oscam-ecm.h"
13 #include "oscam-failban.h"
14 #include "oscam-garbage.h"
15 #include "oscam-lock.h"
16 #include "oscam-net.h"
17 #include "oscam-reader.h"
18 #include "oscam-string.h"
19 #include "oscam-time.h"
20 #include "oscam-work.h"
21 #include "reader-common.h"
22 #include "oscam-chk.h"
24 extern CS_MUTEX_LOCK fakeuser_lock
;
26 static char *processUsername
;
27 static struct s_client
*first_client_hashed
[CS_CLIENT_HASHBUCKETS
]; // Alternative hashed client list
29 /* Gets the unique thread number from the client. Used in monitor and newcamd. */
30 int32_t get_threadnum(struct s_client
*client
)
35 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
37 if(cl
->typ
== client
->typ
)
50 struct s_auth
*get_account_by_name(char *name
)
52 struct s_auth
*account
;
53 for(account
= cfg
.account
; (account
); account
= account
->next
)
55 if(streq(name
, account
->usr
))
63 int8_t is_valid_client(struct s_client
*client
)
66 int32_t bucket
= (uintptr_t)client
/ 16 % CS_CLIENT_HASHBUCKETS
;
68 for(cl
= first_client_hashed
[bucket
]; cl
; cl
= cl
->nexthashed
)
78 const char *remote_txt(void)
80 return cur_client()->typ
== 'c' ? "client" : "remote server";
83 const char *client_get_proto(struct s_client
*cl
)
85 const char *ctyp
= "unknown";
98 ctyp
= reader_get_type_desc(cl
->reader
, 1);
103 ctyp
= "anticascader";
108 if(cccam_client_extended_mode(cl
))
115 ctyp
= get_module(cl
)->desc
;
121 static void cs_fake_client(struct s_client
*client
, char *usr
, int32_t uniq
, IN_ADDR_T ip
)
123 /* Uniq = 1: only one connection per user
125 * Uniq = 2: set (new connected) user only to fake if source
126 * ip is different (e.g. for newcamd clients with
127 * different CAID's -> Ports)
129 * Uniq = 3: only one connection per user, but only the last
130 * login will survive (old mpcs behavior)
132 * Uniq = 4: set user only to fake if source ip is
133 * different, but only the last login will survive
137 struct s_auth
*account
;
138 uint32_t con_count
= 1;
139 cs_writelock(__func__
, &fakeuser_lock
);
141 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
143 account
= cl
->account
;
144 if(cl
!= client
&& cl
->typ
== 'c' && !cl
->dup
&& account
&& streq(account
->usr
, usr
)
145 && uniq
< 5 && ((uniq
% 2) || !IP_EQUAL(cl
->ip
, ip
)))
150 if(con_count
<= account
->max_connections
)
155 if(uniq
== 3 || uniq
== 4)
158 cl
->aureader_list
= NULL
;
159 cs_strncpy(buf
, cs_inet_ntoa(cl
->ip
), sizeof(buf
));
160 cs_log("client(%8lX) duplicate user '%s' from %s (prev %s) set to fake (uniq=%d)",
161 (unsigned long)cl
->thread
, usr
, cs_inet_ntoa(ip
), buf
, uniq
);
163 if(cl
->failban
& BAN_DUPLICATE
)
165 cs_add_violation(cl
, usr
);
170 cs_writeunlock(__func__
, &fakeuser_lock
);
171 cs_sleepms(120); // sleep a bit to prevent against saturation from fast reconnecting clients
173 cs_writelock(__func__
, &fakeuser_lock
);
179 client
->aureader_list
= NULL
;
180 cs_strncpy(buf
, cs_inet_ntoa(ip
), sizeof(buf
));
181 cs_log("client(%8lX) duplicate user '%s' from %s (current %s) set to fake (uniq=%d)",
182 (unsigned long)pthread_self(), usr
, cs_inet_ntoa(cl
->ip
), buf
, uniq
);
184 if(client
->failban
& BAN_DUPLICATE
)
186 cs_add_violation_by_ip(ip
, get_module(client
)->ptab
.ports
[client
->port_idx
].s_port
, usr
);
191 cs_writeunlock(__func__
, &fakeuser_lock
); // we need to unlock here as cs_disconnect_client kills the current thread!
192 cs_sleepms(120); // sleep a bit to prevent against saturation from fast reconnecting clients
193 cs_disconnect_client(client
);
194 cs_writelock(__func__
, &fakeuser_lock
);
200 cs_writeunlock(__func__
, &fakeuser_lock
);
203 /* Resolves the ip of the hostname of the specified account and saves it in account->dynip.
204 If the hostname is not configured, the ip is set to 0. */
205 static void cs_user_resolve(struct s_auth
*account
)
210 IP_ASSIGN(lastip
, account
->dynip
);
211 cs_resolve(account
->dyndns
, &account
->dynip
, NULL
, NULL
);
213 if(!IP_EQUAL(lastip
, account
->dynip
))
215 cs_log("%s: resolved ip=%s", account
->dyndns
, cs_inet_ntoa(account
->dynip
));
220 set_null_ip(&account
->dynip
);
224 /* Returns the username from the client. You will always get a char reference back (no NULLs but it may be string containting "NULL")
225 which you should never modify and not free()! */
226 const char *username(struct s_client
*client
)
228 if(!check_client(client
))
233 if(client
->typ
== 's' || client
->typ
== 'h' || client
->typ
== 'a')
235 return processUsername
? processUsername
: "NULL";
238 if(client
->typ
== 'c' || client
->typ
== 'm')
240 struct s_auth
*acc
= client
->account
;
257 else if(client
->typ
== 'r' || client
->typ
== 'p')
259 struct s_reader
*rdr
= client
->reader
;
269 struct s_client
*create_client(IN_ADDR_T ip
)
272 if(!cs_malloc(&cl
, sizeof(struct s_client
)))
274 cs_log("max connections reached (out of memory) -> reject client %s",
275 IP_ISSET(ip
) ? cs_inet_ntoa(ip
) : "with null address");
281 IP_ASSIGN(cl
->ip
, ip
);
282 cl
->account
= first_client
->account
;
285 SAFE_MUTEX_INIT(&cl
->thread_lock
, NULL
);
286 cl
->login
= cl
->last
= time(NULL
);
287 cl
->tid
= (uint32_t)rand();
289 //Now add new client to the list:
290 struct s_client
*last
;
291 cs_writelock(__func__
, &clientlist_lock
);
293 for(last
= first_client
; last
&& last
->next
; last
= last
->next
)
294 { ; } //ends with cl on last client
301 int32_t bucket
= (uintptr_t)cl
/ 16 % CS_CLIENT_HASHBUCKETS
;
302 cl
->nexthashed
= first_client_hashed
[bucket
];
303 first_client_hashed
[bucket
] = cl
;
305 cs_writeunlock(__func__
, &clientlist_lock
);
310 /* Creates the master client of OSCam and inits some global variables/mutexes. */
311 void init_first_client(void)
313 // get username OScam is running under
315 struct passwd
*pwdbuf
;
318 pwdbuf
= getpwuid(getuid()); // This is safe
321 memcpy(&pwd
, pwdbuf
, sizeof(pwd
));
322 processUsername
= cs_strdup(pwd
.pw_name
);
326 if(getpwuid_r(getuid(), &pwd
, buf
, sizeof(buf
), &pwdbuf
) == 0)
328 processUsername
= cs_strdup(pwd
.pw_name
);
332 if(!cs_malloc(&first_client
, sizeof(struct s_client
)))
334 fprintf(stderr
, "Could not allocate memory for master client, exiting...");
338 memset(first_client_hashed
, 0, sizeof(first_client_hashed
));
339 int32_t bucket
= (uintptr_t)first_client
/ 16 % CS_CLIENT_HASHBUCKETS
;
340 first_client_hashed
[bucket
] = first_client
;
342 first_client
->next
= NULL
; // terminate clients list with NULL
343 first_client
->login
= time(NULL
);
344 first_client
->typ
= 's';
345 first_client
->thread
= pthread_self();
346 set_localhost_ip(&first_client
->ip
);
348 struct s_auth
*null_account
;
349 if(!cs_malloc(&null_account
, sizeof(struct s_auth
)))
351 fprintf(stderr
, "Could not allocate memory for master account, exiting...");
355 first_client
->account
= null_account
;
356 if(pthread_setspecific(getclient
, first_client
))
358 fprintf(stderr
, "Could not setspecific getclient in master process, exiting...");
363 int32_t cs_auth_client(struct s_client
*client
, struct s_auth
*account
, const char *e_txt
)
366 uint8_t md5tmp
[MD5_DIGEST_LENGTH
];
370 char *t_crypt
= "encrypted";
371 char *t_plain
= "plain";
372 char *t_grant
= " granted";
373 char *t_reject
= " rejected";
374 char *t_msg
[] = { buf
, "invalid access", "invalid ip", "unknown reason", "protocol not allowed" };
375 struct s_module
*module
= get_module(client
);
377 memset(&client
->grp
, 0xff, sizeof(uint64_t));
378 //client->grp=0xffffffffffffff;
379 if((intptr_t)account
!= 0 && (intptr_t)account
!= -1 && account
->disabled
)
381 cs_add_violation(client
, account
->usr
);
382 cs_log("%s %s-client %s%s (%s%sdisabled account)",
383 client
->crypted
? t_crypt
: t_plain
,
385 IP_ISSET(client
->ip
) ? cs_inet_ntoa(client
->ip
) : "",
386 IP_ISSET(client
->ip
) ? t_reject
: t_reject
+ 1,
392 // check whether client comes in over allowed protocol
393 if((intptr_t)account
!= 0 && (intptr_t)account
!= -1 && (intptr_t)account
->allowedprotocols
&&
394 (((intptr_t)account
->allowedprotocols
& module
->listenertype
) != module
->listenertype
))
396 cs_add_violation(client
, account
->usr
);
397 cs_log("%s %s-client %s%s (%s%sprotocol not allowed)",
398 client
->crypted
? t_crypt
: t_plain
,
400 IP_ISSET(client
->ip
) ? cs_inet_ntoa(client
->ip
) : "",
401 IP_ISSET(client
->ip
) ? t_reject
: t_reject
+ 1,
407 client
->account
= first_client
->account
;
408 switch((intptr_t)account
)
410 case 0: // reject access
413 cs_add_violation(client
, NULL
);
414 cs_log("%s %s-client %s%s (%s)",
415 client
->crypted
? t_crypt
: t_plain
,
417 IP_ISSET(client
->ip
) ? cs_inet_ntoa(client
->ip
) : "",
418 IP_ISSET(client
->ip
) ? t_reject
: t_reject
+ 1,
419 e_txt
? e_txt
: t_msg
[rc
]);
423 default: // grant/check access
425 if(IP_ISSET(client
->ip
) && account
->dyndns
)
427 if(!IP_EQUAL(client
->ip
, account
->dynip
))
428 { cs_user_resolve(account
); }
429 if(!IP_EQUAL(client
->ip
, account
->dynip
))
431 cs_add_violation(client
, account
->usr
);
436 client
->monlvl
= account
->monlvl
;
437 client
->account
= account
;
442 if(client
->typ
== 'c' || client
->typ
== 'm')
444 client
->pcrc
= crc32(0L, MD5((uint8_t *)(ESTR(account
->pwd
)), cs_strlen(ESTR(account
->pwd
)), md5tmp
), MD5_DIGEST_LENGTH
);
447 if(client
->typ
== 'c')
449 client
->last_caid
= NO_CAID_VALUE
;
450 client
->last_provid
= NO_PROVID_VALUE
;
451 client
->last_srvid
= NO_SRVID_VALUE
;
452 client
->expirationdate
= account
->expirationdate
;
453 client
->disabled
= account
->disabled
;
454 client
->allowedtimeframe_set
=account
->allowedtimeframe_set
;
456 for(i
= 0; i
< SIZE_SHORTDAY
; i
++)
458 for(j
= 0; j
< 24; j
++)
460 client
->allowedtimeframe
[i
][j
][0] = account
->allowedtimeframe
[i
][j
][0];
461 client
->allowedtimeframe
[i
][j
][1] = account
->allowedtimeframe
[i
][j
][1];
465 if(account
->firstlogin
== 0)
467 account
->firstlogin
= time((time_t *)0);
470 client
->failban
= account
->failban
;
471 client
->c35_suppresscmd08
= account
->c35_suppresscmd08
;
472 client
->ncd_keepalive
= account
->ncd_keepalive
;
473 client
->grp
= account
->grp
;
474 client
->aureader_list
= account
->aureader_list
;
475 client
->autoau
= account
->autoau
;
476 client
->tosleep
= (60 * account
->tosleep
);
477 client
->c35_sleepsend
= account
->c35_sleepsend
;
478 caidtab_clone(&account
->ctab
, &client
->ctab
);
482 cs_fake_client(client
, account
->usr
, account
->uniq
, client
->ip
);
485 client
->cltab
= account
->cltab
; // CLASS filter
486 ftab_clone(&account
->ftab
, &client
->ftab
); // IDENT filter
487 ftab_clone(&account
->fchid
, &client
->fchid
); // CHID filter
488 client
->sidtabs
.ok
= account
->sidtabs
.ok
; // services
489 client
->sidtabs
.no
= account
->sidtabs
.no
; // services
490 tuntab_clone(&account
->ttab
, &client
->ttab
);
491 ac_init_client(client
, account
);
496 case -1: // anonymous grant access
504 if(client
->typ
== 'm')
506 snprintf(t_msg
[0], sizeof(buf
), "lvl=%d", client
->monlvl
);
510 int32_t rcount
= ll_count(client
->aureader_list
);
511 snprintf(buf
, sizeof(buf
), "au=");
515 snprintf(buf
+ 3, sizeof(buf
) - 3, "off");
521 snprintf(buf
+ 3, sizeof(buf
) - 3, "auto (%d reader)", rcount
);
525 snprintf(buf
+ 3, sizeof(buf
) - 3, "on (%d reader)", rcount
);
531 cs_log("%s %s-client %s%s (%s, %s)",
532 client
->crypted
? t_crypt
: t_plain
,
533 e_txt
? e_txt
: module
->desc
,
534 IP_ISSET(client
->ip
) ? cs_inet_ntoa(client
->ip
) : "",
535 IP_ISSET(client
->ip
) ? t_grant
: t_grant
+ 1,
536 username(client
), t_msg
[rc
]);
544 void cs_disconnect_client(struct s_client
*client
)
546 char buf
[32] = { 0 };
548 if(IP_ISSET(client
->ip
))
550 snprintf(buf
, sizeof(buf
), " from %s", cs_inet_ntoa(client
->ip
));
553 cs_log("%s disconnected%s", username(client
), buf
);
555 if(client
== cur_client())
565 void kill_all_clients(void)
568 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
570 if(cl
->typ
== 'c' || cl
->typ
== 'm')
574 cs_log("killing client %s", cl
->account
->usr
);
577 #ifdef CS_CACHEEX_AIO
578 ll_destroy_data(&cl
->ll_cacheex_stats
);
582 NULLFREE(processUsername
);
585 void cs_reinit_clients(struct s_auth
*new_accounts
)
587 struct s_auth
*account
;
588 uint8_t md5tmp
[MD5_DIGEST_LENGTH
];
593 for(cl
= first_client
->next
; cl
; cl
= cl
->next
)
595 if((cl
->typ
== 'c' || cl
->typ
== 'm') && cl
->account
)
597 for(account
= new_accounts
; (account
) ; account
= account
->next
)
599 if(!strcmp(cl
->account
->usr
, account
->usr
))
605 if(account
&& !account
->disabled
&& cl
->pcrc
== crc32(0L, MD5((uint8_t *)ESTR(account
->pwd
), cs_strlen(ESTR(account
->pwd
)), md5tmp
), MD5_DIGEST_LENGTH
))
607 cl
->account
= account
;
608 #ifdef CS_CACHEEX_AIO
609 cl
->cacheex_aio_checked
= 0;
613 cl
->grp
= account
->grp
;
614 cl
->aureader_list
= account
->aureader_list
;
615 cl
->autoau
= account
->autoau
;
616 cl
->expirationdate
= account
->expirationdate
;
617 cl
->allowedtimeframe_set
= account
->allowedtimeframe_set
;
619 for(i
= 0; i
< SIZE_SHORTDAY
; i
++)
621 for(j
= 0; j
< 24; j
++)
623 cl
->allowedtimeframe
[i
][j
][0] = account
->allowedtimeframe
[i
][j
][0];
624 cl
->allowedtimeframe
[i
][j
][1] = account
->allowedtimeframe
[i
][j
][1];
628 cl
->ncd_keepalive
= account
->ncd_keepalive
;
629 cl
->c35_suppresscmd08
= account
->c35_suppresscmd08
;
630 cl
->tosleep
= (60 * account
->tosleep
);
631 cl
->c35_sleepsend
= account
->c35_sleepsend
;
632 cl
->monlvl
= account
->monlvl
;
633 cl
->disabled
= account
->disabled
;
634 cl
->cltab
= account
->cltab
; // Class
636 // newcamd module doesn't like ident reloading
639 ftab_clone(&account
->ftab
, &cl
->ftab
); // IDENT filter
640 ftab_clone(&account
->fchid
, &cl
->fchid
); // CHID filter
643 cl
->sidtabs
.ok
= account
->sidtabs
.ok
; // services
644 cl
->sidtabs
.no
= account
->sidtabs
.no
; // services
645 cl
->failban
= account
->failban
;
647 caidtab_clone(&account
->ctab
, &cl
->ctab
);
648 tuntab_clone(&account
->ttab
, &cl
->ttab
);
650 webif_client_reset_lastresponsetime(cl
);
654 cs_fake_client(cl
, account
->usr
, (account
->uniq
== 1 || account
->uniq
== 2) ? account
->uniq
+ 2 : account
->uniq
, cl
->ip
);
657 ac_init_client(cl
, account
);
662 if(get_module(cl
)->type
& MOD_CONN_NET
)
664 cs_log_dbg(D_TRACE
, "client '%s', thread=%8lX not found in db (or password changed)", cl
->account
->usr
, (unsigned long)cl
->thread
);
669 cl
->account
= first_client
->account
;
680 void client_check_status(struct s_client
*cl
)
682 if(!cl
|| cl
->kill
|| !cl
->init_done
)
691 if((get_module(cl
)->listenertype
& LIS_CCCAM
) && cl
->last
&& (time(NULL
) - cl
->last
) > (time_t)12)
693 add_job(cl
, ACTION_CLIENT_IDLE
, NULL
, 0);
696 // Check umaxidle to avoid client is killed for inactivity, it has priority than cmaxidle
697 if(!cl
->account
->umaxidle
)
702 // Check user for exceeding umaxidle by checking cl->last, except Newcamd & Gbox
703 if(!(cl
->ncd_keepalive
&& (get_module(cl
)->listenertype
& LIS_NEWCAMD
)) && !(get_module(cl
)->listenertype
& LIS_GBOX
) && cl
->account
->umaxidle
>0 && cl
->last
&& (time(NULL
) - cl
->last
) > (time_t)cl
->account
->umaxidle
)
705 add_job(cl
, ACTION_CLIENT_IDLE
, NULL
, 0);
708 // Check clients for exceeding cmaxidle by checking cl->last, except Newcamd & Gbox
709 if(!(cl
->ncd_keepalive
&& (get_module(cl
)->listenertype
& LIS_NEWCAMD
)) && !(get_module(cl
)->listenertype
& LIS_GBOX
) && cl
->last
&& cl
->account
->umaxidle
==-1 && cfg
.cmaxidle
&& (time(NULL
) - cl
->last
) > (time_t)cfg
.cmaxidle
)
711 add_job(cl
, ACTION_CLIENT_IDLE
, NULL
, 0);
715 if((get_module(cl
)->listenertype
& LIS_GBOX
) && cl
->last
&& (time(NULL
) - cl
->last
) > (time_t)cfg
.gbox_reconnect
)
717 add_job(cl
, ACTION_PEER_IDLE
, NULL
, 0);
723 cardreader_checkhealth(cl
, cl
->reader
);
728 struct s_reader
*rdr
= cl
->reader
;
729 if(!rdr
|| !rdr
->enable
|| !rdr
->active
) // reader is disabled or restarting at this moment
734 // execute reader do idle on proxy reader after a certain time (rdr->tcp_ito = inactivitytimeout)
735 // disconnect when no keepalive available
736 if((rdr
->tcp_ito
&& is_cascading_reader(rdr
)) || (rdr
->typ
== R_CCCAM
) || (rdr
->typ
== R_CAMD35
) || (rdr
->typ
== R_CS378X
) || (rdr
->typ
== R_SCAM
) || (rdr
->tcp_ito
!= 0 && rdr
->typ
== R_RADEGAST
))
738 time_t now
= time(NULL
);
739 int32_t time_diff
= llabs(now
- rdr
->last_check
);
741 if(time_diff
> 60 || (time_diff
> 12 && (rdr
->typ
== R_CCCAM
|| rdr
->typ
== R_CAMD35
|| rdr
->typ
== R_CS378X
)) || ((time_diff
> (rdr
->tcp_rto
?rdr
->tcp_rto
:60)) && rdr
->typ
== R_RADEGAST
)) //check 1x per minute or every 10s for cccam/camd35 or reconnecttimeout radegast if 0 defaut 60s
743 add_job(rdr
->client
, ACTION_READER_IDLE
, NULL
, 0);
744 rdr
->last_check
= now
;
752 void free_client(struct s_client
*cl
)
759 struct s_reader
*rdr
= cl
->reader
;
761 // Remove client from client list. kill_thread also removes this client, so here just if client exits itself...
762 struct s_client
*prev
, *cl2
;
763 cs_writelock(__func__
, &clientlist_lock
);
765 if(!cl
->kill_started
)
767 cl
->kill_started
= 1;
771 cs_writeunlock(__func__
, &clientlist_lock
);
772 cs_log("[free_client] ERROR: free already started!");
777 for(prev
= first_client
, cl2
= first_client
->next
; prev
->next
!= NULL
; prev
= prev
->next
, cl2
= cl2
->next
)
785 if(cl
== cl2
) // Remove client from list
787 prev
->next
= cl2
->next
;
790 int32_t bucket
= (uintptr_t)cl
/ 16 % CS_CLIENT_HASHBUCKETS
;
792 // Remove client from hashed list
793 if(first_client_hashed
[bucket
] == cl
)
795 first_client_hashed
[bucket
] = cl
->nexthashed
;
799 for(prev
= first_client_hashed
[bucket
], cl2
= first_client_hashed
[bucket
]->nexthashed
;
800 prev
->nexthashed
!= NULL
; prev
= prev
->nexthashed
, cl2
= cl2
->nexthashed
)
810 prev
->nexthashed
= cl2
->nexthashed
;
814 cs_writeunlock(__func__
, &clientlist_lock
);
815 cleanup_ecmtasks(cl
);
817 // Clean reader. The cleaned structures should be only used by the reader thread, so we should be save without waiting
820 ll_destroy_data(&rdr
->emmstat
);
821 remove_reader_from_active(rdr
);
823 cs_sleepms(1000); // just wait a bit that really really nobody is accessing client data
832 cardreader_close(rdr
);
837 network_tcp_connection_close(rdr
, "cleanup");
843 // Clean client specific data
847 cl
->last_caid
= NO_CAID_VALUE
;
848 cl
->last_provid
= NO_PROVID_VALUE
;
849 cl
->last_srvid
= NO_SRVID_VALUE
;
852 cs_sleepms(1000); // just wait a bit that really really nobody is accessing client data
855 struct s_module
*module
= get_module(cl
);
861 // Close network socket if not already cleaned by previous cleanup functions
867 // Clean all remaining structures
869 NULLFREE(cl
->work_mbuf
);
873 add_garbage(cl
->ecmtask
);
877 ll_destroy_data(&cl
->cascadeusers
);
879 ftab_clear(&cl
->ftab
);
880 ftab_clear(&cl
->fchid
);
881 tuntab_clear(&cl
->ttab
);
882 caidtab_clear(&cl
->ctab
);
884 NULLFREE(cl
->cltab
.aclass
);
885 NULLFREE(cl
->cltab
.bclass
);
887 NULLFREE(cl
->cw_rass
);
888 ll_destroy_data(&cl
->ra_buf
);
889 NULLFREE(cl
->aes_keys
);
895 add_garbage(cl
->serialdata
);