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

📄 newcamd.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 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 <stdlib.h>#include <crypt.h>#include <byteswap.h>#include <vdr/thread.h>#include "cc.h"#include "network.h"#include "misc.h"#include "parse.h"#include <openssl/des.h>#define CWS_NETMSGSIZE 240// -- cTripleDes ---------------------------------------------------------------class cTripleDes {private:  DES_key_schedule ks1,ks2;  //  void SetOddParity(unsigned char *key); // key must be 16 bytes!protected:  unsigned char desKey[16];  //  void ScheduleKey(void);  int PadMessage(unsigned char *data, int len);  void Expand(unsigned char *expanded, const unsigned char *normal); // 14 byte key input, 16 byte expanded output  void Decrypt(unsigned char *data, int len);  const unsigned char *Encrypt(const unsigned char *data, int len, unsigned char *crypt);  };void cTripleDes::SetOddParity(unsigned char *key){  DES_set_odd_parity((DES_cblock *)&key[0]); // set odd parity on both keys  DES_set_odd_parity((DES_cblock *)&key[8]); // }void cTripleDes::ScheduleKey(void){  DES_key_sched((DES_cblock *)&desKey[0],&ks1);  DES_key_sched((DES_cblock *)&desKey[8],&ks2);}void cTripleDes::Expand(unsigned char *expand, const unsigned char *normal){  expand[0]  =   normal[0] & 0xfe;  expand[1]  = ((normal[0] << 7) | (normal[1] >> 1)) & 0xfe;  expand[2]  = ((normal[1] << 6) | (normal[2] >> 2)) & 0xfe;  expand[3]  = ((normal[2] << 5) | (normal[3] >> 3)) & 0xfe;  expand[4]  = ((normal[3] << 4) | (normal[4] >> 4)) & 0xfe;  expand[5]  = ((normal[4] << 3) | (normal[5] >> 5)) & 0xfe;  expand[6]  = ((normal[5] << 2) | (normal[6] >> 6)) & 0xfe;  expand[7]  =   normal[6] << 1;  expand[8]  =   normal[7] & 0xfe;  expand[9]  = ((normal[7] << 7)  | (normal[8] >> 1)) & 0xfe;  expand[10] = ((normal[8] << 6)  | (normal[9] >> 2)) & 0xfe;  expand[11] = ((normal[9] << 5)  | (normal[10] >> 3)) & 0xfe;  expand[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;  expand[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;  expand[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;  expand[15] =   normal[13] << 1;  SetOddParity(expand);}int cTripleDes::PadMessage(unsigned char *data, int len){  DES_cblock padBytes;  unsigned char noPadBytes;  noPadBytes = (8 - ((len - 1) % 8)) % 8;  if(len+noPadBytes+1 >= CWS_NETMSGSIZE-8) {    PRINTF(L_CC_NEWCAMD,"message overflow in cTripleDes::PadMessage");    return -1;    }  srand(time(NULL)); // make sure the random generator is initialized  DES_random_key((DES_cblock *)padBytes);  memcpy(data+len,padBytes,noPadBytes); len+=noPadBytes;  data[len]=XorSum(data+2,len-2);  return len+1;}const unsigned char *cTripleDes::Encrypt(const unsigned char *data, int len, unsigned char *crypt){  DES_cblock ivec;  DES_random_key((DES_cblock *)ivec);  memcpy(crypt+len,ivec,sizeof(ivec));  DES_ede2_cbc_encrypt(data+2,crypt+2,len-2,&ks1,&ks2,(DES_cblock *)ivec,DES_ENCRYPT);  return crypt;}void cTripleDes::Decrypt(unsigned char *data, int len){  if((len-2) % 8 || (len-2)<16) {    PRINTF(L_CC_NEWCAMD,"warning: encrypted data size mismatch");    return;    }  DES_cblock ivec;  len-=sizeof(ivec); memcpy(ivec, data+len, sizeof(ivec));  DES_ede2_cbc_encrypt(data+2,data+2,len-2,&ks1,&ks2,(DES_cblock *)ivec,DES_DECRYPT);}// -- cNewCamdClient -----------------------------------------------------------#define USERLEN        32#define PASSWDLEN      32#define CWS_FIRSTCMDNO 0xe0typedef enum {  MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,  MSG_CLIENT_2_SERVER_LOGIN_ACK,  MSG_CLIENT_2_SERVER_LOGIN_NAK,  MSG_CARD_DATA_REQ,  MSG_CARD_DATA,  MSG_SERVER_2_CLIENT_NAME,  MSG_SERVER_2_CLIENT_NAME_ACK,  MSG_SERVER_2_CLIENT_NAME_NAK,  MSG_SERVER_2_CLIENT_LOGIN,  MSG_SERVER_2_CLIENT_LOGIN_ACK,  MSG_SERVER_2_CLIENT_LOGIN_NAK,  MSG_ADMIN,  MSG_ADMIN_ACK,  MSG_ADMIN_LOGIN,  MSG_ADMIN_LOGIN_ACK,  MSG_ADMIN_LOGIN_NAK,  MSG_ADMIN_COMMAND,  MSG_ADMIN_COMMAND_ACK,  MSG_ADMIN_COMMAND_NAK  } net_msg_type_t;typedef enum {  COMMTYPE_CLIENT,  COMMTYPE_SERVER  } comm_type_t;struct CustomData {  union {    struct {      unsigned short prgId; // Big-Endian      unsigned char data[6];      } V525;    struct {      unsigned int prgId;  // Big-Endian      } V520;    };  };class cCardClientNewCamd : public cCardClient, private cTripleDes, private cIdSet {private:  cNetSocket so;  unsigned char configKey[14];  unsigned short netMsgId;  int caId, protoVers, cdLen;  bool emmProcessing;  char username[USERLEN], password[PASSWDLEN];  //  void InitVars(void);  void InitProtoVers(int vers);  bool NextProto(void);  void InitCustomData(struct CustomData *cd, const unsigned short PrgId, const unsigned char *data);  void PrepareLoginKey(unsigned char *deskey, const unsigned char *rkey, const unsigned char *ckey);protected:  virtual bool Login(void);public:  cCardClientNewCamd(const char *Name);  // Client Helper functions  bool SendMessage(cNetSocket *so, const unsigned char *data, int len, bool UseMsgId, const struct CustomData *cd=0, comm_type_t commType=COMMTYPE_CLIENT);  int ReceiveMessage(cNetSocket *so, unsigned char *data, bool UseMsgId, struct CustomData *cd=0, comm_type_t commType=COMMTYPE_CLIENT);  bool CmdSend(cNetSocket *so, net_msg_type_t cmd,  comm_type_t commType=COMMTYPE_CLIENT);  int CmdReceive(cNetSocket *so, comm_type_t commType=COMMTYPE_CLIENT);  //   virtual bool Init(const char *CfgDir);  virtual bool CanHandle(unsigned short SysId);    virtual bool ProcessECM(const cEcmInfo *ecm, const unsigned char *data, unsigned char *Cw);  virtual bool ProcessEMM(int caSys, const unsigned char *data);  };static cCardClientLinkReg<cCardClientNewCamd> __ncd("Newcamd");cCardClientNewCamd::cCardClientNewCamd(const char *Name):cCardClient(Name),so(DEFAULT_CONNECT_TIMEOUT,20,DEFAULT_IDLE_TIMEOUT){  memset(username,0,sizeof(username));  memset(password,0,sizeof(password));  InitVars();  InitProtoVers(525);}void cCardClientNewCamd::InitVars(void){  netMsgId=0; caId=-1; emmProcessing=false;  ResetIdSet();}void cCardClientNewCamd::InitProtoVers(int vers){  switch(vers) {    case 525: protoVers=525; cdLen=8; break;    default:  protoVers=520; cdLen=4; break;    }  PRINTF(L_CC_NEWCAMD,"now using protocol version %d (cdLen=%d)",protoVers,cdLen);}bool cCardClientNewCamd::NextProto(void){  switch(protoVers) {    case 525: InitProtoVers(520); break;    default:  return false;    }  return true;}void cCardClientNewCamd::InitCustomData(struct CustomData *cd, const unsigned short PrgId, const unsigned char *data){  if(cd) {    switch(protoVers) {      case 525:        cd->V525.prgId=bswap_16(PrgId);        if(data) memcpy(cd->V525.data,data,sizeof(cd->V525.data));        else memset(cd->V525.data,0,sizeof(cd->V525.data));        break;      default:        cd->V520.prgId=bswap_32((unsigned int)PrgId);        break;      }    }}void cCardClientNewCamd::PrepareLoginKey(unsigned char *deskey, const unsigned char *rkey, const unsigned char *ckey){  unsigned char tmpkey[14];  for (int i=0; i<(int)sizeof(tmpkey); i++) { tmpkey[i]=rkey[i]^ckey[i]; }  Expand(deskey, tmpkey);}bool cCardClientNewCamd::SendMessage(cNetSocket *so, const unsigned char *data, int len, bool UseMsgId, const struct CustomData *cd, comm_type_t commType){

⌨️ 快捷键说明

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