Pocket

前回UbuntuでのSoftCasに失敗したのだが、Ubuntuの元となったディストリビューションであるDebianでの成功例をコメント頂いたので、同様の方法での動作検証を行ってみた。

検証はUbuntu 13.04の64bitで行う。
今回はPT2のドライバ等のインストールは手動で行うことにした。

まずは、必要となるパッケージをダウンロード。
新しいバージョンだといろいろ問題がありそうなので、全て古いバージョンのものをインストールする。

Sponsored Links

まずは、以下のコマンドを実行。

sudo apt-get -y install libpcsc-perl
sudo apt-get -y install pkg-config unzip autoconf build-essential linux-headers-`uname -r`
wget http://ftp.jaist.ac.jp/pub/Linux/ubuntu//pool/universe/p/pcsc-tools/pcsc-tools_1.4.16-1_amd64.deb
wget http://launchpadlibrarian.net/70522552/pcscd_1.5.5-3ubuntu2.1_amd64.deb
wget http://security.ubuntu.com/ubuntu/pool/main/p/pcsc-lite/libpcsclite-dev_1.5.3-1ubuntu4.2_amd64.deb
wget http://security.ubuntu.com/ubuntu/pool/main/p/pcsc-lite/libpcsclite1_1.5.3-1ubuntu4.2_amd64.deb
wget http://ftp.jaist.ac.jp/pub/Linux/ubuntu//pool/universe/c/ccid/libccid_1.3.11-1_amd64.deb
sudo dpkg -i *.deb

なお、当たり前だが最後のコマンドは他のdebパッケージの置いてあるフォルダで行わないように。
で、パッケージインストール完了したら、以下を実行してapt-get updateを行ってもバージョンが上がらないようにする。

sudo touch /etc/apt/preferences.d/pcsc
sudo echo "package: libccid" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin: version 1.3.11-1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin-Priority: 900" >> /etc/apt/preferences.d/pcsc
sudo echo "package: libpcsclite-dev" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin: version 1.5.5-3ubuntu2.1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin-Priority: 900" >> /etc/apt/preferences.d/pcsc
sudo echo "package: libpcsclite1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin: version 1.5.5-3ubuntu2.1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin-Priority: 900" >> /etc/apt/preferences.d/pcsc
sudo echo "package: pcsc-tools" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin: version 1.4.16-1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin-Priority: 900" >> /etc/apt/preferences.d/pcsc
sudo echo "package: pcscd" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin: version 1.5.5-3ubuntu2.1" >> /etc/apt/preferences.d/pcsc
sudo echo "Pin-Priority: 900" >> /etc/apt/preferences.d/pcsc

パッケージ導入後、recpt1のインストールまでを進める。
●arib25

wget http://hg.honeyplanet.jp/pt1/archive/ec7c87854f2f.zip
unzip ec7c87854f2f.zip
cd pt1-ec7c87854f2f/arib25/src/
make
sudo make install

●pt2ドライバ&recpt1

wget http://hg.honeyplanet.jp/pt1/archive/tip.tar.bz2
tar jxf tip.tar.bz2
cd `ls -tr | tail -1`/driver
sed -i.bk "s/static char version\[\] __devinitdata =/static char version\[\] =/" ./pt1_pci.c
sed -i "s/static int __devinit pt1_pci_init_one (struct pci_dev \*pdev,/static int pt1_pci_init_one (struct pci_dev \*pdev,/" ./pt1_pci.c
sed -i "s/static void __devexit pt1_pci_remove_one(struct pci_dev \*pdev)/static void pt1_pci_remove_one(struct pci_dev \*pdev)/" ./pt1_pci.c
sed -i "s/\t.remove\t\t= __devexit_p(pt1_pci_remove_one),/\t.remove\t\t= pt1_pci_remove_one,/" ./pt1_pci.c
make
sudo make install
cd ../recpt1
./autogen.sh
./configure --enable-b25
make
sudo make install

●既存のpt2ドライバを無効化

echo '' >> /etc/modprobe.d/blacklist.conf
echo 'blacklist earth-pt1' >> /etc/modprobe.d/blacklist.conf</pre>

この辺で一度リブートしとく。

ドライバ入れても、再起動しないとPT2を認識しないからだ。

次に、以下コマンドを実行してSoftCasをダウンロード、解凍する。

wget http://bit.ly/KBSCl9
mv KBSCl9 KBSCl9.zip
unzip KBSCl9.zip
cd softcas/

解凍後、移動したフォルダ内で以下のファイルを作成していく。
今回、Makefileにも修正が必要となるためソースをそのまんま記述。

●winscard.cpp

//  Put the following files in the same folder:
//      Crypto.cpp, Crypto.h, Decoder-ECM.cpp, Decoder.h, Global.h
//      Keys.cpp, Keys.h, Keyset.cpp, Keyset.h
//  You should modify "Size" in Decoder-ECM.cpp l42 to "Size-3"

#include <string.h>
#include <PCSC/winscard.h>
#define htons htons_
#define ntohs ntohs_

#include "Global.h"
#include "Keys.h"
#include "Decoder.h"

#define CHAR    char

extern"C"{

void __attribute__ ((constructor)) SCardVCasInit(void) {
    BCAS::Keys::RegisterAll();
}

LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
{
        *phContext=(SCARDCONTEXT)0x35313239;
        return SCARD_S_SUCCESS;
}

LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders)
{
    CHAR r[]="@OishiiSlurper\0";
    if(mszReaders)memcpy(mszReaders,r,sizeof r);
    *pcchReaders=sizeof r/sizeof r[0];
    return SCARD_S_SUCCESS;
}

LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol)
{
    *phCard=(SCARDHANDLE)0x35313239;
    *pdwActiveProtocol=SCARD_PROTOCOL_T1;
    return SCARD_S_SUCCESS;
}

LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength)
{
    switch(pbSendBuffer[1])
    {
    case 0x30:{
        BYTE r[]={
            0x00,0x39,0x00,0x00,0x21,0x00,0x00,0x05, 0xc0,0xff,0xee,0xc0,0xff,0xee,0x01,0x50,
            0x36,0x31,0x04,0x66,0x4b,0x17,0xea,0x5c, 0x32,0xdf,0x9c,0xf5,0xc4,0xc3,0x6c,0x1b,
            0xec,0x99,0x39,0x21,0x68,0x9d,0x4b,0xb7, 0xb7,0x4e,0x40,0x84,0x0d,0x2e,0x7d,0x98,
            0xfe,0x27,0x19,0x99,0x19,0x69,0x09,0x11, 0x01,0x02,0x01,0x90,0x00};
        memcpy(pbRecvBuffer,r,sizeof r);
        *pcbRecvLength=sizeof r;
        break;}
    case 0x32:{
        BYTE r[]={
            0x00,0x0f,0x00,0x00,0x21,0x00,0x01,0x54, 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x90,0x00};
        memcpy(pbRecvBuffer,r,sizeof r);
        *pcbRecvLength=sizeof r;
        break;}
    case 0x34:{
        BYTE r[]={
            0x00,0x15,0x00,0x00,0x08,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
            0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x90, 0x00};
        BCAS::Decoder::DecodeECM(pbSendBuffer+5,pbSendBuffer[4],r+6,NULL);
        memcpy(pbRecvBuffer,r,sizeof r);
        *pcbRecvLength=sizeof r;
        break;}
    case 0x80:{
        BYTE r[]={
                0x00,0x10,0x00,0x00,0xA1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00};
        memcpy(pbRecvBuffer,r,sizeof r);
        *pcbRecvLength=sizeof r;
        break;}
    default:{
        BYTE r[]={
            0x00,0x04,0x00,0x00,0xa1,0xfe,0x90,0x00};
        memcpy(pbRecvBuffer,r,sizeof r);
        *pcbRecvLength=sizeof r;
        break;}
    }
    return SCARD_S_SUCCESS;
}

LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition){return SCARD_S_SUCCESS;}

LONG SCardFreeMemory(SCARDCONTEXT,LPCVOID){return SCARD_S_SUCCESS;}

LONG SCardReleaseContext(SCARDCONTEXT){return SCARD_S_SUCCESS;}

//LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,LPSCARD_READERSTATE rgReaderStates, DWORD cReaders){return SCARD_S_SUCCESS; }

SCARD_IO_REQUEST g_rgSCardT1Pci_;
//SCARD_IO_REQUEST g_rgSCardT1Pci;

}
</pcsc></string>

●Makefile

PROGRAM = libpcsclite.so.1.0.0
SRCS = winscard.cpp Crypto.cpp  Decoder-ECM.cpp  Keys.cpp  Keyset.cpp
OBJS = $(subst .cpp,.o,$(SRCS))

RM := rm
CXX := g++
CC := g++

CPPFLAGS = -g -fPIC -O2 -I /usr/include/PCSC
LDFLAGS = -g -fPIC -shared -Wl,-soname=libpcsclite.so.1

$(PROGRAM): $(OBJS)
        $(LINK.o) $^ $(LOADLIBES) -shared -o $@

.PHONY: clean

clean:

上記2ファイルを設置後、コンパイルを実行し既存の「libpcsclite.so.1.0.0」と入れ替える。

make
cp libpcsclite.so.1.0.0 /lib/libpcsclite.so.1.0.0
ldconfig
これで録画、再生ができるかテスト。

recpt1 –b25 –strip 22 120 test.ts
結果…

root@testpt2:/home/test/softcas# recpt1 --b25 --strip 22 120 test.ts
recpt1: symbol lookup error: /usr/local/lib/libarib25.so.0: undefined symbol: g_rgSCardT1Pci
root@testpt2:/home/test/softcas#

(゚Д゚)

(;つД⊂)ゴシゴシ

(;゚Д゚)

なん…だと…

どうやら、arib25の実行において「libpcsclite.so.1.0.0」が使用されていたようだ。上書きした「libpcsclite.so.1.0.0」を元に戻したところ、通常のarib25が動かない状態での録画はできた。

一応、この方法でDebianはできたという話だけど…
発生するトラブルの起因として考えられるのって、カードの有無に関する制限が他のディストリよりもきついからのような気がする。

正直、LinuxでSoftCasを使用したい場合はUbuntuは諦めてCentOSかDebianに移行した方がいいと思う。
どうしてもUbuntuでやるなら、SoftCasではなくSoftarib25を採用することを薦める。(ただ、Softarib25はコンパイル実行時点においてカードリーダーとB-CASカードが必須だったような気がする。gitでクローン可能なので、ソースへのリンクは貼っておいた。)

物理的に別サーバを稼働できず、かつUbuntuを潰せないならばKVMやVMwareESXiでPT2(ESXiの場合はPT3。PT2はパススルーしてもうまく使えないので。)を載せて、ゲストOSにパススルーしてCentOSやWindows等で使った方が現実的な気がする。Ubuntuはゲストとして別途立ち上げるか、KVMホストとして使えばいい。

Pocket

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

This article has 5 comments

  1. Anonymous Reply

    初めまして。 ubuntu12.04LTS 64bit で実験してみました。 ここに書いてある手順で実施したところ,同じ結果になりました。
    そこで,winscard.cppのコメントアウトを元に戻してmakeしてみたらエラーを吐き出さず,出来上がった libpcsclite.so.1.0.0 で録画実験したところ,あっさりと・・・

    linux は詳しく無いので,なぜなのかわかりませんが・・・

  2. Anonymous Reply

    libpcscliteの使い方の問題について書き込みます。

    libpcscliteの仕様が変わったことで、クライアント側?にもコードの書き換えが必要になったようですね。
    そのうち、CentOS側にも同様の問題が発生するかと思います。
    (新しいライブラリがCentOSに含まれた場合ですが)

    libpcscliteのヘッダファイルを見ると、
    2つ目のコメントアウトされている変数は、ライブラリ側から参照されているような気がするので、コメントアウトは不味いかと。
    クライアント側のプログラムが動作しないのは、これが原因ではないでしょうか?

    上述の匿名さんの例では、このページの記述に基づいてlibpcscliteを古いものに置き換えていたため、
    クライアント側のソースを元に戻してもコンパイルエラーが出なかったのかも。
    (もちろん古いlibpcscliteで動かすのであれば、今までのクライアントのコードで大丈夫です)

    新しいlibpcscliteと動かすのであれば、下記のページに従って修正すると良いのかも知れません。
    http://lists.alioth.debian.org/pipermail/pcsclite-cvs-commit/2011-May/005288.html

    -LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,LPSCARD_READERSTATE_A rgRe
    aderStates, DWORD cReaders){return SCARD_S_SUCCESS; }
    +LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,LPSCARD_READERSTATE rgRead
    erStates, DWORD cReaders){return SCARD_S_SUCCESS; }

    -SCARD_IO_REQUEST g_rgSCardT1Pci;
    +const SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, sizeof(SCARD_IO_REQUEST) };

    • Blacknon Reply

      コメント有難うございます。
      ライブラリの仕様変更によるものでしたか。

      今はあまり時間を作れないのですが、暇を見て試したいと思います。

    • Blacknon Reply

      おぉ、ありがとうございます。
      拝見させて頂きました。参考にさせて頂きます!

Leave a Comment

メールアドレスが公開されることはありません。