static void radegast_server_init(struct s_client *cl) { if (!cl->init_done) { if (IP_ISSET(cl->ip)) cs_log("radegast: new connection from %s", cs_inet_ntoa(cl->ip)); radegast_auth_client(cur_client()->ip); cl->init_done=1; } return; }
void cs_disconnect_client(struct s_client * client) { char buf[32] = { 0 }; if (IP_ISSET(client->ip)) snprintf(buf, sizeof(buf), " from %s", cs_inet_ntoa(client->ip)); cs_log("%s disconnected%s", username(client), buf); if (client == cur_client()) cs_exit(0); else kill_thread(client); }
static void serverip_fn(const char *token, char *value, void *setting, FILE *f) { IN_ADDR_T srvip = *(IN_ADDR_T *)setting; if (value) { if (strlen(value) == 0) { set_null_ip((IN_ADDR_T *)setting); } else { cs_inet_addr(value, (IN_ADDR_T *)setting); } return; } if (IP_ISSET(srvip) || cfg.http_full_cfg) fprintf_conf(f, token, "%s\n", cs_inet_ntoa(srvip)); }
struct s_client *create_client(IN_ADDR_T ip) { struct s_client *cl; if(!cs_malloc(&cl, sizeof(struct s_client))) { cs_log("max connections reached (out of memory) -> reject client %s", IP_ISSET(ip) ? cs_inet_ntoa(ip) : "with null address"); return NULL; } //client part IP_ASSIGN(cl->ip, ip); cl->account = first_client->account; //master part pthread_mutex_init(&cl->thread_lock, NULL); cl->login = cl->last = time(NULL); cl->tid = (uint32_t)(uintptr_t)cl; // Use pointer adress of client as threadid (for monitor and log) //Now add new client to the list: struct s_client *last; cs_writelock(&clientlist_lock); if(sizeof(uintptr_t) > 4) // 64bit systems can have collisions because of the cast so lets check if there are some { int8_t found; do { found = 0; for(last = first_client; last; last = last->next) { if(last->tid == cl->tid) { found = 1; break; } } if(found || cl->tid == 0) { cl->tid = (uint32_t)rand(); } } while(found || cl->tid == 0); } for(last = first_client; last->next != NULL; last = last->next) { ; } //ends with cl on last client last->next = cl; int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; cl->nexthashed = first_client_hashed[bucket]; first_client_hashed[bucket] = cl; #ifdef MODULE_GBOX cl->gbox_peer_id = 0; #endif cs_writeunlock(&clientlist_lock); return cl; }
static void gbox_server_init(struct s_client *cl) { if(!cl->init_done) { if(IP_ISSET(cl->ip)) { cs_log("gbox: new connection from %s", cs_inet_ntoa(cl->ip)); } gbox_auth_client(cl); if(cl->gbox) { gbox_local_cards(cl); cl->init_done = 1; } } return; }
struct s_client *create_client(IN_ADDR_T ip) { struct s_client *cl; if(!cs_malloc(&cl, sizeof(struct s_client))) { cs_log("max connections reached (out of memory) -> reject client %s", IP_ISSET(ip) ? cs_inet_ntoa(ip) : "with null address"); return NULL; } //client part IP_ASSIGN(cl->ip, ip); cl->account = first_client->account; //master part SAFE_MUTEX_INIT(&cl->thread_lock, NULL); cl->login = cl->last = time(NULL); cl->tid = (uint32_t)rand(); //Now add new client to the list: struct s_client *last; cs_writelock(__func__, &clientlist_lock); for(last = first_client; last && last->next; last = last->next) { ; } //ends with cl on last client if (last) last->next = cl; int32_t bucket = (uintptr_t)cl / 16 % CS_CLIENT_HASHBUCKETS; cl->nexthashed = first_client_hashed[bucket]; first_client_hashed[bucket] = cl; cs_writeunlock(__func__, &clientlist_lock); return cl; }
/************************************************************************************************************************ * client functions *************************************************************************************************************************/ int pandora_client_init(struct s_client *cl) { static struct sockaddr_in loc_sa; int16_t p_proto; char ptxt[16]; struct s_reader *rdr = cl->reader; uchar md5tmp[MD5_DIGEST_LENGTH]; cl->pfd = 0; if (rdr->r_port <= 0) { cs_log("invalid port %d for server %s", rdr->r_port, rdr->device); return (1); } p_proto = IPPROTO_UDP; set_null_ip(&cl->ip); memset((char *) &loc_sa, 0, sizeof(loc_sa)); loc_sa.sin_family = AF_INET; if (IP_ISSET(cfg.srvip)) IP_ASSIGN(SIN_GET_ADDR(loc_sa), cfg.srvip); else loc_sa.sin_addr.s_addr = INADDR_ANY; loc_sa.sin_port = htons(rdr->l_port); if ((cl->udp_fd = socket(PF_INET, SOCK_DGRAM, p_proto)) < 0) { cs_log("Socket creation failed (errno=%d)", errno); return 1; } int32_t opt = 1; setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); #ifdef SO_REUSEPORT setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEPORT, (void *)&opt, sizeof(opt)); #endif set_socket_priority(cl->udp_fd, cfg.netprio); if (rdr->l_port > 0) { if (bind(cl->udp_fd, (struct sockaddr *) &loc_sa, sizeof(loc_sa)) < 0) { cs_log("bind failed (errno=%d)", errno); close(cl->udp_fd); return (1); } snprintf(ptxt, sizeof(ptxt), ", port=%d", rdr->l_port); } else ptxt[0] = '\0'; memcpy(cl->pand_md5_key, MD5((uchar*)rdr->r_pwd, strlen(rdr->r_pwd), md5tmp), 16); cl->crypted = 1; //cl->grp = 0xFFFFFFFF; //rdr->caid[0] = rdr->ctab.caid[0]; cl->pand_send_ecm = rdr->pand_send_ecm; memset((char *) &cl->udp_sa, 0, sizeof(cl->udp_sa)); #ifdef IPV6SUPPORT ((struct sockaddr_in *)(&cl->udp_sa))->sin_family = AF_INET; ((struct sockaddr_in *)(&cl->udp_sa))->sin_port = htons((u_short) rdr->r_port); #else cl->udp_sa.sin_family = AF_INET; cl->udp_sa.sin_port = htons((u_short) rdr->r_port); #endif cs_log("proxy %s:%d pandora %s (%s)", rdr->device, rdr->r_port, rdr->pand_send_ecm?"with ECM support":"", ptxt ); cl->pfd = cl->udp_fd; //fcntl(cl->udp_fd, F_SETFL, fcntl(cl->udp_fd, F_GETFL, 0) | O_NONBLOCK); //!!!!! return (0); }
int32_t cs_auth_client(struct s_client * client, struct s_auth *account, const char *e_txt) { int32_t rc = 0; unsigned char md5tmp[MD5_DIGEST_LENGTH]; char buf[32]; char *t_crypt = "encrypted"; char *t_plain = "plain"; char *t_grant = " granted"; char *t_reject = " rejected"; char *t_msg[] = { buf, "invalid access", "invalid ip", "unknown reason", "protocol not allowed" }; struct s_module *module = get_module(client); memset(&client->grp, 0xff, sizeof(uint64_t)); //client->grp=0xffffffffffffff; if ((intptr_t)account != 0 && (intptr_t)account != -1 && account->disabled) { cs_add_violation(client, account->usr); cs_log("%s %s-client %s%s (%s%sdisabled account)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : "", e_txt ? " " : ""); return 1; } // check whether client comes in over allowed protocol if ((intptr_t)account != 0 && (intptr_t)account != -1 && (intptr_t)account->allowedprotocols && (((intptr_t)account->allowedprotocols & module->listenertype) != module->listenertype)) { cs_add_violation(client, account->usr); cs_log("%s %s-client %s%s (%s%sprotocol not allowed)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : "", e_txt ? " " : ""); return 1; } client->account = first_client->account; switch((intptr_t)account) { case 0: { // reject access rc = 1; cs_add_violation(client, NULL); cs_log("%s %s-client %s%s (%s)", client->crypted ? t_crypt : t_plain, module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_reject : t_reject+1, e_txt ? e_txt : t_msg[rc]); break; } default: { // grant/check access if (IP_ISSET(client->ip) && account->dyndns) { if (!IP_EQUAL(client->ip, account->dynip)) cs_user_resolve(account); if (!IP_EQUAL(client->ip, account->dynip)) { cs_add_violation(client, account->usr); rc=2; } } client->monlvl = account->monlvl; client->account = account; if (!rc) { client->dup=0; if (client->typ=='c' || client->typ=='m') client->pcrc = crc32(0L, MD5((uchar *)(ESTR(account->pwd)), strlen(ESTR(account->pwd)), md5tmp), MD5_DIGEST_LENGTH); if (client->typ=='c') { client->last_caid = NO_CAID_VALUE; client->last_srvid = NO_SRVID_VALUE; client->expirationdate = account->expirationdate; client->disabled = account->disabled; client->allowedtimeframe[0] = account->allowedtimeframe[0]; client->allowedtimeframe[1] = account->allowedtimeframe[1]; if (account->firstlogin == 0) account->firstlogin = time((time_t*)0); client->failban = account->failban; client->c35_suppresscmd08 = account->c35_suppresscmd08; client->ncd_keepalive = account->ncd_keepalive; client->grp = account->grp; client->aureader_list = account->aureader_list; client->autoau = account->autoau; client->tosleep = (60*account->tosleep); client->c35_sleepsend = account->c35_sleepsend; memcpy(&client->ctab, &account->ctab, sizeof(client->ctab)); if (account->uniq) cs_fake_client(client, account->usr, account->uniq, client->ip); client->ftab = account->ftab; // IDENT filter client->cltab = account->cltab; // CLASS filter client->fchid = account->fchid; // CHID filter client->sidtabs.ok= account->sidtabs.ok; // services client->sidtabs.no= account->sidtabs.no; // services memcpy(&client->ttab, &account->ttab, sizeof(client->ttab)); ac_init_client(client, account); } } } case -1: { // anonymous grant access if (rc) { t_grant = t_reject; } else { if (client->typ == 'm') { snprintf(t_msg[0], sizeof(buf), "lvl=%d", client->monlvl); } else { int32_t rcount = ll_count(client->aureader_list); snprintf(buf, sizeof(buf), "au="); if (!rcount) snprintf(buf+3, sizeof(buf)-3, "off"); else { if (client->autoau) snprintf(buf+3, sizeof(buf)-3, "auto (%d reader)", rcount); else snprintf(buf+3, sizeof(buf)-3, "on (%d reader)", rcount); } } } cs_log("%s %s-client %s%s (%s, %s)", client->crypted ? t_crypt : t_plain, e_txt ? e_txt : module->desc, IP_ISSET(client->ip) ? cs_inet_ntoa(client->ip) : "", IP_ISSET(client->ip) ? t_grant : t_grant + 1, username(client), t_msg[rc]); break; } } return rc; }