⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newcamd.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -