サーバ証明書をゲットして、期限を表示するプログラム
前記事のLet’s Encryptの話と関連してます。
実行したときのスタイルは、

こんな感じです。下側に表示されているのが”本サイト”でございます。期限が切れるまでの残りの日数が71日ということです。30日を切ると赤での表示になります。
さて、フォームのデザインは、

このように、TIdHTTPとTIdSSLIOHandlerSocketOpenSSLをドロップしてください。
Unit1.cppは、
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TLabel* url[3];
TLabel* expi[3];
TLabel* days[3];
String urls[3] = { "https://mars.rist.u-tokai.ac.jp",
"https://ghost.mydns.jp",
"https://ruined.mydns.jp"};
int servercount = 2;
int index=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
for( int i = 0 ; i < servercount ; i++ ){
url[i] = new TLabel(Form1);
url[i]->Parent = Form1;
url[i]->Left = 20;
url[i]->Top = 10 + 60*i;
url[i]->Width = 100;
url[i]->Height = 60;
url[i]->Font->Size = 12;
url[i]->Caption = urls[i];
expi[i] = new TLabel(Form1);
expi[i]->Parent = Form1;
expi[i]->Left = 280;
expi[i]->Top = 10 + 60*i;
expi[i]->Width = 100;
expi[i]->Height = 60;
expi[i]->Font->Size = 12;
expi[i]->Caption = "exp. " + IntToStr(i);
days[i] = new TLabel(Form1);
days[i]->Parent = Form1;
days[i]->Left = 550;
days[i]->Top = 10 + 60*i;
days[i]->Width = 100;
days[i]->Height = 60;
days[i]->Font->Size = 12;
days[i]->Caption = "days " + IntToStr(i);
}
IdHTTP1->ConnectTimeout = 5000; // can I do this and effective?
/*
You can also try setting TIdHTTP.Request.Pragma := 'no-cache'; before calling TIdHTTP.Get(). –
Remy Lebeau
Oct 28, 2013 at 22:46
*/
IdHTTP1->Request->Pragma = "no-cache";
for( int i = 0 ; i < servercount ; i++ ){
//String Response;
index = i;
TMemoryStream* ms = new TMemoryStream(); //取得したデータを格納する
expi[index]->Caption = "Working....";
try {
IdHTTP1->Get(urls[i], ms);
}
catch(const Exception& e)
{
//ShowMessage(e.ClassName());
expi[index]->Caption ="Dead";
days[index]->Caption ="NA";
continue;
//printf("Caught C++ Exception: %s :\n", e.msg());
}
}
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::IdSSLIOHandlerSocketOpenSSL1VerifyPeer(TIdX509 *Certificate,
bool AOk, int ADepth, int AError)
{
TDateTime now = Now();
TDateTime exp = Certificate->notAfter;
expi[index]->Caption = Certificate->notAfter;// exp date
int idays = DaysBetween(now,exp);
if( idays < 30 )
days[index]->Font->Color = clRed;
else
days[index]->Font->Color = clBlack;
days[index]->Caption =IntToStr(idays);
return true;
}
証明書の期限を調べるのは、
bool __fastcall TForm1::IdSSLIOHandlerSocketOpenSSL1VerifyPeer(TIdX509 *Certificate,
bool AOk, int ADepth, int AError)
がみそですね。このルーチンをhookするために、

が必要ですし、そもそもhttpsでgetしますから、

というイベントハンドラーの指定が必要です。IdSSLIOHanderl….側のプロパティーも、

でないと、新しいサーバーでは蹴られたと思います。さらに、実行時には、Opensslのddlも必要ですから、バイナリのフォルダーは、

こんなように、ssleay32.dllとlibeay32.dllを置く必要があります。見かけにだまされてはだめで、今回の実行バイナリは32ビット版なので、ともに32ビット版のdllでないとだめです。紛らわしいことに64ビット版のdllもまったく同じファイル名なんです。
コメント