|
SASC-NG
DVBSoftCAM
|
Inheritance diagram for cCardClientNewCamd:Public Member Functions | |
| cCardClientNewCamd (const char *Name) | |
| virtual bool | Init (const char *CfgDir) |
| virtual bool | Login (void) |
| 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) |
| cCardClientNewCamd::cCardClientNewCamd | ( | const char * | Name | ) |
Definition at line 198 of file newcamd.c.
References cNetSocket::SetRWTimeout(), and cCardClient::so.
:cCardClient(Name) { memset(username,0,sizeof(username)); memset(password,0,sizeof(password)); InitVars(); InitProtoVers(525); so.SetRWTimeout(20*1000); }
| bool cCardClientNewCamd::CanHandle | ( | unsigned short | SysId | ) | [virtual] |
Reimplemented from cCardClient.
Definition at line 349 of file newcamd.c.
Referenced by ProcessECM().
{
return (caId>=0 && (SysId==caId || (caId==0x1234 && SysId==0x1801))) || cCardClient::CanHandle(SysId);
}
| bool cCardClientNewCamd::Init | ( | const char * | CfgDir | ) | [virtual] |
Implements cCardClient.
Definition at line 354 of file newcamd.c.
References GetHex(), HexStr(), L_CC_CORE, cCardClient::Logout(), cCardClient::name, cCardClient::ParseStdConfig(), and PRINTF.
{
cMutexLock lock(this);
Logout();
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 true;
}
| bool cCardClientNewCamd::Login | ( | void | ) | [virtual] |
Implements cCardClient.
Definition at line 369 of file newcamd.c.
References cProviders::AddProv(), cCardClient::CaidsChanged(), CheckNull(), cNetSocket::Connect(), CWS_NETMSGSIZE, cTripleDes::desKey, cCardClient::emmAllowed, cTripleDes::Expand(), HexStr(), cCardClient::hostname, i, L_CC_EMM, L_CC_LOGIN, L_CC_NEWCAMD, LBEND, LBPUT, LBSTARTF, cCardClient::Logout(), MSG_CARD_DATA, MSG_CARD_DATA_REQ, MSG_CLIENT_2_SERVER_LOGIN, MSG_CLIENT_2_SERVER_LOGIN_ACK, cCardClient::name, cCardClient::port, PRINTF, cNetSocket::Read(), cTripleDes::ScheduleKey(), cIdSet::SetCard(), and cCardClient::so.
Referenced by ProcessECM().
{
Logout();
if(!so.Connect(hostname,port)) return false;
InitVars();
unsigned char randData[14];
if(so.Read(randData,sizeof(randData))<0) {
PRINTF(L_CC_NEWCAMD,"no connect answer from %s:%d",hostname,port);
Logout();
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
// this seems to conflict with other cardservers e.g. rqcs !!
//struct CustomData cd;
//InitCustomData(&cd,0x5644,0);
if(!SendMessage(buffer,buffer[2]+3,true) || CmdReceive()!=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(MSG_CARD_DATA_REQ) || ReceiveMessage(buffer,false)<=0) return false;
if(buffer[0] == MSG_CARD_DATA) {
int c=(buffer[4]<<8)+buffer[5];
if(c!=caId) CaidsChanged();
caId=c;
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 0x12:
case 0x18: if(caId>=0x1801 || caId==0x1234) {
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);
}
loginOK=true;
return true;
}
| bool cCardClientNewCamd::ProcessECM | ( | const cEcmInfo * | ecm, |
| const unsigned char * | data, | ||
| unsigned char * | Cw | ||
| ) | [virtual] |
Implements cCardClient.
Definition at line 473 of file newcamd.c.
References cEcmInfo::caId, CanHandle(), CheckNull(), cNetSocket::Connected(), CWS_NETMSGSIZE, cNetSocket::Flush(), L_CC_ECM, L_CC_NEWCAMD, Login(), cCardClient::name, cEcmInfo::prgId, PRINTF, SCT_LEN, and cCardClient::so.
{
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(data,SCT_LEN(data),true,&cd)) return false;
unsigned char buffer[CWS_NETMSGSIZE];
int n;
while((n=ReceiveMessage(buffer,true))==-2)
PRINTF(L_CC_NEWCAMD,"msg ID sync error. Retrying...");
switch(n) {
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,"unexpected server response (code %d)",n);
break;
}
return false;
}
| bool cCardClientNewCamd::ProcessEMM | ( | int | caSys, |
| const unsigned char * | data | ||
| ) | [virtual] |
Reimplemented from cCardClient.
Definition at line 502 of file newcamd.c.
References cAssembleData::Assembled(), cMsgCache::Cache(), CWS_NETMSGSIZE, cCardClient::emmAllowed, cMsgCache::Get(), L_CC_EMM, L_CC_NEWCAMD, cIdSet::MatchAndAssemble(), cCardClient::msEMM, PRINTF, and SCT_LEN.
{
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 || emmAllowed>1) {
if(SendMessage(data,len,true,0)) {
unsigned char buffer[CWS_NETMSGSIZE];
len=ReceiveMessage(buffer,true);
if(len>=3) {
if(!(buffer[1]&0x10))
PRINTF(L_CC_EMM,"EMM rejected by card");
}
else
PRINTF(L_CC_NEWCAMD,"unexpected server response (code %d)",len);
}
msEMM.Cache(id,true,0);
}
}
return true;
}
}
return false;
}