static void cs_fake_client(struct s_client *client, char *usr, int32_t uniq, IN_ADDR_T ip) { /* Uniq = 1: only one connection per user * * Uniq = 2: set (new connected) user only to fake if source * ip is different (e.g. for newcamd clients with * different CAID's -> Ports) * * Uniq = 3: only one connection per user, but only the last * login will survive (old mpcs behavior) * * Uniq = 4: set user only to fake if source ip is * different, but only the last login will survive */ struct s_client *cl; struct s_auth *account; cs_writelock(&fakeuser_lock); for (cl = first_client->next; cl; cl = cl->next) { account = cl->account; if (cl != client && cl->typ == 'c' && !cl->dup && account && streq(account->usr, usr) && uniq < 5 && ((uniq % 2) || !IP_EQUAL(cl->ip, ip))) { char buf[20]; if (uniq == 3 || uniq == 4) { cl->dup = 1; cl->aureader_list = NULL; cs_strncpy(buf, cs_inet_ntoa(cl->ip), sizeof(buf)); cs_log("client(%8lX) duplicate user '%s' from %s (prev %s) set to fake (uniq=%d)", (unsigned long)cl->thread, usr, cs_inet_ntoa(ip), buf, uniq); if (cl->failban & BAN_DUPLICATE) { cs_add_violation(cl, usr); } if (cfg.dropdups) { cs_writeunlock(&fakeuser_lock); cs_sleepms(100); // sleep a bit to prevent against saturation from fast reconnecting clients kill_thread(cl); cs_writelock(&fakeuser_lock); } } else { client->dup = 1; client->aureader_list = NULL; cs_strncpy(buf, cs_inet_ntoa(ip), sizeof(buf)); cs_log("client(%8lX) duplicate user '%s' from %s (current %s) set to fake (uniq=%d)", (unsigned long)pthread_self(), usr, cs_inet_ntoa(cl->ip), buf, uniq); if (client->failban & BAN_DUPLICATE) { cs_add_violation_by_ip(ip, get_module(client)->ptab->ports[client->port_idx].s_port, usr); } if (cfg.dropdups) { cs_writeunlock(&fakeuser_lock); // we need to unlock here as cs_disconnect_client kills the current thread! cs_sleepms(100); // sleep a bit to prevent against saturation from fast reconnecting clients cs_disconnect_client(client); cs_writelock(&fakeuser_lock); } break; } } } cs_writeunlock(&fakeuser_lock); }
void cs_add_violation(struct s_client *cl, char *info) { struct s_module *module = get_module(cl); cs_add_violation_by_ip(cl->ip, module->ptab.ports[cl->port_idx].s_port, info); }