//----------------------------------------------- // to_s //----------------------------------------------- char* streamkey_to_s(char *dest, stream_key_t *key) { uint16_t sport, dport; if (0) //pkt_is_v6(pkt)) { sprintf(dest, "IPV6 STREAM HERE"); //sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(pkt->ip6.ip_p),"?:?:?",sport, "?:?:?", dport); return dest; } else { char leftip[16], rightip[16]; ip2string(leftip, GET_LEFT(key)); ip2string(rightip, GET_RIGHT(key)); sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(key->v4.ipproto), leftip, key->v4.lport, rightip, key->v4.rport); return dest; } }
void frcc_sendcards_cli(struct cc_client_data *cli) { int nbcard=0; struct cardserver_data *cs = cfg.cardserver; int i; if (cfg.freecccam.csport[0]) { for(i=0;i<MAX_CSPORTS;i++) { if(cfg.freecccam.csport[i]) { cs = getcsbyport(cfg.freecccam.csport[i]); if (cs) if (cc_sendcard_cli(cs, cli,0)) nbcard++; } else break; } } else { while (cs) { if (cc_sendcard_cli(cs, cli,0)) nbcard++; cs = cs->next; } } debugf(" FreeCCcam: %d cards --> client(%s)\n", nbcard, ip2string(cli->ip) ); }
void *th_cs_connect_cli(struct cs_clicon *param) { char passwdcrypt[120]; unsigned char keymod[14]; int i,index; unsigned char sessionkey[16]; struct cs_custom_data clicd; unsigned char buf[CWS_NETMSGSIZE]; struct cardserver_data *cs = param->cs; int sock = param->sock; uint32 ip = param->ip; free(param); // Create random deskey for (i=0; i<14; i++) keymod[i] = 0xff & rand(); // Create NewBox ID keymod[3] = (keymod[0]^'N') + keymod[1] + keymod[2]; keymod[7] = keymod[4] + (keymod[5]^'B') + keymod[6]; keymod[11] = keymod[8] + keymod[9] + (keymod[10]^'x'); //STAT: SEND RND KEY // send random des key if (send_nonb(sock, keymod, 14, 500)<=0) { debugf(" ERR SEND\n"); close(sock); pthread_exit(NULL); } uint32 ticks = GetTickCount(); // Calc SessionKey //debugf(" DES Key: "); debughex(keymod,14); des_login_key_get(keymod, cs->key, 14, sessionkey); //debugf(" Login Key: "); debughex(sessionkey,16); //md5_crypt("pass", "$1$abcdefgh$",passwdcrypt); //debugf(" passwdcrypt = %s\n",passwdcrypt); //STAT: LOGIN INFO // 3. login info i = cs_message_receive(sock, &clicd, buf, sessionkey,3000); if (i<=0) { if (i==-2) debugf(" %s: (%s) new connection closed, wrong des key\n", cs->name, ip2string(ip)); else debugf(" %s: (%s) new connection closed, receive timeout\n", cs->name, ip2string(ip)); close(sock); pthread_exit(NULL); } ticks = GetTickCount()-ticks; if (buf[0]!=MSG_CLIENT_2_SERVER_LOGIN) { close(sock); pthread_exit(NULL); } // Check username length if ( strlen( (char*)buf+3 )>63 ) { /* buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK; buf[1] = 0; buf[2] = 0; cs_message_send(sock, NULL, buf, 3, sessionkey); */ debugf(" %s: (%s) new connection closed, wrong username length\n", cs->name, ip2string(ip)); close(sock); pthread_exit(NULL); } pthread_mutex_lock(&prg.lockcli); index = 3; struct cs_client_data *usr = cs->client; int found = 0; while (usr) { if (!strcmp(usr->user,(char*)&buf[index])) { found=1; break; } usr = usr->next; } if (!found) { pthread_mutex_unlock(&prg.lockcli); buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK; buf[1] = 0; buf[2] = 0; //cs_message_send(sock, NULL, buf, 3, sessionkey); debugf(" %s: (%s) new connection closed, unknown user '%s'\n", cs->name, ip2string(ip), &buf[3]); close(sock); pthread_exit(NULL); } // Check password index += strlen(usr->user) +1; __md5_crypt(usr->pass, "$1$abcdefgh$",passwdcrypt); if (!strcmp(passwdcrypt,(char*)&buf[index])) { //Check Reconnection if (usr->handle!=INVALID_SOCKET) { debugf(" %s: user already connected '%s' (%s)\n", cs->name, usr->user, ip2string(ip)); cs_disconnect_cli(usr); } // Store program id usr->progid = clicd.sid; // buf[0] = MSG_CLIENT_2_SERVER_LOGIN_ACK; buf[1] = 0; buf[2] = 0; // Send NewBox Id&Version if (clicd.provid==0x0057484F) { // WHO clicd.provid = 0x004E4278; // MBx clicd.sid = REVISION; // Revision cs_message_send(sock, &clicd, buf, 3, sessionkey); } else cs_message_send(sock, NULL, buf, 3, sessionkey); des_login_key_get( cs->key, (unsigned char*)passwdcrypt, strlen(passwdcrypt),sessionkey); memcpy( &usr->sessionkey, &sessionkey, 16); // Setup User data usr->handle = sock; usr->ip = ip; usr->ping = ticks; usr->lastecmtime = GetTickCount(); usr->ecm.busy=0; usr->ecm.recvtime=0; usr->connected = GetTickCount(); usr->chkrecvtime = 0; debugf(" %s: client '%s' connected (%s)\n", cs->name, usr->user, ip2string(ip)); pipe_wakeup( srvsocks[1] ); } else { // send NAK buf[0] = MSG_CLIENT_2_SERVER_LOGIN_NAK; buf[1] = 0; buf[2] = 0; //cs_message_send(sock, NULL, buf, 3, sessionkey); debugf(" newcamd: client '%s' wrong password (%s)\n", usr->user, ip2string(ip)); close(sock); } pthread_mutex_unlock(&prg.lockcli); pthread_exit(NULL); }
static string v2s(uint32_t version_no){ return ip2string(version_no); }
int main(int argc, char *argv[]) { int listenfd; struct sockaddr_in serv_addr; listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { printf("Unable to open socket: %d (%s)\n", errno, strerror(errno)); return 1; } serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(60002); if (bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("Unable to bind address: %d (%s)\n", errno, strerror(errno)); return 1; } listen(listenfd,5); if (fork()) exit(0); setsid(); if (fork()) exit(0); std::vector<Client> clients; while (true) { fd_set rfds, wfds; FD_ZERO(&rfds); FD_ZERO(&wfds); int maxfd = 0; if (clients.size() < MAX_CLIENTS) { FD_SET(listenfd, &rfds); maxfd = listenfd; } for (auto it = clients.begin(), eit = clients.end(); it != eit; ++it) { if (it->write_ready()) { FD_SET(it->fd, &wfds); if (maxfd < it->fd) maxfd = it->fd; } if (it->read_ready()) { FD_SET(it->fd, &rfds); if (maxfd < it->fd) maxfd = it->fd; } } if (select(maxfd+1, &rfds, &wfds, NULL, NULL) < 0) { if (errno == EINTR) continue; syslog(LOG_ERR, "Error in select(): %m"); break; } // Process any existing connections. for (auto it = clients.begin(), eit = clients.end(); it != eit; ++it) { if (FD_ISSET(it->fd, &rfds) || FD_ISSET(it->fd, &wfds)) it->run_io(); } // Accept New Connections if (FD_ISSET(listenfd, &rfds)) { struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); int clientfd = accept(listenfd, reinterpret_cast<struct sockaddr*>(&client_addr), &client_addr_len); #ifdef IP_ACL_FILE if (authorize_ip(ntohl(client_addr.sin_addr.s_addr))) { #endif clients.emplace_back(clientfd); #ifdef IP_ACL_FILE } else { close(clientfd); char ipaddr[16]; ip2string(ntohl(client_addr.sin_addr.s_addr), ipaddr, 16); syslog(LOG_NOTICE, "Connection attempted from unauthorized IP: %s", ipaddr); } #endif } } return 1; }
void *freecc_connect_cli(struct struct_clicon *param) { uint8 buf[CC_MAXMSGSIZE]; uint8 data[16]; int i; struct cc_crypt_block sendblock; // crypto state block struct cc_crypt_block recvblock; // crypto state block char usr[64]; char pwd[255]; int sock = param->sock; uint32 ip = param->ip; free(param); memset(usr, 0, sizeof(usr)); memset(pwd, 0, sizeof(pwd)); // create & send random seed for(i=0; i<12; i++ ) data[i]=fast_rnd(); // Create Multics ID data[3] = (data[0]^'M') + data[1] + data[2]; data[7] = data[4] + (data[5]^'C') + data[6]; data[11] = data[8] + data[9] + (data[10]^'S'); //Create checksum for "O" cccam: for (i = 0; i < 4; i++) { data[12 + i] = (data[i] + data[4 + i] + data[8 + i]) & 0xff; } send_nonb(sock, data, 16, 100); //XOR init bytes with 'CCcam' cc_crypt_xor(data); //SHA1 SHA_CTX ctx; SHA1_Init(&ctx); SHA1_Update(&ctx, data, 16); SHA1_Final(buf, &ctx); //initialisate crypto states cc_crypt_init(&sendblock, buf, 20); cc_decrypt(&sendblock, data, 16); cc_crypt_init(&recvblock, data, 16); cc_decrypt(&recvblock, buf, 20); //debugdump(buf, 20, "SHA1 hash:"); memcpy(usr,buf,20); if ((i=recv_nonb(sock, buf, 20,3000)) == 20) { cc_decrypt(&recvblock, buf, 20); //debugdump(buf, 20, "Recv SHA1 hash:"); if ( memcmp(buf,usr,20)!=0 ) { //debugf(" cc_connect_cli(): wrong sha1 hash from client! (%s)\n",ip2string(ip)); close(sock); return NULL; } } else { //debugf(" cc_connect_cli(): recv sha1 timeout\n"); close(sock); return NULL; } // receive username if ((i=recv_nonb(sock, buf, 20,3000)) == 20) { cc_decrypt(&recvblock, buf, i); memcpy(usr,buf,20); //debugf(" cc_connect_cli(): username '%s'\n", usr); } else { //debugf(" cc_connect_cli(): recv user timeout\n"); close(sock); return NULL; } // Check for username pthread_mutex_lock(&prg.lockfreecccli); int found = 0; struct cc_client_data *cli = cfg.freecccam.client; while (cli) { if (!strcmp(cfg.freecccam.user,usr)) { if (cli->handle<=0) { found = 1; break; } else { if (cli->ip == ip) { // dont connect cc_disconnect_cli(cli); found = 1; break; } } } cli = cli->next; } if (!found) while (cli) { if (!strcmp(cfg.freecccam.user,usr)) { if (cli->handle>0) { // Check if we can disconnect idle state clients if (GetTickCount()-cli->lastecmtime > 100000) cc_disconnect_cli(cli); } if (cli->handle<=0) { found = 1; break; } } cli = cli->next; } pthread_mutex_unlock(&prg.lockfreecccli); if (!found) { debugf(" FreeCCcam: Failed to connect new client(%s)\n",ip2string(ip)); close(sock); return NULL; } // receive passwd / 'CCcam' strcpy( pwd, cfg.freecccam.pass); cc_decrypt(&recvblock, (uint8*)pwd, strlen(pwd)); if ((i=recv_nonb(sock, buf, 6,3000)) == 6) { cc_decrypt(&recvblock, buf, 6); if (memcmp( buf+1, "Ccam\0",5)) { debugf(" FreeCCcam: login failed from client(%s)\n",ip2string(ip)); close(sock); return NULL; } } else { close(sock); return NULL; } // send passwd ack memset(buf, 0, 20); memcpy(buf, "CCcam\0", 6); //debugf("Server: send ack '%s'\n",buf); cc_encrypt(&sendblock, buf, 20); send_nonb(sock, buf, 20, 100); sprintf(cli->user,"%s", ip2string(ip)); //cli->ecmnb=0; //cli->ecmok=0; memcpy(&cli->sendblock,&sendblock,sizeof(sendblock)); memcpy(&cli->recvblock,&recvblock,sizeof(recvblock)); debugf(" FreeCCcam: client(%s) connected\n",ip2string(ip)); // recv cli data memset(buf, 0, sizeof(buf)); i = cc_msg_recv( sock, &cli->recvblock, buf, 3000); if (i!=97) { debug("error recv cli data\n"); close(sock); return NULL; } // Setup Client Data // pthread_mutex_lock(&prg.lockfreecccli); memcpy( cli->nodeid, buf+24, 8); memcpy( cli->version, buf+33, 32); memcpy( cli->build, buf+65, 32 ); debugf(" FreeCCcam: client(%s) running version %s build %s\n",ip2string(ip), cli->version, cli->build); // cli->nodeid,8, cli->cardsent = 0; cli->connected = GetTickCount(); cli->lastecmtime = GetTickCount(); cli->handle = sock; cli->ip = ip; cli->chkrecvtime = 0; // pthread_mutex_unlock(&prg.lockfreecccli); // send cli data ack cc_msg_send( sock, &cli->sendblock, CC_MSG_CLI_INFO, 0, NULL); //cc_msg_send( sock, &cli->sendblock, CC_MSG_BAD_ECM, 0, NULL); int sendversion = ( (cli->version[28]=='W')&&(cli->version[29]='H')&&(cli->version[30]='O') ); cc_sendinfo_cli(cli, sendversion); //cc_msg_send( sock, &cli->sendblock, CC_MSG_BAD_ECM, 0, NULL); cli->cardsent = 1; usleep(10000); frcc_sendcards_cli(cli); pipe_wakeup( srvsocks[1] ); return cli; }
void cache_recvmsg() { unsigned int recv_ip; unsigned short recv_port; unsigned char buf[1024]; struct sockaddr_in si_other; socklen_t slen=sizeof(si_other); uint ticks = GetTickCount(); struct cs_cachepeer_data *peer; int received = recvfrom( cfg.cachesock, buf, sizeof(buf), 0, (struct sockaddr*)&si_other, &slen); memcpy( &recv_ip, &si_other.sin_addr, 4); recv_port = ntohs(si_other.sin_port); if (received>0) { if (flag_debugnet) { debugf(" cache: recv data (%d) from address (%s:%d)\n", received, ip2string(recv_ip), recv_port ); debughex(buf,received); } // Store Data struct cache_data req; switch(buf[0]) { case TYPE_REQUEST: // Check Peer peer = getpeerbyaddr(recv_ip,recv_port); if (!peer) { peer = getpeerbyip(recv_ip); if (!peer) break; } peer->lastactivity = ticks; //peer->totreq++; // Check Multics diferent version if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break; // Check CSP if (received==20) { // arbiter number strcpy(peer->program,"CSP"); break; } // Check Status if (peer->disabled) break; // Get DATA req.tag = buf[1]; req.sid = (buf[2]<<8) | buf[3]; req.onid = (buf[4]<<8) | buf[5]; req.caid = (buf[6]<<8) | buf[7]; req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11]; // Check Cache Request if (!cache_check(&req)) break; // peer->reqnb++; // ADD CACHE struct cache_data *pcache = cache_fetch( &req ); if (pcache==NULL) { //*debugf(" [CACHE] << Cache Request from %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash); pcache = cache_new( &req ); if (cfg.cache.trackermode) { // Send REQUEST to all Peers struct cs_cachepeer_data *p = cfg.cachepeer; while (p) { if (!p->disabled) if (p->host->ip && p->port) if ( (p->lastactivity+75000)>ticks ) if ( !p->fblock0onid || pcache->onid ) cache_send_request(pcache,p); p = p->next; } pcache->sendcache = 1; cfg.cachereq++; } } else if (!cfg.cache.trackermode) { if ( (pcache->status==CACHE_STAT_DCW)&&(pcache->sendcache!=2) ) { //debugf(" [CACHE] << Request Reply >> to peer %s %04x:%04x:%08x\n", peer->host->name, req.caid, req.sid, req.hash); peer->ihitfwd++; peer->hitfwd++; cache_send_reply(pcache,peer); } } break; case TYPE_REPLY: // Check Peer peer = getpeerbyaddr(recv_ip,recv_port); if (!peer) { peer = getpeerbyip(recv_ip); if (!peer) break; } peer->lastactivity = ticks; //peer->totrep++; // Check Multics diferent version if ( !strcmp("MultiCS",peer->program) && (!strcmp("r63",peer->version)||!strcmp("r64",peer->version)||!strcmp("r65",peer->version)||!strcmp("r66",peer->version)||!strcmp("r67",peer->version)||!strcmp("r68",peer->version)||!strcmp("r69",peer->version)||!strcmp("r70",peer->version)||!strcmp("r71",peer->version)||!strcmp("r72",peer->version)||!strcmp("r73",peer->version)||!strcmp("r74",peer->version)||!strcmp("r75",peer->version)||!strcmp("r76",peer->version)||!strcmp("r77",peer->version)||!strcmp("r78",peer->version)||!strcmp("r79",peer->version)||!strcmp("r80",peer->version)||!strcmp("r81",peer->version)||!strcmp("r82",peer->version)||!strcmp("r83",peer->version)||!strcmp("r84",peer->version)||!strcmp("r85",peer->version)) ) break; // Check Status if (peer->disabled) break; // 02 80 00CD 0001 0500 8D1DB359 80 // failed // 02 80 00CD 0001 0500 8D1DB359 80 00CD 0000 0500 63339F359A663232B73158405A255DDC // OLD // 02 80 001F 0001 0100 9A3BA1C1 80 BC02DB99DE3D526D5702D42D4C249505 0005 6361726431 // NEW if (buf[12]!=buf[1]) { //peer->rep_badheader++; break; } req.tag = buf[1]; req.sid = (buf[2]<<8) | buf[3]; req.onid = (buf[4]<<8) | buf[5]; req.caid = (buf[6]<<8) | buf[7]; req.hash = (buf[8]<<24) | (buf[9]<<16) | (buf[10]<<8) |buf[11]; // Check Cache Request if (!cache_check(&req)) { //peer->rep_badfields++; break; } // if (received==13) { // FAILED //peer->rep_failed++; //*debugf(" [CACHE] <| Failed Cache Reply from %s (CAID:%04x SID:%04x ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.onid); // NOTHING TO DO break; } else if (received>=29) { // 02 80 001F 0001 0100 9A3BA1C1 80 BC02DB99DE3D526D5702D42D4C249505 0005 6361726431 // NEW if ( !acceptDCW(buf+13) ) { //peer->rep_baddcw++; break; } //*debugf(" [CACHE] << Good Cache Reply from %s %04x:%04x:%08x (ONID:%04x)\n", peer->host->name, req.caid, req.sid, req.hash, req.onid); peer->repok++; // Request+Reply // Search for Cache data struct cache_data *pcache = cache_fetch( &req ); if (pcache==NULL) pcache = cache_new( &req ); if (pcache->status!=CACHE_STAT_DCW) { //*debugf(" [CACHE] Update Cache DCW %04x:%04x:%08x\n", pcache->caid, pcache->sid, pcache->hash); pcache->peerid = peer->id; memcpy(pcache->cw, buf+13, 16); pcache->status = CACHE_STAT_DCW; if (pcache->sendpipe) { uchar buf[128]; // 32 por defecto buf[0] = PIPE_CACHE_FIND_SUCCESS; buf[1] = 11+2+16; // Data length buf[2] = pcache->tag; buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff; buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff; buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; buf[13] = peer->id>>8; buf[14] = peer->id&0xff; memcpy( buf+15, pcache->cw, 16); //*debugf(" pipe Cache->Ecm: PIPE_CACHE_FIND_SUCCESS %04x:%04x:%08x\n",pcache->caid, pcache->sid, pcache->hash); // debughex(buf, 13+16); pipe_send( srvsocks[1], buf, 13+2+16); //pcache->sendpipe = 0; } if (cfg.cache.trackermode) { // Send REQUEST to all Peers struct cs_cachepeer_data *p = cfg.cachepeer; while (p) { if (!p->disabled) if (p->host->ip && p->port) if ( (p->lastactivity+75000)>ticks ) if ( !p->fblock0onid || pcache->onid ) cache_send_reply(pcache,p); p = p->next; } pcache->sendcache = 2; cfg.cacherep++; } } else if ( pcache->sendpipe && memcmp(pcache->cw, buf+13, 16) ) { // resend to server pcache->peerid = peer->id; memcpy(pcache->cw, buf+13, 16); pcache->status = CACHE_STAT_DCW; uchar buf[128]; // 32 por defecto buf[0] = PIPE_CACHE_FIND_SUCCESS; buf[1] = 11+2+16; // Data length buf[2] = pcache->tag; buf[3] = pcache->sid>>8; buf[4] = pcache->sid&0xff; buf[5] = pcache->onid>>8; buf[6] = pcache->onid&0xff; buf[7] = pcache->caid>>8; buf[8] = pcache->caid&0xff; buf[9] = pcache->hash>>24; buf[10] = pcache->hash>>16; buf[11] = pcache->hash>>8; buf[12] = pcache->hash & 0xff; buf[13] = peer->id>>8; buf[14] = peer->id&0xff; memcpy( buf+15, pcache->cw, 16); pipe_send( srvsocks[1], buf, 13+2+16); }