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); }
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; }