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

📄 camd.cpp

📁 DVB-S的softcam源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * 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 <byteswap.h>#include "cc.h"#include "system-common.h"#include "data.h"#include "network.h"#include "crypto.h"#include "misc.h"#include "parse.h"#include "common.h"#include <openssl/md5.h>//#define DEBUG_EXTRA#ifdef DEBUG_EXTRA#define de(x) { x; }#else#define de(x) ;#endif#define CCVERSION "3.37"#define CCTIMEOUT 5000 // ms// -- cCardClientCommon --------------------------------------------------------class cCardClientCommon : public cCardClient, public cAES, protected cIdSet {private:  bool conReply, logReply, doAES;  bool exclusive;  int minMsgLen;  cCondVar sleepCond;  cTimeMs time;protected:  cNetSocket so;  bool emmProcessing;  char username[11], password[11];  int CAID;  unsigned char lastEmmReq[32];  //  virtual bool Login(void);  bool ParseKeyConfig(const char *config, int *num);  bool ParseUserConfig(const char *config, int *num);  virtual bool SendMsg(cNetSocket *so, const unsigned char *data, int len);  virtual int RecvMsg(cNetSocket *so, unsigned char *data, int len, int to=-1);  void HandleEMMRequest(const unsigned char *buff, int len);public:  cCardClientCommon(const char *Name, bool ConReply, bool LogReply, bool DoAES, int MinMsgLen);  virtual bool CanHandle(unsigned short SysId);  virtual bool Init(const char *config);  virtual bool ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw);//  virtual bool ProcessEMM(int caSys, const unsigned char *source);  };cCardClientCommon::cCardClientCommon(const char *Name, bool ConReply, bool LogReply, bool DoAES, int MinMsgLen):cCardClient(Name),so(DEFAULT_CONNECT_TIMEOUT,CCTIMEOUT/1000,DEFAULT_IDLE_TIMEOUT){  conReply=ConReply; logReply=LogReply; doAES=DoAES; minMsgLen=MinMsgLen;  emmProcessing=exclusive=false;  CAID=0;  memset(lastEmmReq,0,sizeof(lastEmmReq));}bool cCardClientCommon::ParseUserConfig(const char *config, int *num){  int startNum=*num;  if(sscanf(&config[*num],":%10[^:]:%10[^:]%n",username,password,num)==2) {    *num+=startNum;    dc(printf("cc-%s: username=%s password=%s\n",name,username,password));    return true;    }  return false;}bool cCardClientCommon::ParseKeyConfig(const char *config, int *num){  char hexkey[33];  int startNum=*num;  if(sscanf(&config[*num],":%32[^:]%n",hexkey,num)==1) {    *num+=startNum;    dc(printf("cc-%s: key=%s\n",name,hexkey))    unsigned char binkey[16];    memset(binkey,0,sizeof(binkey));    const char *line=hexkey;    int n=GetHex(line,binkey,sizeof(binkey),false);    if(n!=(int)sizeof(binkey))      dc(printf("cc-%s: warning AES key not %d bytes long\n",name,sizeof(binkey)))    SetKey(binkey);    }  return true;}bool cCardClientCommon::SendMsg(cNetSocket *so, const unsigned char *data, int len){  unsigned char *buff2 = new unsigned char[minMsgLen];  if(len<minMsgLen) {    memcpy(buff2,data,len);    memset(buff2+len,0,minMsgLen-len);    data=buff2; len=minMsgLen;    }  unsigned char *buff = new unsigned char[len+16];  const int l=Encrypt(data,len,buff);  if(l>0) { data=buff; len=l; }  return cCardClient::SendMsg(so,data,len);}int cCardClientCommon::RecvMsg(cNetSocket *so, unsigned char *data, int len, int to){  int n=cCardClient::RecvMsg(so,data,len,to);  if(n>0) Decrypt(data,n);  return n;}bool cCardClientCommon::CanHandle(unsigned short SysId){  return (emmProcessing && SysId==CAID) || cCardClient::CanHandle(SysId);}bool cCardClientCommon::Init(const char *config){  cMutexLock lock(this);  so.Disconnect();  int num=0;  if(ParseStdConfig(config,&num) &&     ParseUserConfig(config,&num) &&     (!doAES || ParseKeyConfig(config,&num))) {    return (emmAllowed && logReply && Immediate()) ? Login() : true;    }  return false;}bool cCardClientCommon::Login(void){  so.Disconnect();  if(!so.Connect(hostname,port)) return false;  dc(printf("cc-%s: connected to %s:%d (%s)\n",name,hostname,port,name))  emmProcessing=false;  unsigned char buff[128];  if(conReply) {    if(RecvMsg(&so,buff,sizeof(buff))!=16) {      dc(printf("cc-%s: bad connect reply\n",name));      return false;      }    }  memset(buff,0,32);  int user_len=strlen(username)+1;  memcpy(buff+1,username,user_len);  int pass_len=strlen(password)+1;  memcpy(buff+1+user_len+1,password,pass_len);  int vers_len=strlen(CCVERSION)+1;  memcpy(buff+1+user_len+pass_len+1,CCVERSION,vers_len);  dc(printf("cc-%s: login user='%s' password=hidden version=%s\n",name,username,CCVERSION))  if(!SendMsg(&so,buff,32)) return false;  if(emmAllowed && logReply) {    dc(printf("cc-%s: waiting for login reply ...\n",name))    int r=RecvMsg(&so,buff,sizeof(buff));    if(r>0) HandleEMMRequest(buff,r);    }  dc(printf("cc-%s: login done\n",name))  return true;}void cCardClientCommon::HandleEMMRequest(const unsigned char *buff, int len){  if(len>=13 && buff[0]==0 && !CheckNull(buff,len) && memcmp(buff,lastEmmReq,13)) {    CAID=buff[1]*256+buff[2];    ResetIdSet();    SetCard(new cCardIrdeto(buff[6],&buff[3]));    AddProv(new cProviderIrdeto(0,&buff[7]));    AddProv(new cProviderIrdeto(2,&buff[10]));    memcpy(lastEmmReq,buff,13);#ifdef DEBUG_CC    printf("cc-%s: CAID: %04x HexSerial: %02X%02X%02X, HexBase: %02X\n"           "cc-%s: Provider00: %02X%02X%02X, Provider10: %02X%02X%02X\n",           name,CAID,buff[3],buff[4],buff[5],buff[6],           name,buff[7],buff[8],buff[9],buff[10],buff[11],buff[12]);    if(!emmAllowed) printf("cc-common: EMM disabled from config\n");#endif    emmProcessing=true;    }}/*bool cCardClientCommon::ProcessEMM(int caSys, const unsigned char *source){  if(emmProcessing && emmAllowed) {    cMutexLock lock(this);    if(MatchEMM(source)) {      const int length=SCT_LEN(source);      int id=msEMM.Get(source,length,0);      if(id>0) {        unsigned char buff[length+32];        buff[0]=0x03;        buff[1]=(caSys>>8);        buff[2]=(caSys&0xFF);        memcpy(buff+3,((cCardIrdeto *)card)->hexSer,3);        buff[6]=((cCardIrdeto *)card)->hexBase;        memcpy(&buff[7],source,length);        //dc(printf("cc-%s: sending EMM for caid 0x%04X\n",name,caSys))        SendMsg(&so,buff,length+7);        msEMM.Cache(id,true,0);        }      return true;      }    }  return false;}*/bool cCardClientCommon::ProcessECM(const cEcmInfo *ecm, const unsigned char *source, unsigned char *cw){  Lock();  bool res=false;  while(exclusive) sleepCond.Wait(*this);  if((so.Connected() || Login()) && (!emmProcessing || CanHandle(ecm->caId))) {    const int length=SCT_LEN(source);    unsigned char *buff = new unsigned char[length+32];    int n;    while((n=RecvMsg(&so,buff,16,0))>0) HandleEMMRequest(buff,n);    buff[0]=0x02;    buff[1]=(ecm->caId>>8);    buff[2]=(ecm->caId&0xFF);    memset(&buff[3],0,4);    memcpy(&buff[7],source,length);    if(SendMsg(&so,buff,length+7)) {      exclusive=true;      time.Set(CCTIMEOUT);      do {        sleepCond.TimedWait(*this,50);        while((n=RecvMsg(&so,buff,32,0))>0) {          if(n>=21 && buff[0]==2) {            if(!CheckNull(buff+5,16)) {              if(!res) {                memcpy(cw,buff+5,16);                res=true;                }              else dc(printf("cc-camd33: unexpected CW packet\n"))              }            else {              d(printf("cc-camd33: server is unable to handle ECM\n"))              n=-1;              break;              }            }          else HandleEMMRequest(buff,n);          }        } while(!res && n>=0 && !time.TimedOut());      if(!res && time.TimedOut()) d(printf("cc-camd33: CW request timed out\n"))      exclusive=false;      sleepCond.Broadcast();      }    }  Unlock();  return res;}// -- cCardClientCamd33 --------------------------------------------------------class cCardClientCamd33 : public cCardClientCommon {public:  cCardClientCamd33(const char *Name);  };static cCardClientLinkReg<cCardClientCamd33> __camd33("Camd33");cCardClientCamd33::cCardClientCamd33(const char *Name):cCardClientCommon(Name,true,true,true,0){}// -- cCardClientCardd ---------------------------------------------------------class cCardClientCardd : public cCardClientCommon {public:  cCardClientCardd(const char *Name);  };static cCardClientLinkReg<cCardClientCardd> __cardd("Cardd");cCardClientCardd::cCardClientCardd(const char *Name):cCardClientCommon(Name,false,true,false,96){}// -- cCardClientBuffy ---------------------------------------------------------#define MAX_CAIDS 16class cCardClientBuffy : public cCardClientCommon {private:  unsigned short CAIDs[MAX_CAIDS], numCAIDs;protected:  virtual bool Login(void);public:  cCardClientBuffy(const char *Name);  virtual bool Init(const char *config);  virtual bool CanHandle(unsigned short SysId);  };static cCardClientLinkReg<cCardClientBuffy> __buffy("Buffy");cCardClientBuffy::cCardClientBuffy(const char *Name):cCardClientCommon(Name,true,false,true,0){}bool cCardClientBuffy::Init(const char *config){  cMutexLock lock(this);  if(cCardClientCommon::Init(config)) {    return Immediate() ? Login() : true;    }  return false;}bool cCardClientBuffy::CanHandle(unsigned short SysId){  cMutexLock lock(this);  for(int i=0; i<numCAIDs; i++) if(CAIDs[i]==SysId) return true;  return false;}bool cCardClientBuffy::Login(void){  cMutexLock lock(this);  if(!cCardClientCommon::Login()) return false;  unsigned char buff[128];  memset(buff,0,sizeof(buff));  buff[0]=0x0A;  if(!SendMsg(&so,buff,32)) return false;  int n=RecvMsg(&so,buff,sizeof(buff));  if(n<0) return false;  for(int i=1; i<n && numCAIDs<MAX_CAIDS; i+=2) {    unsigned short caid=(buff[i+1]<<8)+buff[i];    if(caid==0xFFFF) break;    if(caid) CAIDs[numCAIDs++]=caid;

⌨️ 快捷键说明

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