Exemple #1
0
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);
}
Exemple #2
0
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;
}