📄 newcamd.c
字号:
if(len<3||len+cdLen+4>CWS_NETMSGSIZE) { PRINTF(L_CC_NEWCAMD,"bad message size %d in SendMessage",len); return false; } unsigned char netbuf[CWS_NETMSGSIZE]; memset(&netbuf[2],0,cdLen+2); memcpy(&netbuf[cdLen+4],data,len); netbuf[cdLen+4+1]=(data[1]&0xf0)|(((len-3)>>8)&0x0f); netbuf[cdLen+4+2]=(len-3)&0xff; len+=4; if(cd) memcpy(&netbuf[4],cd,cdLen); len+=cdLen; if(UseMsgId) { if(commType==COMMTYPE_CLIENT) netMsgId++; netbuf[2]=netMsgId>>8; netbuf[3]=netMsgId&0xff; } if((len=cTripleDes::PadMessage(netbuf,len))<0) { PRINTF(L_CC_NEWCAMD,"PadMessage failed"); return false; } if((data=cTripleDes::Encrypt(netbuf,len,netbuf))==0) { PRINTF(L_CC_NEWCAMD,"Encrypt failed"); return false; } len+=sizeof(DES_cblock); netbuf[0]=(len-2)>>8; netbuf[1]=(len-2)&0xff; return cCardClient::SendMsg(so,netbuf,len);}int cCardClientNewCamd::ReceiveMessage(cNetSocket *so, unsigned char *data, bool UseMsgId, struct CustomData *cd, comm_type_t commType){ unsigned char netbuf[CWS_NETMSGSIZE]; int len=cCardClient::RecvMsg(so,netbuf,2); if(len!=2) { if(len>0) PRINTF(L_CC_NEWCAMD,"bad length %d != 2 on message length read",len); return 0; } const int mlen=WORD(netbuf,0,0xFFFF); if(mlen>CWS_NETMSGSIZE-2) { PRINTF(L_CC_NEWCAMD,"receive message buffer overflow"); return 0; } len=cCardClient::RecvMsg(so,netbuf+2,mlen); if(len!=mlen) { PRINTF(L_CC_NEWCAMD,"bad length %d != %d on message read",len,mlen); return 0; } len+=2; cTripleDes::Decrypt(netbuf,len); len-=sizeof(DES_cblock); if(XorSum(netbuf+2, len-2)) { PRINTF(L_CC_NEWCAMD,"checksum error"); return 0; } int returnLen=WORD(netbuf,5+cdLen,0x0FFF)+3; if(cd) memcpy(cd,&netbuf[4],cdLen); if(UseMsgId) { switch(commType) { case COMMTYPE_SERVER: netMsgId=WORD(netbuf,2,0xFFFF); break; case COMMTYPE_CLIENT: if(netMsgId!=WORD(netbuf,2,0xFFFF)) { PRINTF(L_CC_NEWCAMD,"bad msgid %04x != %04x ",netMsgId,WORD(netbuf,2,0xFFFF)); return -1; } break; default: PRINTF(L_CC_NEWCAMD,"unknown commType %x",commType); return -1; } } memcpy(data,netbuf+4+cdLen,returnLen); return returnLen;}bool cCardClientNewCamd::CmdSend(cNetSocket *so, net_msg_type_t cmd, comm_type_t commType){ unsigned char buffer[3]; buffer[0] = cmd; buffer[1] = buffer[2] = 0; return SendMessage(so,buffer,sizeof(buffer),false,0,commType);}int cCardClientNewCamd::CmdReceive(cNetSocket *so, comm_type_t commType){ unsigned char buffer[CWS_NETMSGSIZE]; if(ReceiveMessage(so,buffer,false,0,commType)!=3) return -1; return buffer[0];}bool cCardClientNewCamd::CanHandle(unsigned short SysId){ return (caId>=0 && SysId==caId) || cCardClient::CanHandle(SysId);}bool cCardClientNewCamd::Init(const char *config){ cMutexLock lock(this); int num=0; char key[29]; const char *tmp=key; if(!ParseStdConfig(config,&num) || sscanf(&config[num],":%31[^:]:%31[^:]:%28[^:]",username,password,key)!=3 || GetHex(tmp,configKey,sizeof(configKey),false)!=14) return false; char str[32]; PRINTF(L_CC_CORE,"%s: username=%s password=%s key=%s",name,username,password,HexStr(str,configKey,14)); return Immediate() ? Login() : true;}bool cCardClientNewCamd::Login(void){ so.Disconnect(); if(!so.Connect(hostname,port)) return false; InitVars(); unsigned char randData[14]; if(so.Read(randData,sizeof(randData))!=14) { PRINTF(L_CC_NEWCAMD,"no connect answer from %s:%d",hostname,port); so.Disconnect(); return false; } char *crPasswd=crypt(password,"$1$abcdefgh$"); unsigned char buffer[CWS_NETMSGSIZE]; const int userLen=strlen(username)+1; const int passLen=strlen(crPasswd)+1; // prepare the initial login message buffer[0] = MSG_CLIENT_2_SERVER_LOGIN; buffer[1] = 0; buffer[2] = userLen+passLen; memcpy(&buffer[3],username,userLen); memcpy(&buffer[3]+userLen,crPasswd,passLen); // XOR configKey with randData and expand the 14 byte result -> 16 byte PrepareLoginKey(desKey,randData,configKey); cTripleDes::ScheduleKey(); // set NewCS client identification struct CustomData cd; InitCustomData(&cd,0x5644,0); if(!SendMessage(&so,buffer,buffer[2]+3,true,&cd) || CmdReceive(&so)!=MSG_CLIENT_2_SERVER_LOGIN_ACK) { PRINTF(L_CC_NEWCAMD,"failed to login to cardserver for username %s (proto %d)",username,protoVers); if(NextProto()) return Login(); return false; } // create the session key (for usage later) unsigned char tmpkey[14]; memcpy(tmpkey, configKey, sizeof(tmpkey)); const int passStrLen=strlen(crPasswd); for(int i=0; i<passStrLen; ++i) tmpkey[i%14]^=crPasswd[i]; cTripleDes::Expand(desKey,tmpkey); // expand 14 byte key -> 16 byte cTripleDes::ScheduleKey(); if(!CmdSend(&so,MSG_CARD_DATA_REQ) || ReceiveMessage(&so,buffer,false)<=0) return false; if(buffer[0] == MSG_CARD_DATA) { caId=(buffer[4]<<8)+buffer[5]; LBSTARTF(L_CC_LOGIN); char str[32], str2[32]; LBPUT("%s: CaID=%04x admin=%d srvUA=%s",name,caId,buffer[3]==1,HexStr(str,&buffer[6],8)); if(!CheckNull(&buffer[6],8)) { emmProcessing=true; switch(caId>>8) { case 0x17: case 0x06: SetCard(new cCardIrdeto(buffer[6+4],&buffer[6+5])); break; case 0x01: SetCard(new cCardSeca(&buffer[6+2])); break; case 0x0b: SetCard(new cCardConax(&buffer[6+1])); break; case 0x09: SetCard(new cCardNDS(&buffer[6+4])); break; case 0x05: SetCard(new cCardViaccess(&buffer[6+3])); break; case 0x0d: SetCard(new cCardCryptoworks(&buffer[6+3])); break; case 0x18: if(caId==0x1801) { SetCard(new cCardNagra2(&buffer[6+4])); break; } // fall through to default default: LBPUT(" (unhandled)"); break; } } LBPUT(" provider"); for(int i=(buffer[14]-1)*11; i>=0; i-=11) { LBPUT(" %s/%s",HexStr(str2,&buffer[15+i],3),HexStr(str,&buffer[18+i],8)); if(!CheckNull(&buffer[18+i],8)) { switch(caId>>8) { case 0x17: case 0x06: AddProv(new cProviderIrdeto(buffer[18+i+4],&buffer[18+i+5])); break; case 0x01: AddProv(new cProviderSeca(&buffer[15+i+1],&buffer[18+i+4])); break; case 0x0b: AddProv(new cProviderConax(&buffer[18+i+1])); break; case 0x09: AddProv(new cProviderNDS(&buffer[18+i+4])); break; case 0x05: AddProv(new cProviderViaccess(&buffer[15+i],&buffer[18+i+4])); break; case 0x0d: AddProv(new cProviderCryptoworks(&buffer[18+i+3])); break; default: LBPUT(" <unhandled>"); break; } } } LBEND(); if(emmProcessing && !emmAllowed) PRINTF(L_CC_EMM,"%s: EMM disabled from config",name); } return true;}bool cCardClientNewCamd::ProcessECM(const cEcmInfo *ecm, const unsigned char *data, unsigned char *cw){ cMutexLock lock(this); if((!so.Connected() && !Login()) || !CanHandle(ecm->caId)) return false; so.Flush(); struct CustomData cd; InitCustomData(&cd,(unsigned short)ecm->prgId,0); if(!SendMessage(&so,data,SCT_LEN(data),true,&cd)) return false; unsigned char buffer[CWS_NETMSGSIZE]; switch(ReceiveMessage(&so,buffer,true)) { case 19: // ecm was decoded // check for zero cw, as newcs doesn't send both cw's every time if(!CheckNull(buffer+3+0,8)) memcpy(cw+0,buffer+3+0,8); if(!CheckNull(buffer+3+8,8)) memcpy(cw+8,buffer+3+8,8); return true; case 3: PRINTF(L_CC_ECM,"%s: card was not able to decode the channel",name); break; default: PRINTF(L_CC_NEWCAMD,"warning an unexpected error occurred"); break; } return false;}bool cCardClientNewCamd::ProcessEMM(int caSys, const unsigned char *data){ if(emmProcessing && emmAllowed) { cMutexLock lock(this); cAssembleData ad(data); if(MatchAndAssemble(&ad,0,0)) { while((data=ad.Assembled())) { int len=SCT_LEN(data); int id=msEMM.Get(data,len,0); if(id>0) { if(SendMessage(&so,data,len,true,0)) { unsigned char buffer[CWS_NETMSGSIZE]; ReceiveMessage(&so,buffer,true); } msEMM.Cache(id,true,0); } } return true; } } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -