2008年8月13日水曜日

Zip コンポーネントの ExcludedAttributes について

IP*Works! Zip 製品の Zip コンポーネントには、Config Settings に ExcludedAttributes という項目が用意されており、ファイルの属性を指定してアーカイブ対象から「除外」する機能を提供しています。

ただしこの機能は「除外」にしか利用できません。従って、例えば「アーカイブ属性が付与されているファイルだけを Zip したい」というような用途にはご利用いただけません。

現状では、

・システムのファイルアクセス用関数を用いて必要な属性を持つファイルの一覧を取得し、Files コレクションに各ファイルを設定する。
・あるいは、対象となるフォルダを全て指定して IncludeFiles メソッドを呼び出し Files コレクションを生成する。Compress する前に Files[i].Attributes をチェックし、所定のフラグが設定されていないものを Files コレクションから削除する。その後 Compress を実行する。

のような措置が必要となります。

2008年7月24日木曜日

簡単サーバ

弊社 IP*Works! 製品には幾つかのサンプルが同梱されています。それらの大半は通常どのサイトでもほぼご利用可能なプロトコルを前提として作成されています。

しかし、中には既に古いプロトコルとなってしまい、現在ではサービスがなかなか提供されていないものもあります (Echo サーバや DateTime サーバ等)。

しかし、これらのサンプルは非常にシンプルであり、コンポーネントの動作を理解するにはお手軽で便利なものとなっています。(サーバがあれば、ですが。)

そこで、弊社の UDPPort および IPDaemonを使って非常にシンプルな UDP Echo サーバおよび DateTime サーバを C# 作成してみました。(サービス仕様の詳細に興味のある方は、RFC862 - Echo Protocol および RFC867 - Daytime Protocol をご参照ください。)

●UDPEcho サーバ

クリックすると拡大表示この UDP Echo サーバの UI は非常にシンプルです。ListView が1つと Button が1つだけです。VisualStudio でフォームを作成し、これらをドロップします。名前はそれぞれ既定値の ListView1 および button1 です。続いて UDPPort をフォームにドロップします。こちらも名前は規定値の udpport1 です。この状態で、以下のようなソースを作成します。(VS2005 の場合。) ユーザが定義するのは、ボタンクリックイベントハンドラ button1_Click と、UDPPort の DataIn イベントハンドラ udpport1_OnDataIn のみです。
namespace UDPEchoServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.Equals("&Start"))
{
udpport1.Active = false;
udpport1.InvokeThrough = this;
udpport1.LocalPort = 7; // UDP Echo
udpport1.Active = true;
udpport1.AcceptData = true;

button1.Text = "&Stop";
}
else
{
udpport1.Active = false;
button1.Text = "&Start";
}
}

private void udpport1_OnDataIn(object sender, nsoftware.IPWorks.UdpportDataInEventArgs e)
{
ListViewItem newdata = new ListViewItem(new String[] {DateTime.Now.ToString(), e.SourceAddress, e.Datagram});
listView1.Items.Add(newdata);

udpport1.RemoteHost = e.SourceAddress;
udpport1.RemotePort = e.SourcePort;
udpport1.Send(e.DatagramB);
}
}
}
非常にシンプルですね。button1_Click では、サーバ停止状態 (button1.Text が "&Start") であれば、使用するポートを設定し、udpport コンポーネントをアクティブにし、データを受け入れ可能にします。サーバ動作中であれば、サーバを非アクティブにします。動作中にデータを受信すると、udpport1_OnDataIn イベントハンドラが実行されます。ここでは受信したデータグラムの情報をリストビューに表示し、受信したデータをそのまま送信元に返送しています。

次は少し複雑な DayTime サーバを見てみましょう。

●DayTime サーバ

クリックすると拡大表示こちらの DayTime サーバは、UDP/IP と TCP/IP を両方サポートする関係上 UI も少し項目が増えています。情報表示用のリストビュー、プロトコル選択用チェックボックス (UDP TIME と TCP TIME)、返す日時フォーマット選択用のラジオボタン (US 形式か UK 形式か)、そして起動/停止用のボタンです。これらをフォームのドロップした後、UDPPort コンポーネントおよび IPDaemon コンポーネントをフォームにドロップします。今回もユーザが作成しなければならないのは、起動/停止ボタンのクリックイベントハンドラ、UDPPort の OnDataIn イベントハンドラ、および IPDaemon の OnDataIn イベントハンドラのみです。
namespace DayTimeServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void bStart_Click(object sender, EventArgs e)
{
Control[] controls = { chkbUDP, chkbTCP, rbUK, rbUS };

if (bStart.Text.Equals("&Start"))
{
foreach (Control c in controls)
{
c.Enabled = false;
}

if (chkbUDP.Checked)
{
udpport1.Active = false;
udpport1.InvokeThrough = this;
udpport1.LocalPort = 13; // UDP Daytime port
udpport1.Active = true;
udpport1.AcceptData = true;
}
if (chkbTCP.Checked)
{
ipdaemon1.InvokeThrough = this;
ipdaemon1.LocalPort = 13; // TCP Daytime port
ipdaemon1.Listening = true;
}
bStart.Text = "&Stop";
}
else
{
if (chkbUDP.Checked)
{
udpport1.AcceptData = false;
}
if (chkbTCP.Checked)
{
ipdaemon1.Listening = false;
}
foreach (Control c in controls)
{
c.Enabled = true;
}
bStart.Text = "&Start";
}
}

private void udpport1_OnDataIn(object sender, nsoftware.IPWorks.UdpportDataInEventArgs e)
{
DateTime now = DateTime.Now;
ListViewItem newdata = new ListViewItem(new string[] {
now.ToString(), e.SourceAddress, "UDP"
});
listView1.Items.Add(newdata);

String fmt = rbUK.Checked ? "dd MMM yy hh:mm:ss' UTC'" : "dddd', 'MMMM dd', 'yyyy hh':'mm':'ss'-UTC'";
String utcnow = now.ToUniversalTime().ToString(fmt);

udpport1.RemoteHost = e.SourceAddress;
udpport1.RemotePort = e.SourcePort;
udpport1.Send(System.Text.Encoding.UTF8.GetBytes(utcnow+"\r\n"));
}

private void ipdaemon1_OnDataIn(object sender, nsoftware.IPWorks.IpdaemonDataInEventArgs e)
{
DateTime now = DateTime.Now;
ListViewItem newdata = new ListViewItem(new string[] {
now.ToString(), ipdaemon1.Connections[e.ConnectionId].RemoteHost, "TCP"
});
listView1.Items.Add(newdata);

String fmt = rbUK.Checked ? "dd MMM yy hh:mm:ss' UTC'" : "dddd', 'MMMM dd', 'yyyy hh':'mm':'ss'-UTC'";
String utcnow = now.ToUniversalTime().ToString(fmt);

ipdaemon1.Send(e.ConnectionId, System.Text.Encoding.UTF8.GetBytes(utcnow+"\r\n"));

ipdaemon1.Connections[e.ConnectionId].AcceptData = false;
ipdaemon1.Connections[e.ConnectionId].Connected = false;
}
}
}
bStart_Click はサーバの起動と停止を制御します。起動時にはチェックボックスやラジオボタンを無効化して動作中に変更できなくし、またプロトコル選択チェックボックスの状態に応じて UDPPort コンポーネントおよび IPDaemon コンポーネントのインスタンスをアクティブ化します。停止時にはプロトコルの選択状態に応じて対応するコンポーネントを非アクティブ化し、チェックボックスおよびラジオボタンを有効にします。

udpport1_OnDataIn では UDP で受信したデータから得られた送信元に対し、現在時刻を指定されたフォーマットで UDP で返信します。同様に ipdaemon1_OnDataIn では TCP で受信したデータから得られた送信元に対し現在時刻を指定されたフォーマットで TCP で返信します。なお、この DateTime サーバでは、日時は UTC で返すようにしています。

このどちらのサーバも、弊社のデモに対するテスト用サーバとしてご利用いただけます。

2008年7月9日水曜日

IP*Works! 製品の複数バージョンの共存について

殆どの IP*Works! 製品には複数のバージョンが存在しています。
通常は最新バージョンのみをご利用になることが殆どだと思いますが、共有サーバ上に複数の開発部隊がそれぞれの所有しているバージョンを同時にインストールしなければならないようなケースがあります。

この場合、製品によっては異なるバージョンの共存インストールができないものがありますのでご注意ください。基本的には以下のようになります。
  • .NET/Java 系製品は、バージョン間の共存が可能です。プロジェクトごとに参照するバージョンを指定できます。
  • ActiveX 製品は、バージョン間の共存が可能です。
  • Delphi / C++ Builder 製品はバージョン間の共存インストール自体は可能ですが、ツールパレットには1つのバージョンのアイコンしか表示できず IDE そのものが単一のバージョンしか管理できません。利用可能なバージョンはメニューの [コンポーネント] - [インストールパッケージ] で選択します。

その他の製品に関しましては、製品名およびバージョン番号をご明記の上、弊社までお問い合わせください。

なお、バージョン間共存インストールができても、同一プロジェクト内で複数のバージョンのコンポーネントを参照すること (たとえば同一のプロジェクト内で同一製品の V6 と V8 のコンポーネントを混在参照する等) はできませんのでご注意ください。

2008年7月8日火曜日

IPDaemon/IPPort の SendFile(...) と Timeout

IPDaemon や IPPort では、V8 から SendFile(...) メソッドをサポートしています。
これを使うことで、ファイルに格納されたデータをまとめて送信することができ大変便利です。

ただし、IPDaemon や IPPort の設定を既定値のまま SendFile(...) を使用すると IPWorksException (code=702; message="This operation cannot be performed in a non-blocking manner.") が発生してしまいます。

これは、IPDaemon および IPPort では既定値では Timeout は 0 になっており、非同期動作するように構成されているためです。SendFile を使用する際には Timeout 値に適当な正の整数値を指定してからお使いください。

また、IPDaemon では Timeout 値の設定には2つの方法があります。
  • DefaultTimeout プロパティを使用して、全てのコネクションの既定値として設定する方法。こちらの場合は、コネクションの生成前に値を設定しておく必要があります。
  • コネクションごとに Timeout を設定する方法。こちらの場合は、コネクション生成後でも必要に応じて当該コネクションの Timeout フィールドの値を設定・変更することが可能です。

状況に応じてこの2つの方法を使い分けることが可能です。

2008年6月24日火曜日

トライアル版から製品版への移行

弊社製品をご検討頂いているお客様から時々頂くご質問に、

「トライアル版(評価版)で検証した後、製品版に移行するにはどうするのか」
「トライアル版に製品版キー/シリアル番号を適用して製品にしたいがどうするのか」

というものがあります。

弊社のシステムでは、評価版を製品版キー/シリアル番号で制限解除する方法は採用しておりません

製品版の setup.exe を実行し、インストール中に示される手順に従って再インストールして頂く形になります。この手順内で製品版のキーとシリアル番号を要求されますので、ここに入力することにより製品版のライセンスが登録されます。

既に評価版がインストールされている環境の場合、ライセンス情報はこの時点で製品版のものにより置換されます。

製品版 setup.exe は弊社公式サイトの http://www.nsoftware.com/download/ からダウンロードしていただけます。

2008年6月20日金曜日

IPDaemon のイベントとマルチスレッド

以前あったお問い合わせに、

「IPDaemon をメインフォームではないクラスで別スレッドで動作させているのだが、そのクラスに InvokeThrough してもイベントを受け取れない」

というものがありました。私もちょっと気になったので弊社技術者の回答をチェックしてみたところ、以下のような回答がなされていました。

「IPDaemon は非同期に動作するため、イベントは DoEventS() 呼び出しが行われるまで発生しない。これを解決するには、IPDaemon の DoEvents() をプログラムのループ内で明示的に呼び出すか、タイマーを使って (定期的に) DoEvents() を呼び出すようにすることで解決できる」

ちょっと面倒ではありますが、シングルスレッドでは動作していたプログラムをマルチスレッド化してイベントを受け取れなくなった場合はこれをお試しください。

2008年6月18日水曜日

インストール時の "key verification failed" エラー

弊社製品をインストールする際に、製品シリアル番号およびキーを入力すると

"key verification failed (xx)"

のようなエラーが表示されることがあります。これは、入力したデータが実行中のインストーラ (setup.exe) に適合しないものであった場合に発生します。(例: C++ Builder Edition のインストーラで C++ Edition のシリアル番号とキーを使用した、等。)

このエラーが発生した場合は、使用しているインストーラとシリアル番号およびキーが一致しているかどうかをご確認ください。

インストーラの情報は、インストーラ起動時に表示されるスプラッシュ画面をご参照ください。シリアル番号の種別は先頭4バイトで識別されます。

例)

IPN8 - IP*Works! V8 .NET Edition
IPJ8 - IP*Works! V8 Java Edition
ISN8 - IP*Works! SSL V8 .NET Edition
ISJ8 - IP*Works! SSL V8 Java Edition
IZN8 - IP*Works! ZIP V8 .NET Edition
IZJ8 - IP*Works! ZIP V8 Java Edition
IPA6 - IP*Works! V6 ActiveX Edition
ISC6 - IP*Works! SSL V6 C++ Edition

2008年6月13日金曜日

製品を正しくインストールしアクティブ化もしたはずなのに「アクティブ化が必要」と表示される

弊社製品の V6 (およびそれ以前) のライセンスを新しいマシンに移行したお客様から時々このお問い合わせを頂くことがあります。

これは、新しいマシンが 64bit Windows OS の場合に発生します。ライセンスのアクティブ化情報はレジストリに格納されますが、Windows システムの都合で 32bit OS の場合と 64bit OS の場合で格納先が異なるためです。

これに該当する場合は、アクティブ化キー取得ページの URL の末尾に &w64=1 (全て半角 ASCII 文字でアンパサンドに続けてダブリュー、数字の6、数字の4、等号、数字の1) というパラメータを追加してアクセスします。例えば IP*Works! V6 .NET Edition の場合通常の 32bit OS 時は

http://www.nsoftware.com/download/lic.aspx?prod=ipn6a

ですが、これを

http://www.nsoftware.com/download/lic.aspx?prod=ipn6a&w64=1

とすることで 64bit Windows OS 用のアクティブ化キーを取得することができます。

2008年6月12日木曜日

Windows 以外の OS での Zip 自己展開形式サポート

弊社 Zip の .NET Edition では自己展開形式ファイルの作成をサポートしています (ZipSFX コンポーネント)。

このコンポーネントが生成するのは Windows の .EXE ファイルであり、Windows 以外の OS ではご利用いただけません。

なお、「OS に依存せず専用ツールなしで Zip を展開したい」ということであれば、.jar 形式を採用することでこれに近いことを行えます。(ただし Java ランタイムは必要。)

.jar 形式は、java -jar コマンドで展開可能ですので、Java ランタイムがインストールされている環境であれば OS に依存することなくまた専用展開ツールなしでアーカイブの展開を行うことができます。

2008年6月9日月曜日

EndTransfer イベントについて

あるお客様から、EndTransfer イベントの発生タイミングに関するお問い合わせを頂きました。

その内容は

・EndTransfer イベントが発生するのは、データ転送終了直後なのか、転送に関わる処理が終わった直後なのか

というものです。例えば弊社 IMAP コンポーネントで FetchMessageText() や FetchMessagePart() を実行した際に、fetch されたデータのプロパティへの書き込みは EndTransfer イベントが発生した時点で 終了しているのかどうか、ということです。

弊社の製品仕様では、EndTransfer イベントはデータの受信が完了した直後に発生しています。そして受信データから取り出した情報の各種プロパティへのセットはその後行われます。

従って、

・EndTransfer イベントは純粋にサーバとクライアント間でデータの転送が終わった事をのみを意味する
・転送されたデータのプロパティへの反映は、EndTransfer イベント内では保障されていない

ということになります。FetchMessageText() や FetchMessagePart() から制御が戻った時点では全てのプロパティ処理は完了していますので、プロパティ参照はそれ以降に行う必要があります。

2008年5月30日金曜日

tar ファイルのファイル末尾データについて (補足)

過去の記事で、EOA (End-Of-Archive) について述べましたが、今回はこれに起因する互換性の問題について述べてみたいと思います。

先の記事では、tar ファイルはその歴史的経緯からブロック化書き込みを行う必要があり、アーカイブの実データサイズとファイルサイズは必ずしも一致しないことを述べました。

しかし、実運用上はファイルの EOF (End-Of-File) を検出した時点で EOA を読み取ったのと同等の処理をする処理系が多く、弊社の tar コンポーネントも既定値では EOA を付与しないようになっています。

しかし弊社へのお問い合わせを見ていると、この EOA が必須となっている tar 展開プログラムも存在しているようです。(WinRAR 3.71 等。)

このような場合に対処するために、弊社の tar コンポーネントには ExtraNullBytes という構成設定項目が用意されています。
tar.Config("ExtraNullBytes=1024")

上記を行うことにより、生成される tar アーカイブの末尾に 1024 個の NULL 文字 (0x00) から成るブロックが付与され、EOA として機能するようになります。

2008年4月22日火曜日

FTPS で LIST コマンドがハングアップする

先日、あるお客様から FTPS でサーバに接続すると、サーバログイン後しばらくすると固まってしまう、というお問い合わせを頂きました。そのログを見ると以下のようになっています。
> Connecting to FTP server
> Connected.
> 220 Serv-U FTP Server v6.4 for WinSock ready...
> USER XXXXXXXX
> 331 User name okay, need password.
> PASS XXXXXXXX
> 230 User logged in, proceed.
> PWD
> 257 "/" is current directory
> PASV
> 227 Entering Passive Mode(192,168,0,2,8,71)
> LIST

サーバから 227 応答を得た後、クライアントが LIST コマンドを発行してところでハングアップしてしまいます。

これは、既定値ではパッシブモード時のリモートサーバアドレスを、サーバ応答から得るためで、この例ではリモートサーバはファイアウォールの内側に設置されており 192.168.0.2 というプライベートアドレスを使用しているためです。SSL を使用していなければファイアウォールがこのデータの書き換えを行ってくれるでしょうが、SSL で暗号化されたセッションの書き換えは行いません。この結果、クライアント側はサーバへのデータチャネルの接続にこのプライベートアドレスを使用してしまい、接続ができずタイムアウトしてしまうことになります。

これを解決するには FTP コンポーネントの構成設定パラメータで
    FTPS1.Config('UseRemoteHostAddressForPassive=true')

として、リモートサーバアドレスを RemoteHost プロパティから得るようにします。これにより、リモートサーバのアドレスは実際に当該クライアントから見たリモートサーバのアドレス (ファイアウォールのグローバル側アドレス) が使用されるようになり、ファイアウォールのポートフォワード機能を介して正しくファイアウォールの内側にあるサーバとコントロールチャネルを確保できるようになります。

2008年4月21日月曜日

IPv6 と IPv4

弊社の通信系コンポーネントでは、アドレス指定方式として IPv6 と IPv4 をサポートしています。

この設定は、UseIPV6 構成設定パラメータで指定します。既定値は false で、IPv4 アドレスを使用します。この設定を true にすることで、IPv6 アドレス形式を使用できるようになります。設定例 (C#):
コンポーネント名.Config("UseIPV6=true");

なお、UseIPV6 の設定の如何にかかわらずアドレス形式は IPv6 または IPv4 を排他的に使用します。両者の混在はできません。(UseIPV6=true の場合は IPv6 形式、false の場合は IPv4 形式のみがご利用頂けます。)

2008年4月18日金曜日

弊社製品で必要となる JDK バージョン

弊社 Java 製品は JDK 1.3 以降でのご利用を前提として設計されていますが、JDK 1.4 以降でのご利用をお勧めします。

2008年4月17日木曜日

Java Edition の2つの .jar ファイルについて

製品版の lib フォルダ内を見ると、2つの .jar ファイルがあります。ひとつは製品名の .jar (IP*Works! Core なら ipworks.jar、IP*Works! Zip なら ipworkszip.jar)、もうひとつは製品に関係なく deploy.jar となっています。

これらは、内容はほとんど同じですが、製品名の .jar にはデバッグ用の情報も含まれています。従って、サイズは deploy.jar は製品名の .jar のおよそ半分以下となりますので、成果物を配布する際には deploy.jar を指定する方が有利なケースが多々あります。

※なお、評価版には deploy.jar は含まれておらず製品名の .jar のみとなっています。

また、同一アプリケーションで複数の弊社 Java 製品をご利用いただく場合、deploy.jar という名称が衝突してしまいます。このような場合は適宜名前を変更してご利用ください。

2008年4月15日火曜日

IP*Works! アクティブ化 FAQ

製品アクティブ化 FAQ

アクティブ化とは何ですか?

アクティブ化とは、意図的な、あるいは意図せざるソフトウェアへの著作権侵害行為を制限することを目的に登録処理内に追加された手順です。製品のアクティブ化はソフトウェアベンダーがソフトウェアの著作権侵害行為を制御するためのポピュラーな手段となっており、Microsoft や Novell、Borland 等多くのベンダーにより利用されています。そして著作権侵害行為を制限することにより、各社は開発により注力しより多くの資源を割り当て、また顧客に対しより価値のあるサービスをしっかりと提供することができます。
アクティブ化は製品ライセンス同意書の事項に従った合法的な使用を妨げるようなことは意図していません。

それはどのように動作しますか?

アクティブ化は通常、初めて製品をインストールする際に行われます。あるマシン上で初めて当該製品をインストールする場合、インストールプログラムは当該製品をアクティブ化しなければならない旨を通知します。そしてインストーラはアクティブ化キーをダウンロードするための、弊社サイト内のページへの URL をオープンするよう提示します。この時これを受け入れると、弊社ウェブサイトへと誘導され、あなたの製品名、シリアル番号、キーおよび NODEID が記載済みのページが表示されます。このページで .reg ファイルのアイコンをクリックするだけで、あなたのマシンで製品をアクティブ化するための正しいレジストリファイルがダウンロードされます。

REG ファイルをあなたのマシンにダウンロードしたら、当該ファイルをディスクに保存します。これ以降あなたがマシン名を変更しない限り、この REG ファイルをダブルクリックするだけで毎回弊社ウェブサイトを参照することなく、当該ソフトウェアをアクティブ化することができます。NODEID は同一のままですので、これが問題になることはありません。

NODEID とは何ですか?NODEID はどうすれば知ることができますか?

NODEID とは、アクティブ化処理時に使用される、マシン名の一方向ハッシュです。これにより我々は製品がアクティブ化されるコンピュータの実際のマシン名を収集する必要がなく、あなたのプライバシーを守ることができるのです。あなたの NODEID は、次の2つの方法で知ることができるはずです:

製品のインストール中であれば、当該製品をアクティブ化しなければならないことを通知するウィンドウが表示されます。このウィンドウ内に当該マシンの NODEID が記載されています。

コンポーネントがあるマシンでアクティブ化されていないのであれば、そのマシン上でいずれかのコンポーネントを使用すると当該マシンの NODEID を提示するダイアログが表示されます。

【訳注: V8 製品ではインストール時にアクティブ化しないとインストールが完了しないようになっていますので、未アクティブ化状態でのインストールは、レジストリの破損等でもない限り通常はあり得なくなっています。】

一度当該マシンの NODEID を取得してしまえば、そのマシン上で製品を簡単にアクティブ化できます。

製品アクティブ化には何か特別なソフトウェアが必要ですか?

いいえ。製品アクティブ化サイクルの際に弊社ウェブサイトが提示され .reg ファイルをダウンロードするよう示されます。ダウンロードした REG ファイルをダブルクリックすることで、アクティブ化情報はあなたのローカルマシン レジストリに自動的に追加されます。

私のコンピュータはファイアウォールの内側にありますが、これはアクティブ化に関し問題となりますか?

これは問題とはならないはずです。アクティブ化処理ははウェブベースの処理であり、あなたが弊社ウェブサイトに到達できるのであればなんら問題は発生しないはずです。弊社ウェブサイトへの接続が困難な場合は、FAQ「IP*Works! をインストールするマシンがインターネットに接続されていません。…」をご参照ください。

プライバシーはどうなりますか?マシンをアクティブ化するのにどんな情報が必要ですか?

ソフトウェアのアクティブ化の際に必要となる情報は、有効なシリアル番号、キーおよび NODEID のみです。これらはユーザの確認およびアクティブ化のためだけに必要です。さらに付け加えておくと、NODEID は一方向ハッシュでありその値からいかなる情報をも取り出すことは不可能です。これら以外の情報を集めないことで、/n software はお客様のプライバシーを完全に保護します。

アクティブ化せずに IP*Works! を使用できますか?

IP*Works! 製品はどれもアクティブ化をすることなくご利用頂くことは可能です。ただし、About ダイアログが表示され続け、ライセンスのない評価版と全く同じ動作になります。IP*Works! 製品はアクティブ化されなければなりません。さもないと、About ダイアログが表示されます。

IP*Works! をインストールするマシンがインターネットに接続されていません。この場合、どうやってアクティブ化すればよいですか?

IP*Works! がインストールされるマシンからインターネット接続ができない場合の製品アクティブ化には幾つかの方法があります。まず最初に、当該製品をアクティブ化するマシンの NODEID を調べます。続いて次のうちのいずれか1つを実行できます:
  1. 別のマシンからhttp://www.nsoftware.com/download/lic.aspxをアクセスし、表示されたフォームに適切な値を記入します。全てを記入することで、有効な REG (.reg) ファイルをダウンロードできるようになります。この REG ファイルを取得し、インターネット接続のできないマシンにコピーします。コピー先マシン上でこの REG ファイルをダブルクリックすることで、適切なキーが当該マシンのレジストリにインストールされます。
  2. support@nsoftware.com にメールを送り、製品をインストールしたいマシン用の有効な REG ファイルをリクエストすることができます。なおその際にはあなたのシリアル番号とキーの他、ソフトウェアをインストールしたいマシンの NODEID をお知らせください。

  3. 上記のいずれもご利用頂けない場合は、お電話にて製品アクティブ化のための追加オプションを弊社カスタマサポートまでお問い合わせください。



IP*Works! ソフトウェアを別のマシンに移転したらどうなりますか?

弊社ソフトウェアを、別の名称のマシンに移動させた場合、あるいは当該ソフトウェアを別のマシンに移転させた場合は、「移転通知」を弊社まで FAX にてご送付頂く必要があります。この FAX にはあなたの署名と、当該ソフトウェアが以前インストールされていたマシンから完全に削除されたことを言明する一文を含めてください。また、当該製品が新たにインストールされるマシンの NODEID も併せてご記載ください。

【訳注: 現在は移転通知はウェブフォーム (http://www.nsoftware.com/lic/transfer/) 経由で自動送信されますので、書面を FAX する必要はなくなりました。】

アプリケーションをコンパイルしビルドした場合、そのアプリケーションの配布先マシン全てでライセンスをアクティブ化しなければならないのですか?

いいえ、そのようなことは全く必要ありません。コンパイル対象アプリケーションをビルドする際に、アクティブ化はライセンスがインストールされる開発マシンでのみ必要となります。有効なアクティブ化済みライセンスでアプリケーションをコンパイルすると、ライセンス情報はアプリケーションに埋め込まれるので実行時のアクティブ化は全く必要ありません。

2008年4月14日月曜日

V8 .NET 製品のライセンスについて

V8 製品は、これまでの製品とは異なるランタイムライセンスルーチンを使用しています。このため、コンポーネントを標準的な使い方 (IDE 上でのフォームへのドラグ&ドロップ) 以外の方法でご利用いただく場合の処置が旧バージョン製品とは若干異なっています。

この件に関しては、インストール先に licensing.htm という名称で説明文書が残されています。参考のため、以下にその日本語訳を載せておきます。

IP*Works! V8 - ライセンス情報


標準 (ロイヤルティ・フリー) ライセンス
.NET および ASP.NET コンポーネントは Microsoft .NET ライセンス スキームを使用しています。.NET Compact Framework コンポーネントのライセンスについては、後述の ".NET CF" セクションをご覧ください。

Microsft .NET ライセンス スキームでは、Visual Studio .NET はフォームにライセンス済みコンポーネントをドロップすると、自動的に "licenses.licx" という名称のファイルを生成します。このファイルは埋め込みリソース (embedded resource) としてあなたのプロジェクトに自動的追加されます。このプロジェクトをビルドすると、ライセンス情報をコンパイルされたアセンブリに埋め込むのにこの licenses.licx ファイルが使用されます。(ただし ASP.NET 2.0 ではライセンス情報は既定値では別途用意されたファイル App_License.dll に埋め込まれます。)

フォームを使用しない、あるいはコンポーネントを動的に生成する場合にlicx ファイルを生成する最も簡単な方法は、別プロジェクトを1つ用意し、そのフォームにコンポーネントを1つドロップして licenses.licx を生成させ、その licenses.licx ファイルをフォームを使わないプロジェクトにコピーします。

要注意事項:
  • licx ファイルの名称は、必ず "licenses.licx" でなければなりません。また、このファイルは埋め込みリソースとしてプロジェクトに含められる必要があります。
  • 開発しているのがクラスライブラリである場合、そのライブラリを参照するプロジェクトにもこの .licx ファイルが埋め込みリソースとして含められている必要があります。さらに、そのプロジェクトは有効なライセンスがインストールされているマシン上でコンパイルされなければなりません。

.NET CF のライセンス
.NET Compact Framework コンポーネントは前述の Microsoft .NET ライセンス スキームを使用することができません。代わりに RuntimeLicense プロパティのみを使用します。ライセンス済みコンポーネントをフォームにドロップすると、デザイナ内 (および当該フォームの InitializeComponent 関数内) に RuntimeLicense という名称のプロパティが出現しライセンス文字列が割り当てられます。なお同じ RuntimeLicense プロパティ値を、当該製品の同一エディションに含まれる全てのコンポーネントでご利用頂けます。

ASP.NET 用シングルサーバ ライセンス - 共有ホスト上へのシングルサーバ ライセンスのインストール手順
ご購入頂いたライセンスが .NET Edition 用のシングルサーバ ライセンスであった場合、アプリケーションをサーバに配置して初めて起動した際に、当該システムに有効なライセンスが見つからなかった旨のエラーが表示されます。このエラーメッセージには製品アクティブ化ページへのリンクが含まれており、当該ページから keys.reg ファイルをダウンロードできます。この keys.reg ファイルにはあなた用のライセンスが格納されており、次の2通りの使い方が可能となっています:
  • keys.reg ファイルをサーバマシン上で実行できます。これにより、ライセンスが当該システムのレジストリにインストールされます。
  • あるいは、keys.reg ファイルを "nsoftware.XXXX.lic" (XXXX の部分は、製品ごとに固有の名称。通信系 Core 製品なら IPWorksWeb、SSL 製品なら IPWorksSSLWeb、ZIP 製品なら IPWorksZipWeb) にリネームし、あなたの web アプリケーションの /bin ディレクトリにコピーします。

トラブルシューティング
ライセンスを購入済なのに、ライセンス例外が発生する、あるいは "About" メッセージが表示される場合には以下の点をチェックしてみてください:
  • licenses.licx ファイルに問題はありませんか?当該ファイルがちゃんと存在しており、プロジェクトに含められており、正しい情報 (正しいコンポーネント名や正しいバージョン) が格納されていますか?
  • ビルド対象が ASP.NET 2.0 の場合は、licenses.licx ファイルを右クリックし「ランタイムライセンスのビルド (Build Runtime Licenses)」を選択し、当該プロジェクトをリビルドします。
  • コンポーネントの新ビルドをインストールしたらこの問題が発生するようになった場合は、licenses.licx ファイルに正しいバージョン情報が格納されていることを確認してください。バージョン情報が含まれていない licenses.licx は問題ありません。
  • クラスライブラリをビルドしているのであれば、そのライブラリを参照する側にも同じライセンスルールが適用されます。参照側アプリケーションにもこの licx ファイルが埋め込みリソースとして含まれており、またそのアプリケーションはライセンス済みマシン上でコンパイルされていますか?

ライセンスの移転
ライセンスを別のシステムに移転したい場合は、ライセンス移転申請書 (英文) を弊社までお送りください。この申請を行うことにより、別途のインストール行為をライセンス違反と誤認することがなくなります。

製品のアクティブ化に関しより詳しい情報が必要な場合は、弊社の「製品アクティブ化 FAQ (英文)」をご参照ください。

V8 Java 製品のライセンスについて

V8 製品は、これまでの製品とは異なるランタイムライセンスルーチンを使用しています。このため、コンポーネントを標準的な使い方 (IDE 上でのフォームへのドラグ&ドロップ) 以外の方法でご利用いただく場合の処置が旧バージョン製品とは若干異なっています。

この件に関しては、インストール先に licensing.htm という名称で説明文書が残されています。参考のため、以下にその日本語訳を載せておきます。

IP*Works! V8 - ライセンス情報


標準 (ロイヤルティ・フリー) ライセンス
IPWorks コンポーネントは実行時のライセンスチェックに RuntimeLicense という名称のプロパティを使用します。ライセンス済みコンポーネントをフォームにドロップすると、ライセンス文字列が自動的に RuntimeLicense プロパティに割り当てられます。お使いの IDE がこのプロパティを自動的には設定してくれない場合は、このプロパティをソースコードにハードコードすることで、ご利用いただくコンポーネントが正しくライセンスされたものであることを明示します。デザイナを使用しないのであれば、別のプロジェクトを作成してそこから RuntimeLicense プロパティの値を読み取り、その値をコピーしてあなたのアプリケーションにペーストします。なお、同一の製品の同一エディションに含まれる全てのコンポーネントに対し、同一の RuntimeLicense プロパティ値を使用できます。

シングルマシン ライセンス - サーバにシングルマシン ライセンスをインストールする手順
お買い上げ頂いたライセンスがシングルマシン ライセンスであった場合、ライセンスは上記のロイヤルティ・フリー ライセンスとは異なった動作をします。あなたのアプリケーションをサーバ上で初めて実行した際に、有効なライセンスがシステム上で見つからないというエラーが表示されるかもしれません。その場合には、 IPWorks セットアップ時に生成された .lic ファイル (IP*Works! 製品なら ipworks.lic、IP*Works! SSL 製品なら ipworksssl.lic、IP*Works! Zip 製品なら ipworkszip.lic) を、製品の .jar ファイル (IP*Works! 製品なら ipworks.jar、IP*Works! SSL 製品なら ipworksssl.jar, IP*Works! Zip 製品なら ipworkszip.jar) と共に配置する必要があります。この ipworks.lic ファイルはあなたのユーザホームディレクトリ配下の .nsoftware フォルダ内に格納されています。なお、ipworks.lic ファイルはそれを生成したマシンに結び付けられていますので、このファイルを他のマシンにコピーした場合は動作しません。

Unix/Linux およびその他のシステムへのライセンスのインストール
Windows 以外のシステムでは、各コンポーネントは ZIP ファイルにアーカイブされています。アーカイブをオープンし、製品の jar ファイル (IP*Works! 製品なら ipworks.jar、IP*Works! SSL 製品なら ipworksssl.jar, IP*Works! Zip 製品なら ipworkszip.jar) をダブルクリック (あるいはコマンド java -jar ipworks.jar 等を実行) してライセンスをアクティブ化します。なおローヤルティ・フリー ライセンスではこの手順は一度だけ、開発マシン上でのみ実行が求められるのみであり、実行時には各コンポーネントは RuntimeLicense プロパティに格納されたライセンスが使用されます(前述)。

トライアル版ライセンスをインストールする場合も、同じ手順で行います: 製品 jar ファイルをダブルクリック (あるいは java -jar ipworks.jar 等を実行) し、指示に従って処理を進めます。

ライセンスの移転
ライセンスを別のシステムに移転したい場合は、ライセンス移転申請書 (英文) を弊社までお送りください。この申請を行うことにより、別途のインストール行為をライセンス違反と誤認することがなくなります。

製品のアクティブ化に関しより詳しい情報が必要な場合は、弊社の「製品アクティブ化 FAQ (英文)」をご参照ください。

2008年4月11日金曜日

Delphi Edition のリプレース後エラーが発生する件

あるお客様から、Delphi Edition のトライアル版での評価終了後、製品版をインストールしたのだが下記のエラーが出るというお問い合わせを頂きました。

Undeclared Identifier IPWorksSSLLoadDRU
Undeclared Identifier IPWorksSSLFindFunc
Undeclared Identifier IPWorksSSLfreeDRU

このエラーは、旧バージョンの .pas ファイルが Delphi の Lib フォルダ内に残っている場合に発生します。この場合の対応策は以下の通りです。
  1. まず最初に、当該製品をアンインストールします。
  2. C:\Program Files\Borland\[Delphi Version]\Bin に移動し、"dclipwssl6.bpl" ファイルを削除します。
  3. C:\Program Files\Borland\[Delphi Version]\Lib に移動し、.dru および .pas という拡張子のファイルのうち当該コンポーネント用のもの (IP*Works! SSL なら "ips" で始まるもの) を全て削除します。
  4. 最後に IDE がクローズされていることを確認の上、製品版の setup を再度実行します。

FTP によるファイル転送とタイムスタンプ

FTP コンポーネントをお使いのお客様から、「ファイルをサーバにアップロードする際にクライアント側のタイムスタンプをサーバ側に反映できないか」というお問い合わせがありました。

FTP の仕様 (RFC959 および RFC1579) には残念ながらタイムスタンプを扱う機能は規定されておりません。このため、通常の FTP サーバ (特殊な拡張機能を実装されていない FTP サーバ) との間で転送されたファイルは、ファイルが転送された時点のタイムスタンプを持つようになっています。

どうしてもタイムスタンプを保持しなければならないような場合には、タイムスタンプを保持できるアーカイバ (tar や zip 等) でファイルをアーカイブして転送するようにします。この場合、アーカイブファイル自体のタイムスタンプは変更されますが、メンバーファイルのタイムスタンプは保持されておりメンバーファイルには展開時に元のタイムスタンプが付与されます。

アーカイブの作成や展開には、弊社の IP*Works! ZIP 製品をご利用いただけます。

2008年4月10日木曜日

FTP でサーバ側ファイルの存在をチェックする

先の記事ではサーバ側ディレクトリの存在の有無をチェックする方法を紹介しましたが、V8 製品にはサーバ側ファイルの存在をチェックする方法が用意されています。

V8 FTP および FTPS コンポーネントには FileExists プロパティが追加されています。RemoteFile プロパティに調べたいリモートファイル名を設定した後 FileExists プロパティを参照すると、FTP コマンド NLST を用いてサーバ上に当該ファイルが存在するかどうかをチェックします。そしてファイルが存在する場合は FileExists プロパティに true が、存在しない場合には false がセットされます。

なお FileExists でチェックできる対象は「ファイル」のみであり、「ディレクトリ」のチェックはできません。ディレクトリの存在のチェックは現状では先の記事の方法、またはそれに類する方法 (ListDirectoryLong() の戻り値を使って調べる方法) 等で行うことになります。

2008年4月8日火曜日

FTPS と Passive プロパティ

弊社の FTP コンポーネントでは、PORT (Active) モードと PASV (Passive) モードをサポートしており、切り替えは Passive プロパティの値を変更することで行います。(Passive の値が true の時 PASV モード。)

FTPS コンポーネントにもこの Passive プロパティが存在していますが、V6 製品では Passive に false を設定しても必ず PASSIVE モードで接続されます。これはファイアウォール使用時に SSL 接続を PORT モードで行うことは困難だからです。(特に NAT ファイアウォールの場合、リモート側からのデータコネクションで使用するポートを特定することが困難。) このため、SSL 製品のFTPS コンポーネントでは Passive プロパティは互換性のため残したまま、その値の如何にかかわらず常に Passive モードで接続するようになっていました。

ただし、SSL V8 製品では再び Passive プロパティの設定が有効となり、SSL 製品でも PORT モードと PASV モードを選択使用することが可能となっています。これは、Config() で上記の問題に対応できるようになったためです。このために使用する設定は以下の通りです。
  • ftp.Config("PortRange=...");
  • ftp.Config("ActiveModePORTAddress=...");

PortRange 設定により FTPS コンポーネントが PORT モード時にリスンする TCP/IP ポートの範囲を指定し、ActiveModePORTAddress 設定により、PORT コマンドのパラメータとしてサーバ側に通知する IP アドレスとポートを設定します。これにより、PORT コマンドでサーバに通知するアドレスとポートをクライアント PC のものではなくファイアウォールの外側アドレス (およびポート) を設定することが可能となります。そして、ファイアウォールの当該インターフェイスおよびポートへの外部からの接続を、当該クライアントにフォワードするように設定します。

以上により、ファイアウォールがパケットの書き換えを行うことなく外部のサーバと FTP(S) の PORT モード接続を行うことが可能となります。

各設定の詳細については、製品添付のヘルプをご参照ください。

IP*Works! Zip で扱う tar フォーマット

tar ファイルには主として以下のような複数のフォーマットがあります。
  • V7 (Version 7 Unix)
  • 旧 gnu
  • 新 gnu
  • POSIX.1-1988 (ustar)
  • POSIX.1-2001 (posix)
これらのうち、もっとも基本的なものは V7 であり、それ以外のものは V7 のヘッダフォーマットを拡張するか、全く異なる構造になっています。

弊社の tar コンポーネントでは V7 フォーマットと、(本来の V7 にはない) シンボリックリンクの検出機能をサポートしています。その他のフォーマットの場合は、当該フォーマットが V7 の上位互換であり、拡張機能を使用していない部分 (長いファイル名形式や拡張ファイルタイプ) に関しては読み取りおよび展開可能です。

また、弊社製品は他の Windows 版 tar アーカイバ、例えば WinZIP や WinRAR 同様、ファイルの保全および交換を目的としており、取り扱い可能なファイルタイプは
  • 通常のファイル (regular file)
  • 通常のディレクトリ (regular directory)
  • シンボリックリンク

に限定されている点に注意してください。ハードリンクやスペシャルファイル、ボリュームラベル等は WinZIP や WinRAR 同様取り扱うことはできません。
 IP*Works! (tar)WinZIPWinRAR
通常のファイル
ハードリンク×××
シンボリックリンク△1××
キャラクタスペシャルファイル×××
ブロックスペシャルファイル×××
ディレクトリ
FIFOスペシャルファイル×××

△1: 現時点では作成時のみ利用可能。展開時は未サポート。


【注】この表は私が個人的に片手間に調べたものであり、各製品の公式なアナウンスではありません。上記で×になっている機能は標準では利用できないだけで、オプション設定等により利用可能となる可能性もあります。詳細については実際の各製品をご参照ください。

2008年4月4日金曜日

パケットダンプツールについて

TCP/IP 通信ソフトウェアを作成している場合、不具合のチェックにはパケットダンプが必要なことがあります。

弊社のサポートでも、状況の切り分けや確認のためにパケットダンプデータを添えて頂くことで対応が早くなる場合があります。

そのような場合によく使われるツールに Wireshark があります。このソフトウェアは Gnu GPL に基づき配布されているフリーソフトウェアです。

このツールを使用してパケットデータをキャプチャし、フィルタリングして絞り込み、パケットデータの階層表示と16進表示を使って詳細をかなり容易に調査することができます

もしパケットダンプツールをお持ちでないのであれば、Wireshark をお勧めします。

2008年3月31日月曜日

FTP でサーバ側ディレクトリの存在をチェックする

少し前のことになりますが、お客様から FTP コンポーネント使用時にサーバ側のディレクトリの存在の有無をチェックする方法は無いか、というお問い合わせをいただきました。

FTP の規格 (RFC959) 自体にはそのようなチェック機能はありませんので、実際にそのディレクトリをアクセスしてみてサーバ側の反応を見ることで対応することになります。

なお FTP プロトコル上のエラーとしてサーバから返されるエラーは、IPWorksFtpException でエラーコード 141 として検出されます。このコードではディレクトリ不在エラー以外のものも検出しますので、サーバ側から返されるメッセージもチェックして判断する必要があります。

以下にサンプルコードを示します。このコードでは、RemotePath に当該ディレクトリを設定して (内部的に) CWD コマンドを発行させます。またディレクトリ /abc/xyz が存在しない場合には、サーバ側からは

550 CWD failed. "/abc/xyz": directory not found

というエラーメッセージが返されると仮定しています。

    try
{
// 確認したいパスを RemotePath に設定
ftp.RemotePath = "/abc/xyz";
}
catch (IPWorksFtpException ipwe)
{
// パスが存在しない場合は FTP Protocol Error を返す。
// FTP Protocol Error は全てエラーコード 141 にされるので、実際のメッセージを確認して
// 判断する。
if ( ipwe.Code == 141 )
{
// サーバから返されたエラーメッセージをチェック
if ( ipwe.Message.Contains("directory not found") )
{
System.Console.WriteLine("*** directory /abc/xyz doesn't exit. ***");
}
}
}
このロジックはサーバの返すメッセージに依存していますので、実際にご利用いただく際には検出ロジックを実際のサーバに合わせて調整する必要があります。

なお、サーバが仕様上「ディレクトリが存在しない場合」と「存在するけれどアクセス権が無い場合」のエラーメッセージをサーバが区別しない場合はクライアント側で両者を区別することはできません。

2008年3月28日金曜日

nscontrols.dll が書き込めない?

先日、.NET Edition を複数連続インストールしていたところ奇妙なエラーに遭遇しました。(右図)

当該製品を単独でインストールする場合このエラーは発生せず、複数の製品を連続インストールする場合、特に比較的大規模な製品が2つ連続する場合に発生するようです。

この nscontrols.dll は Visual Studio IDE のツールボックスに当該製品のタブを作成するための dll です。

そして、この問題の原因はインストールファイルのキャッシュイメージ処理あるいは遅延書き込み処理による排他ロックで、これはシステム環境依存のため弊社製品インストーラでは対処できません。

このエラーが発生した場合は、以下のいずれかの回避策で対処します。

  1. ダイアログが出た状態で長時間放置し、キャッシュイメージが全てフラッシュされる、あるいは遅延書き込みキューが空になるのを待ってから Retry をクリックする。

  2. Ignore で先に進む。弊社の .NET 製品が既に正しくインストールできていれば、 nscontrols.dll は既にインストール済みのはずなのでインストーラは既存の nscontrols.dll を使用してインストールを継続するはず。インストール終了後念のため Visual Studio の IDE を起動して当該製品のタブが生成されているかどうかを確認し、生成されていない場合は手作業で当該製品を追加する。

  3. 3. Abort で当該製品のインストールを中止し、PC を再起動してから当該製品を改めてインストールする。
なお 1. に関してはは個々のシステムの状態に依存しますので、待機時間を予測することは困難です。従って通常は 2. もしくは 3. で対応することになります。

2008年3月27日木曜日

tar ファイルの基本構造

tar ファイルは、Unix の基本 I/O 単位の 512 バイトのブロックから構成されています。

先頭のブロックはメンバーファイルに対する情報を格納したヘッダブロックであり、その後ろにメンバーファイルのファイル内容が書き込まれたブロックが続きます。メンバーファイルの長さ (バイト数) が 512 の倍数でない場合は、最後のブロックの途中でデータは終わることになります。(長さは当該メンバーファイルに対するヘッダブロック内に記述されています。) そして、サイズ合わせのため 512 バイトに達するまでダミーデータが末尾に追加されます。

各メンバパートはヘッダパートとデータパートから成ります。ヘッダパートは基本的には512バイトの1ブロックですが、機能拡張版では複数のブロックから構成されるヘッダパートもあります。ヘッダパートには、メンバファイルの様々な属性 (サイズやパーミッション、所有者情報等) が書き込まれます。
一方データパートはメンバーファイルの内容がそのまま書き込まれます。データパートも512バイトのブロック単位で書き込まれますので、末尾のブロックには長さ合わせのためのフィラー(詰め物) データが書き込まれることがあります。実際の長さは、ヘッダブロックから取得できます。

次のメンバーファイルが存在する場合は、またヘッダパート、そしてファイルデータパートが続きます。

最後のメンバーファイルのファイル内容ブロックの次にはアーカイブ終端を示す特別なデータ (EOA; End-Of-Archive マーク。全バイトが 0x00 の連続する2ブロック (1024 バイト)) が付与されます。

また、アーカイブ生成時に指定されたブロック化係数によっては、EOA の後ろにサイズ合わせのためのデータが付与されることがあります。

なお、ブロック化したレコードバッファをクリアしないタイプの tar アーカイバの場合は、EOA の後に以前のファイルデータが残っていることがありますが、もちろんこの部分はメンバーデータとしては取り扱われません。

参考: GNU tar 1.19: Basic Tar Format

2008年3月19日水曜日

ナレッジベースの日本語訳について

弊社では良くあるお問い合わせを公式ページ上でオンライン・ナレッジベースとして提供させて頂いております。

ただし現時点では英文のみとなっており、その他の言語でのナレッジベースの提供予定はございません。

しかし実際には日本からのお問い合わせも少なからずこのナレッジベースに記載されている事項がございますので、良くあるお問い合わせについて個人的に翻訳したものを掲載することにしました。翻訳済みのナレッジベース記事はこちらの「別館 (NSJ's Knowledge Base)」に蓄積していく予定です。

本家のナレッジベースとは違いキーワード検索等はできませんが、弊社製品ユーザ様への一助となれば幸いです。

2008年3月17日月曜日

tar ファイルのファイル末尾データについて

弊社の IP*Works! Zip 製品では tar 形式のアーカイブを扱うことができます。その関係で幾つかのテストデータを SuSE や KNOPPIX 等で作ってテストしていて気づいたのですが、Gnu tar で作成した tar ファイルはアーカイブの末尾に使用されないデータを含んでおり、ファイルサイズ (バイト数) が常に 10240 の整数倍になっていました。

一方弊社製品で作成する場合は, 512 の整数倍のサイズですが、必ずしも 10240 バイトの整数倍にはなりません。両者は特に問題なく生成も展開も互換性が保たれています。

少々気になったのでいろいろ調べていたところ、以下のようなことだと判明しました。

・tar は Tape ARchiver の略であり、元来はテープデバイスへの書き込みを目的としていた。
・テープデバイスは低速であり、Unix の書き込み単位 (512 バイト) はブロック化して書き込まないと効率が悪い。
・その関係で、Gnu tar の既定値ではブロック化係数 (blocking factor) が 20 になっている。

その結果、既定値を使用して tar ファイルを作成するとそのサイズは 512 x 20 = 10240 バイトの整数倍になります。なおアーカイブメンバーは必ずしもぴったりこのブロックに収まるわけではありませんので、アーカイブの末尾位置を明示するために特別なデータ (EOA: End-of-Archive マーク) をヘッダパートに書き込んで明示します。(そして、EOA 以降のデータは無視されます。)

弊社製品で生成する tar アーカイブも形式としては同様ですが、ブロック化係数が 1 として処理されるため、EOA より後にデータは書き込まれません。このため、生成されるアーカイブのサイズは常に 512 の整数倍となります。

また、EOA 以降のデータに何が入るかは規定されていません。このため、tar の実装によって

・以前のデータ断片が残ったままのもの
・EOA 以降を 0x00 等でクリアするもの

があります。前者の場合、一見意味のあるデータがファイル末尾に存在しているように見えますが、EOA 以降のデータは tar アーカイブとしては意味を持ちませんので、自分で tar アーカイブを処理する場合には注意が必要です。

※もちろん弊社の IP*Works! ZIP 製品に含まれる tar コンポーネントは正しく EOA を認識し、EOA 以降にブロッキング由来の不要データが存在してもそれらは無視されます。

2008年3月7日金曜日

PublicKey 情報が一致しない

先日、.pfx ファイル経由でプライベートキーを Windows の証明書ストアに登録しました。その際に、Windows の証明書マネージャで内容を確認したところ、「PublicKey」の詳細情報が CertMgr の PublicKey 情報と一致しないことに気づきました。

例えば、ある証明書の PublicKey が Windows の証明書マネージャの表示では 140 オクテットの
30 81 89 02 81 81 00 be 02 58 78 d1 4e 7f ea bd
32 aa 23 8c d6 2a 88 81 59 63 26 81 c6 0c 87 31
43 5e 9b a7 c0 9a 0d e1 cd c9 b5 c9 6a e0 0e 19
           …【中略】…
ae c7 91 f0 0c 4a 1d d1 f0 be 25 93 aa c4 f9 49
9a 35 1a f1 3c c7 11 02 03 01 00 01

となっているとします。同じ証明書を CertMgr で開き、PublicKey フィールドを読み取って得られる
-----BEGIN RSA PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Alh40U5/6r0yqiOM1iqIgVljJoHGDIcxQ16b
                  …【中略】…
fw/rLw6xXDpnPOJjSe0hVRB50W6ux5HwDEod0fC+JZOqxPlJmjUa8TzHEQIDAQAB
-----END RSA PUBLIC KEY-----

をデコードしてみると、162 オクテットの
30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01
05 00 03 81 8d 00
30 81 89 02 81 81 00 c1 e5 95
15 4e 89 3c 8d 6a c4 2e 4f d5 d8 0f 28 ed 9e 3b
            …【中略】…
2d 65 94 d9 2d 2d 6e bf 45 e8 e0 d6 d9 02 03 01
00 01

というデータが格納されていました。このデータは Windows の証明書マネージャの提示する PublicKey 情報とは一致しません。よくよく見てみると、CertMgr で読み取った方には先頭に余分な 22 オクテット (薄ピンクの網掛け部分) が付加されています。その後ろに続く140オクテットは、Windows の証明書マネージャで表示される PublicKey と一致しています。

このデータは DER エンコードされた ASN.1 オブジェクトですので、その構造を解析してみると以下のようになっていました。
SEQUENCE {
SEQUENCE {
OBJECTID: 1.2.840.113549.1.1.1 (RSA Encryption)
NULL
}
BITSTRING:

30 81 89 02 81 81 00 be 02 58 78 d1 4e 7f ea bd
32 aa 23 8c d6 2a 88 81 59 63 26 81 c6 0c 87 31
 …【中略】…
ae c7 91 f0 0c 4a 1d d1 f0 be 25 93 aa c4 f9 49
9a 35 1a f1 3c c7 11 02 03 01 00 01
(unused bits: 0)
}

薄ピンクの網掛け部分が、先のデータの網掛け部分に該当しています。この部分には、鍵の暗号化アルゴリズムの情報が格納されていました。しかし、この情報は PublicKeyAlgorithm フィールドから得られるはずです。なぜこの情報を PublicKey フィールドの値に埋め込むのか開発部隊に確認してみたところ、次のような回答がありました。
  • RSA アルゴリズムの場合は PublicKeyAlgorithm で得られる情報のみで事足りるが、現在は RSA の他 DSA もサポートしている。こちらの場合、前記の ASN.1 フォーマットでは NULL となっている箇所にアルゴリズム用のパラメータを格納する必要がある。
  • しかし、現在のフィールド構成ではそのデータを取得するためのフィールドは存在していない。かといって、今後新たなアルゴリズムが追加されるたびに個別にフィールドを追加するのは大変だ。
  • 従って、PublicKey フィールドの値として返すデータにこの部分を含めることにした。実際、PublicKey として BITSTING 部分を使用する場合にはそのデータが何であるかを提示する必要があるので、この形式を PublicKey として返すことに問題はないはずだ。生の BITSTRING 部分が必要なのであれば、比較的簡単な手順で取り出すことも可能だ。

ある証明書に対し、CertMgr で得られる PublicKey が Windows (や Mozilla/Thunderbird) の提示するデータと異なるのはこういうことなのでした。

2008年3月3日月曜日

.cer ファイルのフォーマットについて

公開鍵をエクスポートする際には、幾つかの形式が選択可能ですが、注意が必要なケースも存在します。

Microsoft の [Control Panel] - [Intrenet Options] - [Content] - [Certificates] で起動される Certificates ダイアログでは Windows レジストリに登録されているユーザストアおよびマシンストアに格納されている証明書のエクスポートをサポートしています。この機能は Certificate Export Wizard で処理されますがこのウィザードでは
  1. DER エンコードの X.509 バイナリファイル
  2. (上記を) Base64 エンコードしたファイル

が共に .cer という拡張子になります。

通常は .cer は前者 (X.509 DER 形式) を指し、後者 (X.509 PEM 形式) に対しては .pem という拡張子を付与するようです。大抵のソフトウェアではファイル書式を自動判別してこれが問題となることは無いようになっているようですが、万一お使いのソフトウェアが .cer ファイルを正しく読み込めない場合は、.cer と .pem を厳密に区別するタイプのものかもしれません。念のため読み込ませる証明書の書式を確認してみることをお勧めします。そして内容がテキストの場合は、拡張子を .pem に変更して再度読み込ませてみるとうまく行くかもしれません。.pem 形式のファイルは、以下のようなテキストになっています。
-----BEGIN CERTIFICATE-----
MIIBlTCB/6ADAgECAgMBAAAwDQYJKoZIhvcNAQEFBQAwEDEOMAwGA1UEAxMFdGVz
…【中略】…
95NT76nIcgvBVR6Z/Rd1zOLknHV7jKhLxw==
-----END CERTIFICATE-----
弊社製品では公開鍵ファイルの読み込みは AddRecipient(Byte[] publicKey) で行いますが、引数として与えるバイト配列データは .cer のものでも .pem のものでも、いずれも受理するようになっています。

2008年2月18日月曜日

ASP.NET が動かない

以前 ASP.NET プロジェクトで発生した奇妙な現象と、その対処法をメモしておきます。

現象:
VisualStudio2005の開発環境下ではテストサーバで正しく動作するのに、実際に XP Pro SP2 上の IIS 5.1 に発行して当該 .aspx を実行すると以下のようなエラーが発生する。

The XML page cannot be displayed

Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.

--------------------------------------------------------------------------------

A name was started with an invalid character. Error processing resource 'http://localhost/IssueTracker/Default.aspx'. Line...
...

原因:

何らかの理由で ASP.NET のバージョンが正しく IIS メタデータに登録されていなかった。恐らく VS2005 のインストールと IIS 5.1 のインストール順序による不整合。

対処法:

  1. [Control Panel] - [Administrative Tools] - [Internet Information Services] で IIS 管理コンソールを開き、問題の発生する .aspx ファイルの格納されている仮想フォルダを選択し、右クリックする。当該フォルダのプロパティウィンドウが表示されるので、ASP.NET タブを選択する。

  2. 右のように、ASP.NET Version 欄が空白になっていたので、適切なバージョンをコンボボックスから選択する。

通常はこれで動作するようになるはずだが、もし別のエラー (Failed to access IIS metabase.) が表示されるようなら、IIS のメタベースにも不整合が生じているので、以下の手順でメタベースの再構築を行う。
  1. 上記で設定したバージョンの .NET Framework フォルダ (%systemroot%\Microsoft.NET\Framework\<versionNumber>) に移動する。

  2. 当該フォルダにある aspnet_regiis.exe を、以下のように実行する。

   aspnet_regiis.exe -ga ASPINET   

以上で、当該 .aspx は動作するようになるはずです。

参考リンク:
A name was started with an invalid character
ローカルIISWebサイトを実行したら"IISメタベースにアクセスできませんでした”というエラーが表示されます。

2008年2月13日水曜日

S/MIME と証明書の登録

弊社では S/MIME 対応の製品を幾つかリリースしています。この S/MIME 製品をご利用いただくことで、電子メールに署名をしたり、暗号化を行うことができます。署名や暗号化には証明書が必要となります。証明書は Verisign 社や Thawte 社等から購入することもできますが、自己署名した証明書を生成し利用することも可能です。自己署名証明書は弊社製品に含まれている CertMgr コンポーネントでも作成可能です。

作成した証明書は、利用する電子メールソフトウェアから利用できるよう登録されなければなりませんが、証明書の管理機構は必ずしも共通化されているわけではありません。例えば Microsoft Outlook であれば、Windows の「インターネットオプション」経由で「証明書ストア」に登録すれば利用可能となりますが、Mozilla Thunderbird はこのデータは参照せず独自の管理機構を使用しますので別途登録が必要です。その他のメールソフトウェアではまた別の機構への登録が必要かもしれません。

以下に Outlook および Thunderbird のための証明書登録方法の一例を示しておきます。どちらも証明書は .pfx ファイルの形で取得しているものと仮定しています。

Outlook の場合(Windows 証明書ストアへの登録)


1. Control Panel から Internet Options を起動し "Content" タブを開きます。
2. タブウィンドウ中ほどにある "Certificates" ボタンをクリックし Certificates ダイアログを表示します。
3. "Import..." ボタンをクリックし Certificate Import Wizard を起動します。
4. "Next >" ボタンをクリックしファイルインポート画面に移動し、証明書ファイル (.pfx) を指定します。
5. "Next >" ボタンをクリックすると Password 画面が表示されますので .pfx ファイルのパスワードを入力します。必要に応じてその他のオプションを指定します。
6. "Next >" ボタンをクリックすると Certificate Store 画面が表示されます。ここでは、当該証明書をどのストアに登録するかを指定できます。
7. "Next >" ボタンをクリックすると確認画面が表示されますので、登録内容を確認し問題なければ Finish ボタンをクリックし登録処理を実行します。

Thunderbird の場合


1. Thunderbird のメニューから [Tools] - [Options...] - [Advanced] で Certificates タブを選択します。
2. "View Certificates" ボタンをクリックし、Certificate Manager を起動します。
3. "Import" ボタンをクリックすると読み込むファイル名を尋ねられるので、.pfx ファイルを指定します。
4. "Please enter the master password for the Software Security Device." と尋ねられるので、パスワードを入力します。既定値では現在の Thunderbird メールアカウントのパスワードになっています。
5. 続いて "Please enter the password that was used to encrypts this certificate backup." と尋ねられるので、当該 .pfx ファイルのパスワードを入力します。
6. 全て正しく処理されれば "Successfully restored your security certificate(s) and private key(s)." と表示され証明書が Thunderbird の Certificate Manager に登録されます。

2008年2月12日火曜日

Gmail への SMTP 接続について

少し前のことになりますが、弊社製品を利用して Gmail 経由でメール送信する方法の有無の問い合わせが、複数の異なる国の異なるお客様から立て続けに数件ありました。(特定の業界では Gmail 利用が現在のトレンドなんでしょうか??)

それはさておき、Gmail では SMTPS を使用することになりますので、弊社 SSL 製品をご利用頂くことでメール送信を行うことができます。以下にコード例を示します。
       Smtps smtps1 = new Smtps();
 
 …【中略】…
 
smtps1.MailServer = "smtp.gmail.com";
smtps1.MailPort = 587;
smtps1.User = <Gmail ユーザ名>; // ex) "abc@gmail.com";
smtps1.Password = <Gmail パスワード>;
smtps1.SSLStartMode = SmtpsSSLStartModes.sslExplicit;

smtps1.SendTo = <受信者アドレス>;
smtps1.From = <送信者アドレス>; // ex) "abc@gmail.com";
smtps1.Subject = "test from IP*Works! SSL V8";

smtps1.MessageText = "Hello, world!\r\nThis is just a test.\r\n";

smtps1.Send();

以上、ご参考まで。

2008年2月4日月曜日

証明書の有効期限の設定

弊社の SSL 製品等のセキュア製品では CertMgr というコンポーネントを提供しており、各種証明書のインポートやエクスポートの他、証明書の生成をサポートしています。

証明書の生成ではプロパティで各種設定を行います。証明書の失効期日は CertExpirationDate プロパティ (V8 では Certificate.ExpirateionDate フィールド) で参照できますが、このプロパティは読み取り専用で設定できません。

この値は、Config 設定の CertValidityTime で設定します。既定値は 365 (日) になっています。この値を 730 にすれば生成される証明書の有効期間は730日 (2年) になります。

2008年1月25日金曜日

Zip 製品における日本語ファイル名について

Zip コンポーネントを使用して日本語のファイル名を持つファイルをアーカイブした場合、他のツールで展開しようとすると文字化けすることがあります。

これは、Zip コンポーネントでは既定値ではシステムの既定値エンコーディングを使用するため、日本語 Windows 以外の Windows で日本語拡張機能を使用し日本語ファイルを保存しようとした場合に使用されるエンコーディングが Shift-JIS 以外のものになってしまうことで発生します。この問題に対処するために、Zip コンポーネントには Encoding コンフィグパラメータが用意されています。Shift-JIS ファイル名のメンバーファイルを格納する際には、
zip.Config("Encoding=SJIS");

のようにすることでメンバファイル名として指定された日本語文字列を、Shift-JIS コードに変換した上でZip アーカイブのファイル情報に書き込みます。

なお、書き込まれたファイル名の文字セット情報はアーカイブの情報としては持ちませんので、メンバファイル名をどの文字セットで解釈するかはプログラマの責任において行って頂くことになります。

アーカイブ生成時に指定した文字セットと、展開時に指定した文字セットが異なる場合、ファイル名を正しく扱うことができません。

アーカイブ作成と展開で日本語ファイル名が正しく処理されない場合には、この Encoding コンフィグパラメータをお試しください。

補足: この Encoding コンフィグパラメータは、メンバファイル名だけでなく同時にパスワード文字列にも影響を与えます。Encoding=SJIS が設定されている場合は、パスワード文字列も Shift-JIS 文字列としてアーカイブに書き込まれます。逆に言うと、ファイル名とパスワードは異なる文字セットを利用することはできません。

バージョン番号、ビルド番号の調べ方

/n software 製品のサポートをご利用いただく際には、ご利用製品のバージョン番号やビルド番号が重要な意味を持ちます。これは、製品は日々修正を加えられ進化しており、バージョン番号やビルド番号が異なる場合、動作や応答に違いがある可能性があるのです。従って、的確なサポートを受けるためにはこれらを把握しておく必要があります。

では、以下にこれらの番号の調べ方をまとめておきましょう。

  • ご利用いただいている製品のインストーラ (setup.exe) が手元にある場合

    setup.exe を起動します。起動直後に表示されるスプラッシュスクリーンにバージョン番号およびビルド番号が記載されています。


  • インストール済みの製品自体で調べる場合

    • Windows 製品の場合
      • 当該製品の DLL ファイルを右クリックし、ファイルプロパティで製品バージョンを表示します。
      • .NET 製品の場合は、実行時に以下のコードを実行することでも製品バージョンを知ることができます。
        System.Console.WriteLine(snmptrapmgr1.GetType().Assembly.FullName);
      この結果表示されたものが 8.0.2991.0 であれば、Version 8.0 Build 2991 であることを表します。
    • Java 製品の場合は、以下のような簡単なコードをコンパイルし実行することで知ることができます。
      • V8 の場合:
        System.out.println(ipworks.AboutPropertyEditor.getVersion());
      • V6 の場合:
        System.out.println(ipworks.AboutPropertyEditor.VERSION);
      この結果表示されたものが 8.0.0.2938 であれば、Version 8.0 Build 2938 を意味します。

注: Windows 製品と Java 製品では、ビルド番号の表示位置が異なります。

2008年1月23日水曜日

Control.Invoke / InvokeThrough について・その後


先の記事で紹介した Control.Invoke の件ですが、V8 では .NET CF Edition でも InvokeThrough プロパティがサポートされるようになりそうです。

これにより .NET Edition でもイベント周りのコードディングが簡略化され作成が容易になると思います。現時点では IP*Works! V8 (Core) の社内テストビルドにのみ実装されていますが、特に問題が発生しなければ順次他の製品にも反映されると思います。

2008年1月21日月曜日

Command プロパティについて

IP*Works! 製品では、各コンポーネントは準拠する規格 (あるいはデファクト・スタンダード) に則りメソッドやプロパティを設計してあります。

通常の用途であれば、当該コンポーネントに用意されているこれらのメソッドやプロパティを使用することでほぼ問題なく通信を行うことができます。

しかし、サーバ側が独自の拡張コマンドを使用する場合や、IP*Works! 製品が準拠している規格が改訂され新たにコマンドが追加されたような場合には、既存のメソッドやプロパティでは対処しきれないことがあるかも知れません。

このような場合には、Command プロパティを使用して対応することができます。

この Command プロパティにコマンド文字列を代入すると、当該コマンドがサーバに対し送信されます。

Command プロパティに対するサーバからの応答は、LastReply プロパティまたは PITrail イベントを使用して取得します。

このプロパティは、当該コンポーネントの実装するプロトコルがテキストコマンドおよびテキスト応答を使用する場合にのみ提供されます。例えば、IP*Works! V8 Core では以下のコンポーネントでのみこのプロパティをご利用いただけます。
  • FileMailer
  • FTP
  • HTMLMailer
  • IMAP
  • NNTP
  • POP
  • Rexec
  • Rshell
  • SMTP
  • SNPP
  • Telnet
例えば FTP には Command プロパティが提供されていますが、よく似た処理をするはずの TFTP には提供されていません。これは、前者はテキストベースのコマンド/応答をサポートしていますが後者はバイナリコードによるコマンド/応答で動作することによります。

2008年1月17日木曜日

About Box (ライセンスダイアログ) について・その2

先日の投稿では .NET Edition におけるライセンスの認識方法を示しました。これは WinForm を前提としていましたが、ASP.NET では少々状況が異なります。

ASP.NET には 1.1 および 2.0 が存在します。

ASP.NET 1.1 アプリケーションでは、WinForm の場合と同様に licenses.licx を用いた Microsoft .NET Licensing Scheme を使用します。従ってその対処法も先の投稿と同じです。

一方 Visual Studio 2005 の ASP.NET 2.0 アプリケーションの場合はちょっと複雑な手順を要します。

  1. ソリューションエクスプローラ内で、licenses.licx を右クリック

  2. ランタイムライセンスの作成を選択

これにより、App_Licenses.dll が生成されますので、これを作成した ASP.NET 2.0 アプリケーションとともに配布する必要があります。

2008年1月8日火曜日

About Box (ライセンスダイアログ) について

比較的高い頻度でサポートに寄せられるお問い合わせに、「IP*Works! の製品版をインストールしたのに、About Box (ライセンスダイアログ) が表示される」というものがあります。今回は .NET Edition を例に、ライセンスの仕組みと対処法を解説してみたいと思います。

NET Edition では、製品ライセンスに Microsoft Licensing scheme を使用します。これにより、ライセンス済みのコンポーネントをフォームにドロップした時点で "licenses.licx" という名称のファイルが自動生成され、埋め込みリソース (embedded resource) として当該プロジェクトに自動追加されます。Visual Studio .NET 内でライセンス済みコンポーネントを使用するにはこのファイルが必要で、このファイルが存在しないあるいはファイル内に正しい情報が記載されていない場合、About Box が表示されます。

ではフォームを使用しないアプリケーションの場合や、フォームを使用するけれど動的にコンポーネントを生成する場合はどうすれば良いでしょうか。

このような場合には licenses.licx ファイルを手で作成することで対処します。このファイルはライセンス済みコンポーネントの情報から成る行で構成されています。各行にはコンポーネント名およびライブラリ名が記述されています。例えば、nsoftware.IPWorks.dll の NNTP コンポーネントを使用するのであれば licx ファイルには
nsoftware.IPWorks.Nntp, nsoftware.IPWorks
という行が含まれることになります。

なお既定値では Visual Studio は上記以外の付加情報 (バージョン番号やカルチャ等) もこの行に含めます。もしライセンス上の問題が発生した場合は、これらの付加情報を削除し、前述の2項目 (コンポーネント名およびライブラリ名) のみにしてみると状況が改善することがあります。

licenses.licx に関する注意事項:
  1. licx ファイルを手作業で作成する場合は、ソリューションエクスプローラを通じて当該プロジェクトに対する埋め込みリソースとして追加されなければなりません。
  2. licx ファイルは "licenses.licx" という名称でなければならず、また当該プロジェクトのルートディレクトリに配置されなければなりません。(サブフォルダに配置することはできません。)
  3. 開発対象がクラスライブラリの場合は、呼び出し側アプリケーションに対し当該 licenses.licx ファイルをクラスライブラリとともに配布する必要があります。さらに、呼び出し側アプリケーションは当該製品がアクティブ化済みになっているマシン上でコンパイルされなければなりません。(簡単に言えば、クラスライブラリはそれ自身は royalty-free で配布することは認められていません。)

最後にもう1つ注意すべき点があります。Visual Studio .NET はプロジェクト名に空白文字 (" ") が含まれている場合、正しく licx ファイルを認識しないという問題があります。もしプロジェクト名がこれに該当する場合は、プロジェクト名から空白文字を除去するか、別の文字に置き換えてからプロジェクトをリビルドしてみてください。

2008年1月5日土曜日

明けましておめでとうございます。

いよいよ2008年が始まりました。

皆様は初詣に行かれましたでしょうか。

私は3が日明けの1月4日に、妻の実家に近い伊勢神宮の外宮に行きました。ちょうど各党の党首の参拝と重なってしまったようで、某党の党首や総理の参拝にぶつかりかなりの混雑で少々難儀をしました。

その時、こういった場合の移動プラン等はどのくらい公開されるのかに興味を持ちました。

要人は常にテロを避けるための隠密性と、活動をアピールするための公開性の両方のバランスを考え行動する必要があるでしょう。また、提供する情報の粒度(詳細さ)もいろいろなレベルがあります。

これはコンピュータで提供するサービスのセキュリティと利便性の最良の落とし所を決めるのとちょっと似ているなぁ、などと思いました。

まぁ、一般人としては事情を知らずに現地に行っても、混雑を避けうる程度の情報はその場で得られるくらいはして欲しい、という愚痴にすぎませんが (^_^);