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

📄 radegast.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <stdio.h>#include <string.h>#include "cc.h"#include "parse.h"#include "network.h"#include "version.h"// -- cCardClientRadegast ------------------------------------------------------#define MAXCAIDS 16class cCardClientRadegast : public cCardClient, private cIdSet {private:  cNetSocket so;  bool emmProcessing;  int caids[MAXCAIDS], numCaids;  //  void InitVars(void);  void SetLength(unsigned char *buff, int len);  int GetLength(const unsigned char *buff);  int GetNanoStart(const unsigned char *buff);  int GetMsgLength(const unsigned char *buff);  int GetMaxLength(const unsigned char *buff);  void StartMsg(unsigned char *buff, int cmd);  bool CheckLength(const unsigned char *buff, int len);  void AddNano(unsigned char *buff, int nano, int len, int value);  void AddNano(unsigned char *buff, int nano, int len, const unsigned char *data);  bool Send(const unsigned char *buff);  int Recv(unsigned char *buff, int len);protected:  virtual bool Login(void);public:  cCardClientRadegast(const char *Name);  virtual bool Init(const char *config);  virtual bool CanHandle(unsigned short SysId);    virtual bool ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw);  virtual bool ProcessEMM(int caSys, const unsigned char *data);  };static cCardClientLinkReg<cCardClientRadegast> __rdg("Radegast");cCardClientRadegast::cCardClientRadegast(const char *Name):cCardClient(Name),so(DEFAULT_CONNECT_TIMEOUT,7,DEFAULT_IDLE_TIMEOUT){  InitVars();}void cCardClientRadegast::InitVars(void){  emmProcessing=false; numCaids=0;}bool cCardClientRadegast::CanHandle(unsigned short SysId){  cMutexLock lock(this);  if(numCaids<=0) return cCardClient::CanHandle(SysId);  for(int i=0; i<numCaids; i++) if(caids[i]==SysId) return true;  return false;}bool cCardClientRadegast::Init(const char *config){  cMutexLock lock(this);  so.Disconnect();  return ParseStdConfig(config) && (Immediate() ? Login() : true);}void cCardClientRadegast::SetLength(unsigned char *buff, int len){  if(buff[0]<=0x90) buff[1]=min(255,len);  else { buff[1]=len>>8; buff[2]=len&0xFF; }}int cCardClientRadegast::GetLength(const unsigned char *buff){  return (buff[0]<=0x90) ? buff[1] : ((buff[1]<<8)+buff[2]);}int cCardClientRadegast::GetNanoStart(const unsigned char *buff){  return (buff[0]<=0x90) ? 2 : 3;}int cCardClientRadegast::GetMsgLength(const unsigned char *buff){  return GetLength(buff)+GetNanoStart(buff);}int cCardClientRadegast::GetMaxLength(const unsigned char *buff){  return (buff[0]<=0x90) ? 0xFF : 0xFFFF;}void cCardClientRadegast::StartMsg(unsigned char *buff, int cmd){  buff[0]=cmd;  SetLength(buff,0);}bool cCardClientRadegast::CheckLength(const unsigned char *buff, int len){  int l=GetLength(buff)+len+2;  int max=GetMaxLength(buff);  if(len>255) PRINTF(L_CC_RDGD,"cmd %02x: nano too long %d > 255",buff[0],len);  else if(l>max) PRINTF(L_CC_RDGD,"cmd %02x: msg too long %d > %d",buff[0],l,max);  return l<=max;}void cCardClientRadegast::AddNano(unsigned char *buff, int nano, int len, int value){  unsigned char hex[4];  for(int i=0; i<len; i++) hex[i]=value >> ((len-i-1)*8);  AddNano(buff,nano,len,hex);}void cCardClientRadegast::AddNano(unsigned char *buff, int nano, int len, const unsigned char *data){  int pos=GetLength(buff), off=GetNanoStart(buff);  if(pos<GetMaxLength(buff)) {    buff[off+pos]=nano;    buff[off+pos+1]=len;    memcpy(&buff[off+pos+2],data,len);    pos+=len+2;    }  SetLength(buff,pos);}bool cCardClientRadegast::Send(const unsigned char *buff){  return SendMsg(&so,buff,GetMsgLength(buff));}int cCardClientRadegast::Recv(unsigned char *buff, int len){  int n=RecvMsg(&so,buff,len);  if(n<1) return n;  int k=GetNanoStart(buff);  if(n<k) {    PRINTF(L_CC_RDGD,"bad length %d < %d on cmd read",n,k);    return -1;    }  k=GetMsgLength(buff);  if(n<k) {    PRINTF(L_CC_RDGD,"bad length %d < %d on nano read",n,k);    return -1;    }  return n;}bool cCardClientRadegast::Login(void){  so.Disconnect();  if(!so.Connect(hostname,port)) return false;  PRINTF(L_CC_LOGIN,"%s: connected to %s:%d",name,hostname,port);  InitVars();  unsigned char buff[512];  char hello[32];  snprintf(hello,sizeof(hello),"rdgd/vdr-sc-%s",ScVersion);  StartMsg(buff,0x90);			// RDGD_MSG_CLIENT_HELLO  AddNano(buff,1,strlen(hello),(unsigned char *)hello);	// RDGD_NANO_DESCR  int n;  if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false;  if(n>0 && buff[0]==0x91) {    PRINTF(L_CC_RDGD,"got server hello, assuming V4 mode");    StartMsg(buff,0x94);		// RDGD_MSG_CLIENT_CAP_REQ;    if(!Send(buff) || (n=Recv(buff,sizeof(buff)))<0) return false;    if(n>0 && buff[0]==0x95) {      LBSTARTF(L_CC_LOGIN);      LBPUT("radegast: got caps");      int caid;      for(int l=GetNanoStart(buff); l<n; l+=buff[l+1]+2) {        switch(buff[l]) {          case 0xE2:            LBPUT(" VERS %s",(char *)&buff[l+2]);            break;          case 0xE4: // CAP_NANO_CAID            if(numCaids>=MAXCAIDS) { l=n; break; } //stop processing            caid=(buff[l+2]<<8)+buff[l+3];            LBPUT(" CAID %04X",caid);            caids[numCaids++]=caid;            // XXX we should have EMM processing setup here, but as we don't            // XXX get any ua/sa we cannot filter EMM anyways            break;          case 0xE5: // CAP_NANO_PROVID            for(int i=0; i<buff[l+1]; i+=3)              LBPUT("/%02X%02X%02X",buff[l+2+i],buff[l+2+i+1],buff[l+2+i+2]);            break;          }        }      LBEND();      }    }  else PRINTF(L_CC_RDGD,"no server hello, assuming old mode");  if(emmProcessing && !emmAllowed)     PRINTF(L_CC_EMM,"%s: EMM disabled from config",name);  return true; }bool cCardClientRadegast::ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw){  cMutexLock lock(this);  so.Flush();  int len=SCT_LEN(source);  int keynr=-1;  switch(ecm->caId>>8) {    case 0x01: // Seca      keynr=source[7]&0x0F; break;    case 0x05: // Viaccess      keynr=source[4]&0x0F; break;    }  unsigned char buff[512], tmp[10];  StartMsg(buff,1);			// CMD_ECM_KEY_ASK  AddNano(buff,2,1,ecm->caId>>8);       // ECM_NANO_CAID_INDEX (old)  AddNano(buff,10,2,ecm->caId);		// ECM_NANO_CAID  sprintf((char *)tmp,"%08X",ecm->provId);  AddNano(buff,6,8,tmp);		// ECM_NANO_PROVIDER  if(keynr>=0) {    sprintf((char *)tmp,"%04X",keynr);    AddNano(buff,7,4,tmp);		// ECM_NANO_KEYNO    }  if(!CheckLength(buff,len)) return false;  AddNano(buff,3,len,source);		// ECM_NANO_PACKET  if(!Send(buff) || (len=Recv(buff,sizeof(buff)))<=0) return false;  if(buff[0]==2) {    for(int l=GetNanoStart(buff); l<len; l+=buff[l+1]+2) {      switch(buff[l]) {        case 0x05:          if(buff[l+1]==16) {            // check for zero cw, as someone may not send both cw's every time            if(!CheckNull(buff+l+ 2,8)) memcpy(cw+0,buff+l+ 2,8);            if(!CheckNull(buff+l+10,8)) memcpy(cw+8,buff+l+10,8);            return true;            }          else PRINTF(L_CC_RDGD,"wrong cw length %d from server",buff[l+1]);          break;        case 0x04:          PRINTF(L_CC_ECM,"%s: key not available from server",name);          break;        default:          PRINTF(L_CC_RDGD,"unknown nano %02x in ECM response",buff[l]);          break;        }      }    }  else PRINTF(L_CC_RDGD,"bad ECM response from server %02x != 02",buff[0]);  return false;}bool cCardClientRadegast::ProcessEMM(int caSys, const unsigned char *data){  if(emmProcessing && emmAllowed) {    cMutexLock lock(this);    int upd;    cProvider *p;    cAssembleData ad(data);    if(MatchAndAssemble(&ad,&upd,&p)) {      while((data=ad.Assembled())) {        int len=SCT_LEN(data);        int id=msEMM.Get(data,len,0);        if(id>0) {          unsigned char buff[512];          StartMsg(buff,0x41);			//          AddNano(buff,0x42,2,caSys);		// EMM_CAID          if(p) {            unsigned char tmp[10];            sprintf((char *)tmp,"%08X",(int)p->ProvId());            AddNano(buff,0x46,8,tmp);		// EMM_PROVID            }/*          if(upd==2 || upd==3) {            AddNano(buff,0x44,2,(unsigned char *)"aa");	// EMM_ADDR_VAL            }*/          AddNano(buff,0x45,1,upd==3 ? 0x11 : (upd==2 ? 0x12 : 0x13)); // EMM_ADDR_TYPE          if(CheckLength(buff,len)) {            AddNano(buff,0x43,len,data);	// EMM_CA_DATA            Send(buff);            }          msEMM.Cache(id,true,0);          }        }      return true;      }    }  return false;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -