Comments
Description
Transcript
WWW に基づいた インターネットメールシステムの構築
WWW に基づいたインターネットメールシステムの構築 1998 年度 修士学位申請論文 指導教員 井田昌之 WWW に基づいた インターネットメールシステムの構築 A Design and an Implementation of the Internet e-Mail System Based on World Wide Web Technology 大学院国際政治経済学研究科 国際ビジネス専攻 氏名 公文善之 WWW に基づいたインターネットメールシステムの構築 概要 WWW の登場により、この数年間のインターネット技術の発展には目を見張るものがある。 インターネットアプリケーションとしては、WWW と並んでメールシステムが非常に大きな役 割を果たしている。メールシステムは一般に、利用者側の機能と、管理者側の機能に大別される。 本論文は、メールシステムの双方の機能を対象としてる。 現在のインターネットメールシステムは、各プラットフォームごとにさまざまなものがある。 それらは、類似した機能を持ったものであるが、各々の操作・用語等に違いがある。利用者は増 えているものの、これらのソフトウエアの操作上の違いや、用語の複雑さのために利用は必ずし も簡単なものではなく、このままでは戸惑いが生じ出している。一方管理者側でも、利用者が増 えることによるサポートの増加や、メンテナンスのための人員確保において、複雑化するシステ ムに対応することができなくなりつつある。 本論文では、現状での利用・運用上の問題の所在を確認・解析し、問題解決の手段として WWW を基本としたインターネットメールシステムを設計・構築する手法ならびに実現形態について論 述する。WWW を利用したシステムでは、 「プラットフォーム独立性」や「アクセスの普遍性」、 「ユーザインタフェイスの統一」 、「セキュリティ対策の容易さ」、 「プログラム・システムのライ フサイクルの独立化」 、 「システム運営の効率化」等が重要な考慮点であることを指摘し、技術的 および経済的な利点のあるシステム構築に関する設計を行った。 次に、システムの試作を行った。システムの試作は、本論文で述べる設計をもとに行い、その 後、これらの目標・設計との比較評価を行うことにより、設計が実現可能であることを示した。 そして、利用側、運用側双方に利点があることを示した。 1 WWW に基づいたインターネットメールシステムの構築 目次 概要 ......................................................................................................................................... 1 目次 ......................................................................................................................................... 2 1 はじめに ........................................................................................................................... 5 1.1 緒言 ........................................................................................................................... 5 1.2 研究対象 .................................................................................................................... 5 1.3 研究目的 .................................................................................................................... 5 1.4 論文の構成 ................................................................................................................. 6 1.4.1 2 1.4.2 2 章 問題の所在とその解析................................................................................. 6 1.4.3 3 章 WWW を利用した、メールシステムの概念設計.......................................... 6 1.4.4 4 章 システムの具体的な設計 ............................................................................. 6 1.4.5 5 章 システムの試作とその評価.......................................................................... 6 1.4.6 6 章 まとめ ......................................................................................................... 7 1.4.7 付録 .................................................................................................................... 7 問題点の所在とその解析 ................................................................................................... 8 2.1 メーラの現状: ユーザの視点 ...................................................................................... 8 2.1.1 問題点の所在....................................................................................................... 8 2.1.2 代表的なメーラの比較......................................................................................... 9 2.1.3 メーラ機能比較とそれによる共通的な機能の抽出 ............................................. 14 2.2 メールシステム管理の現状: 管理者の視点 ............................................................... 18 2.2.1 問題点の所在..................................................................................................... 19 2.2.2 実際の経験から ................................................................................................. 20 2.3 メールシステム発展に関する歴史的認識.................................................................. 22 2.3.1 メールは UNIX 上で ......................................................................................... 22 2.3.2 POP の利用....................................................................................................... 23 2.3.3 IMAP の利用..................................................................................................... 25 2.3.4 WWW を利用.................................................................................................... 26 2.3.5 各メーラの位置関係 .......................................................................................... 27 2.4 3 1 章 はじめに ..................................................................................................... 6 WEB メーラの現状 .................................................................................................. 28 2.4.1 インターネットサイトのサービスとしての WWW メール ................................. 28 2.4.2 イントラネットサイトで導入される WWW メール ........................................... 29 2.4.3 WEB メーラの機能比較と本論文での開発との関係........................................... 30 WWW を採用したメールシステムの概念設計 ................................................................. 32 2 WWW に基づいたインターネットメールシステムの構築 3.1 構築する体系の基本概念 .......................................................................................... 32 3.1.1 ユーザ側の概念設計 .......................................................................................... 33 3.1.2 管理側の概念設計.............................................................................................. 36 3.2 WWW を基本としたメールシステムの期待する利点................................................ 38 3.2.1 4 3.2.2 アクセスの普遍性.............................................................................................. 38 3.2.3 ユーザインタフェイスの統一 ............................................................................ 38 3.2.4 セキュリティ対策の容易さ................................................................................ 39 3.2.5 プログラム・システムのライフサイクルの独立化 ............................................. 39 3.2.6 システム運用の効率化....................................................................................... 39 システムの具体的な設計 ................................................................................................. 40 4.1 ユーザ登録から認証システムの設計......................................................................... 40 4.1.1 ユーザ登録 ........................................................................................................ 40 4.1.2 認証システム..................................................................................................... 41 4.1.3 RDBMS 利用の利点 .......................................................................................... 42 4.2 メーラの設計: JAVA の利用 ....................................................................................... 42 4.2.1 詳細な設計 ........................................................................................................ 43 4.2.2 メールの保存場所.............................................................................................. 43 4.2.3 メールの保存形式.............................................................................................. 44 4.2.4 Java 利用の利点 ............................................................................................... 44 4.2.5 Java 利用の問題点 ............................................................................................ 45 4.2.6 JDK 1.2 利用の利点/問題点............................................................................... 46 4.3 5 プラットフォーム独立性 ................................................................................... 38 管理システムの設計 ................................................................................................. 47 4.3.1 ユーザ情報変更システムの設計......................................................................... 48 4.3.2 メール蓄積量管理システムの設計 ..................................................................... 48 4.3.3 ユーザ削除機能の設計....................................................................................... 49 4.3.4 システムパラメータの管理................................................................................ 50 システムの試作とその評価.............................................................................................. 51 5.1 ユーザ登録・認証システムの概要 ............................................................................ 51 5.1.1 ユーザ登録機能・概要....................................................................................... 51 5.1.2 ユーザ認証、ログイン機能・概要 ..................................................................... 53 5.2 メーラの概要 ........................................................................................................... 54 5.2.1 ユーザインタフェイス・機能概要 ..................................................................... 55 5.2.2 開発環境の現時点での問題点 ............................................................................ 58 5.3 管理システム概要..................................................................................................... 59 5.3.1 管理メニュー機能一覧....................................................................................... 59 5.3.2 ユーザ情報管理機能・概要................................................................................ 60 5.3.3 ユーザ削除画面 ................................................................................................. 61 5.3.4 メール蓄積量管理機能・概要 ............................................................................ 62 3 WWW に基づいたインターネットメールシステムの構築 5.3.5 5.4 6 システムパラメータ設定機能・概要.................................................................. 63 試作評価 .................................................................................................................. 65 5.4.1 設計目標との比較・評価 / 理論上の評価 .......................................................... 65 5.4.2 具体設計との比較・評価 / 技術的評価 ............................................................. 66 まとめ............................................................................................................................. 68 6.1 結論 ......................................................................................................................... 68 6.2 今後の課題 ............................................................................................................... 68 ACKNOWLEDGEMENT...................................................................................................... 68 参考文献・参考 WWW サイト................................................................................................ 70 付録 ....................................................................................................................................... 71 プログラムソースコード..................................................................................................... 71 [A] メーラ Java ソースコード ....................................................................................... 71 [B] CGI、サーバサイドプログラム ソースコード........................................................... 89 4 WWW に基づいたインターネットメールシステムの構築 1 はじめに 本章では、この論文についての緒言、研究目的、研究対象、論文の構成を述べる。 1.1 緒言 今日インターネットは急速に発展し、便利になった。特に WWW の登場以来のインターネッ トの進化は、めざましい。WWW の普及により発展が加速したインターネットではあるが、依 然としてメールシステムは、 ユーザ同士のコミュニケーションのツールとして重要な位置を占め ている。このインターネットメールシステムの普及に伴い、メールシステムは専門家ではない一 般のエンドユーザに対する道具となってきた。それに関する論文である。 現在利用されているインターネットメールシステムの設計には、いくつかの問題がある。 WWW を利用することは、問題解決のための方法のひとつである。 1.2 研究対象 本論文が研究対象とするのは、インターネット上のメールシステムである。その中で、直接ユ ーザが利用するメールクライアント、および、そのシステムの管理者が利用する管理ソフトウエ アである。また、構築する概念として WWW の技術に基づくメーラを目的としているため、対 象となるシステムは、WWW に基づくメールシステムである。 このメールシステムは、広く公のサービスとしてではなく、イントラネットサイトでのサービ スとして導入される場合を対象としている。その理由は、不特定多数に向けてのサービスとして 立ち上げる場合には、システム構成等もプロモーションその他のマーケティング要素が入り、本 論文の目的からそれてしまうからである。 1.3 研究目的 本論文の目的は、インターネットメールシステムの問題点を指摘し、その問題点を改善するも のとして、WWW に基づくシステムの具体的な設計・試作を通して論文で主張する概念を検証 する。 また、システムの中核となるメールクライアント部分を Java アプレットを利用して実現する。 本論文では、国際標準をベースとする。このため、開発環境としては、今後 ISO として国際標 準となることが確定している JDK 1.2 の規格を用いる。これにより、旧来のバージョンでの未 定部分がなく将来にわたって利用可能となる。1999 年 1 月現在一般に公開されている商品やフ 5 WWW に基づいたインターネットメールシステムの構築 リーで利用できる WWW メールサイトでも JDK 1.2 を利用しているところは無い。JDK1.2 は 国際標準となることが想定されるが、現時点の処理系ではまだ問題がある可能性が高い。よって、 JDK1.2 処理系の実用レベルの評価も同時に行う。 1.4 論文の構成 本論文は、以下のように構成される。 1.4.1 1 章 はじめに 論文執筆の動機付けを示す緒言をのべ、その後に、本論文の目的、対象を明らかにし、論文全 体の構成を示している。 1.4.2 2 章 問題の所在とその解析 メールシステムの利用者を、ユーザと管理者に分け、双方の視点からの現状の問題点を指摘し、 解析をしている。 ユーザの視点からは、現状のメーラの比較を行い、共通機能の抽出を行うことによって、メー ラの基本機能を解析している。管理者の視点からは、さまざまな管理コスト増加の問題を指摘し、 それを実際の経験からも解析している。 そして、これらの問題に至るまでを、メールシステムの発展の歴史から認識している。 その後、WWW を利用したメーラの現状を、インターネットサイトのサービス、イントラネ ットサイトのサービスに分けて分析し、本論文での開発との関係を明確にしている。 1.4.3 3 章 WWW を利用した、メールシステムの概念設計 構築するメールシステムを WWW に基づくものとし、2 章で述べたように、ユーザと管理者 に分け、別々にシステムの概念設計を示している。 次に、WWW に基づくメールシステムの期待する利点を述べ、設計目標としている。 1.4.4 4 章 システムの具体的な設計 3 章で述べたシステム概念に対する具体的な設計の一例を述べている。システムを、ユーザ登 録から認証システム、メーラ、そして管理システムと 3 つの部分に分けて、それぞれの設計を 示している。 1.4.5 5 章 システムの試作とその評価 4 章の具体的な設計に基づいて、ユーザ登録・認証システム、メーラおよび、管理システムを 実際に試作し、本論文で概念設計・具体的な設計が確かに実現可能であることを示している。ま 6 WWW に基づいたインターネットメールシステムの構築 た、試作にあたって利用した開発環境である正式リリース直後(1998 年 12 月リリース)の JDK の現状での問題点を述べている。 その後、これらの試作を通して評価を述べる。 1.4.6 6 章 まとめ 本論文での結論、および、結果として残った問題点を、今後の課題として述べている。 1.4.7 付録 5 章で試作したシステムのソースコードレベルでの解説と、開発ソースコードを付録としてい る。 7 WWW に基づいたインターネットメールシステムの構築 2 問題点の所在とその解析 本章では、現状の問題点の所在を確認し、その内容を解析する。インターネットメールシステ ムを利用するにあたっての問題点を、大きく分けて 2 つの視点から解析する。それは、1)利用す るユーザの視点、2)そのシステムを運営・管理する管理者の視点である。1 節は、ユーザ側の視 点を、2 節では管理者の視点としての解析を取り上げる。この双方の視点で問題を捕らえること によって、全体としてのシステムの目指す目標をはっきりさせる。 2.1 メーラの現状: ユーザの視点 ユーザ側の視点から解析する対象は、メーラ(実際にインターネットメールを送受信するソフ ト)である。利用者にとって、メーラの善し悪し、使い勝手が直接触れるものであって、評価の 対象となってしまう。その点で大きな意味を持っている。この節では、最初に全体としての問題 点の所在を確認した上で、具体的にいくつかの代表的なメーラを取り上げて、メーラの現状がど うなっているかを解析する。 2.1.1 問題点の所在 インターネットメールの送受信は、現在様々なプラットフォームで、可能となった。しかし、 「等しく可能である」わけではなく、各プラットフォームごとに大きく「違い」がある。問題点 はこの「違い」による部分が大きい。 近年のインターネットの急速な普及により、インターネットメールの利用ユーザは急速に増加 している。以前は、メールの利用者と研究者・技術者が比較的同義であったので、様々な相違点 は表面的なもので、本質的な問題点とはされなかった。しかし、現在メールの利用者は圧倒的に 初心者ユーザが多く、インターネットそのものの理解すらない可能性のほうが、むしろ高いとい える。この状況では、表面的と思われていた小さな違いが、ユーザにとって決定的な問題をもた らすことになる。 もともとインターネットは、UNIX の相互接続からはじまったものなので、最初にメールシス テムが利用されるようになったのも UNIX 上である。UNIX 上では、今でも最もシンプルなメ ールコマンド mail なども残っている。当時のメーラは、現在のようにメールヘッダの一覧か ら読みたいメールを選んで閲覧したり、読んだメールをフォルダに振り分けて整理するようなタ イプではなく、単純に上から順番(正確には逆順)に読むことしかできなかった。 UNIX は基本操作が CUI なので、メールの送受信も CUI で行うことが多い。一方、インター ネットの普及にしたがって、Macintosh や、DOS/V マシンでもインターネットメールの読み書 8 WWW に基づいたインターネットメールシステムの構築 きができるようになった。これらのコンピュータ上の OS は GUI1 が基本となっているので、メ ーラも自然と GUI ベースのものになる。 2.1.2 代表的なメーラの比較 ここで、一般的に使われていると思われる GUI ベースの代表的なメーラの使用方法の概要を 説明する。それは、これから述べる問題、様々な相違点を明確に示すためである。対象は、 Windows 95/98/NT/MacOS 上 で 利 用 さ れ る Eudora Pro( 以下 Eudora) お よ び 、 Outlook Express とする。 2.1.2.1 Outlook Express / Microsoft 概要 1) 画面構成: 下図 1 は、Microsoft 社2 のメーラ Outlook Express Windows 版のメール受信画面である。基 本的な操作はほとんどこの画面で行う。 図 1 Outlook Express 全体画面 1 2 Graphic User Interface の略。文字ベースのユーザインタフェイスに対してグラフィックを使ったユーザ インタフェイス。 http://www.microsoft.com/ 9 WWW に基づいたインターネットメールシステムの構築 各部品の機能・内容は以下の通りである: 1. 新規メールの作成 2. 差出人に対しての返信メールを作成 3. 差出人および、受信者全員に対しての返信メールを作成 4. 受信者以外にメールを転送 5. 送信トレイに入っているメールの一括送信と受信 6. メールの削除 7. (メールアドレスの)アドレス帳を開く 8. 受信されたメールで使用される言語を指定 9. 受信メールの一覧 10. 各メールボックスの一覧(受信トレイ、送信トレイ、送信済みアイテム、削除済みアイ テム、下書きおよび、ユーザ自身が作成したメールボックスが並ぶ) 11. 9 で選択されているメールの内容 2) 基本送受信: 次に、最低限度の基本操作に触れる。メールを受信する場合は、5 の「送受信」ボタンを押す。 そうすると、10 に受信トレイが選択されている場合は、9 に受信されたメールの一覧が表示さ れる。内容を確認するためには、9 の一覧から確認するメールを選択する。選択されたメールの 内容が 11 に表示される。内容を別ウィンドウ上で確認する場合は、9 上の確認したいメールを ダブルクリックする。 新規メールを送信する場合は、まず 1 を押して、新規メール作成ウィンドウを開く。その後、 内容を入力し、作成ウィンドウ上の「送信」ボタンを押す。 2.1.2.2 Eudora Pro J3 / KUNI RESEARCH INTERNATIONAL 概要 1) 画面構成: 以下図 2 はクニリサーチインターナショナル社4 のメーラ Eudora Pro J のメール受信画面であ る。こちらも基本的にこの画面でほとんどの操作を行う。画面は、Macintosh 版を使用したが、 製品は、Windows 版/Macintosh 版それぞれあり、多少の画面上の違いはある。 3 4 画面のバージョンは、3.x http://www.kuni.co.jp/ 10 WWW に基づいたインターネットメールシステムの構築 図 2 Eudora Pro / KUNI RESEARCH INTERNATIONAL 各部品の機能・内容は以下の通りである: 1. メールの削除 2. 送信メールボックスを開く 3. 受信メールボックスを開く 4. メールの受信 5. 新規メールの作成 6. 返信メールの作成 7. メールの転送 8. メールの回送 9. 添付書類の選択 10. スペルチェック 11. アドレス帳 12. メールの印刷 13. 受信メールの一覧 14. 選択された受信メールを開いたもの 11 WWW に基づいたインターネットメールシステムの構築 2) 基本送受信: こちらも同様に、基本操作を把握する。メールの受信をする場合は、4 の「メールの確認」を 押す。新規メールが到着している場合は、13 の「受信簿(Outlook Express でいう受信トレイ)」 が開く。確認したメールをダブルクリックすると、14 の確認用のウィンドウが開く。 新規メールの送信をする場合は、5 の「新規メッセージ」を押す。新規メール作成用のウィン ドウが開くので、内容を入力して、そのウィンドウ右上にある「送信」ボタンを押す。 2.1.2.3 代表的なメーラ間の相違と対処例 以上 2 つの代表的なメーラを取り上げて、基本画面、基本操作を紹介した。基本画面、基本操 作ともに、ユーザが様々にカスタマイズしたり、様々な操作方法で同様の機能が実行される。ま た、各メーラとも、プラットフォームによって多少の概観、操作の違いがあるため、どの事項に 関しても上記の例の限りではない。これらの内容から、現状の問題点として上げられるものをま とめると、以下のようになる。 • 操作体系の違い • 設定項目の違い • 使われる用語の意味の違いと複雑さ 「操作体系の違い」に関しては、各プラットフォーム、各ソフトウエアによってもさまざまで、 メールを受信するという動作ひとつをとってもさまざまである。 例えば、 Macintosh の Eudora Pro では、「メールの確認」となっているが、Windowsの Outlook Express では、 「送受信」という項目と、 「すべてダウンロード」という項目になっており、単純 な受信作業は無いように思われる。これが、UNIX の標準 mail コマンドになった場合は、すべ て端末上からコマンド入力により行うことになる。これらの相違は、各ソフトウエアの歴史的な 経緯に由来するものだと思われる。 Eudora Pro は、もともと Macintosh 上のフリーウエア Eudora の商用パッケージである。 Eudora は、研究室等で POP が利用され始めた当初に利用が始まったソフトウエアである。当 時はインターネットに専用線接続された研究室等でのクライアント端末で利用されていた。つま り、専用線での利用を前提にしている。一方、Outlook Express は、Microsoft 社が Internet Explorer 4.0 のリリースとあわせて作ったもので、利用環境は、専用線ではなく、ダイアルアッ プ接続のユーザを主な対象にしている。そのため、メールは基本的にオフラインで書いておき、 オンラインになっている間に送信、受信作業を同時に行うことを前提にしている。UNIX の mail コマンドはもっとずっと原始的な仕組みで、メールが蓄積されているサーバ上にログインし直接 メールを読むことを前提にしている。 次に、「設定項目の違い」に関して。メールの送受信が可能になるためには、まず諸々の設定 をする必要がある。しかし、この設定する内容に関しても非常に複雑で、多くの違いがある。例 12 WWW に基づいたインターネットメールシステムの構築 えば、最低限設定する必要のある項目として、SMTP5 サーバ、POP36 サーバまたは IMAP47 サ ーバ、自分のメールアドレスまたは、メールアカウント名、認証のためのパスワード等がある。 ここで、前述の例での Eudora と Outlook Express の例を見てみる。Eudora では、メール受 信のための POP サーバと SMTP サーバの設定と受信用メールアドレスの設定をするのだが、 設 定項目としては、POP アカウント、返信アドレス、SMTP サーバの 3 項目となる。また、Outlook Express の方では、電子メールアドレス、受信メール(POP3 または IMAP4)サーバ、送信メー ル(SMTP)サーバ、アカウント名、パスワードとなる。この時点ではあまり大きな違いがないよ うに感じられるかもしれないので、私の大学院での設定で比較することにする。 Macintosh / Eudora Pro J POP アカウント: [email protected] … (1) 返信アドレス: [email protected] … (2) SMTP サーバ: daisy.sipeb.aoyama.ac.jp … (3) Windows 95/98/NT / Outlook Express 電子メールアドレス: [email protected] … (4) 受信メールサーバ: daisy.sipeb.aoyama.ac.jp … (5) 送信メールサーバ: daisy.sipeb.aoyama.ac.jp … (6) アカウント名: kumon … (7) パスワード: ****** … (8) となる。比較結果は以下のようになる。 • (1)と同じものは、Outlook Express の方には存在していない。代わりに (5) + (7) とい う形で実現されている。内部的には、Eudora の方が (1) を@で分割して、左側をアカ ウント、右側を POP サーバ名として使うことになる。 • Eudora の方では、パスワードを最初から入力することはなく、パスワードの保存が別 の設定項目としてある。そして、パスワードは、最初のメール受信の時に聞かれるこ とになる。 • (2)と(4)も内部的には、Reply-to ヘッダ8 として利用されることはわかるが、設定項目 としては、初心者には別物に見える可能性がある。 • (3)と(6)については意味としては、まったく同じである。 これらの設定項目は、必須項目であり、全体の設定内容のほんの一部分に過ぎない。以前のメ ーラと比べて、最近のメーラは非常に多機能な分、設定項目も多い。その各設定内容は、実際に 5 6 7 8 Simple Mail Transfer Protocol の略で、メールを送信するための仕組み。RFC 821。 Post Office Protocol 3 の略で、メールを遠隔で受信するための仕組み。POP3 では、メールは、基本的 に端末に取り込まれる。RFC 1939。 Interactive Mail Access Protocol の略で、メールを遠隔で受信するための仕組み。IMAP では、メール のコピーはサーバ側に置くことになる。RFC2060 IMAP4rev1。 RFC 822 Standard for The Format of ARPA Internet Text Messages に規定されている。 13 WWW に基づいたインターネットメールシステムの構築 は、インターネットメールの技術を理解していないと理解できないものがほとんどであるため、 増加する初心者には利用への障壁となる。 設定項目が基本的な設定項目以外にも多くの項目を含んでいるのは、近年のメーラが、メーラ の自身の「おすすめの使い方」に対して関与し始めてきたことを示している。 「利用される用語の複雑さ」に関しては、前述の 2 つの項目と共通する部分がある。前述の 2 項目のような問題が起きるそもそもの原因であるともいえる。メールの送受信という作業は GUI での操作では特に実際のやりとりされるプロトコル等に関してはみえてこない。初心者に とっては、みえることこそが問題だが、様々に利用される用語を統一しておかないと、混乱のも ととなる。 2.1.3 メーラ機能比較とそれによる共通的な機能の抽出 これまで、各プラットフォームの主なメーラの紹介をしてきた。本項では、Windows プラッ トフォームでのメーラの主な機能の比較をする。 以下の表9 (表 1-4)は、比較する 1)ソフトウエアの概要、2)メールの送信/返信機能、3)メールの 保守機能、4)その他の機能の一覧である。2、3、4 中の○、×、△は、それぞれ、対応、未対応、 制限付きの対応を示している。比較対象として取り上げることのできるメーラは、非常に少数で 限られたものである。しかし、その少数の中でも非常に様々な機能の違いがあることがわかる。 また、この表で取り上げた機能は、多くのメーラが採用している機能である。ここで、多くの メーラが採用している共通的な機能を抽出することにより、本質的にメーラとして必要な機能/ そうでない機能が含まれていることが分かる。後述の 3.1 では、これらの機能を取り上げ、その 中でメーラが最低限度実装するべき機能を考える。 2.1.3.1 ソフトウエアの概要 以下表 1、2 は比較対象とするソフトウエアの外観を示すものである。その内容は、バージョ ン、ファイルサイズ、必要ディスク容量、ソフトウエアの種類(シェアウエア/フリーウエア/市販)、 価格、著作者、販売元である。各ソフトウエアでファイルサイズ、必要ディスク容量に大きな違 いがあることが分かる。 表 1 ソフトウエアの概要 (1) ソフトウェア名 Becky! Al-Mail akira32Gold 電信八号 バージョン Ver 1.20 Ver 1.32 Ver 2.9z7 Ver 321.0 ファイルサイズ 1,204KB 730.KB 829KB 371KB 必要ディスク容量 2.51MB 0.85MB 1.73MB 0.98MB ソフトウェアの種類 シェアウェア シェアウェア シェアウェア フリーウェア 価格 4,000円 2,000円 4,500円 無料 著作者 乗松知博氏 中村匡志氏 黒木 茂氏 石岡 隆光氏 9 http://softplaza.biglobe.or.jp/text/mailer/hikaku.html を参考にし、修正を加えたもの。 14 WWW に基づいたインターネットメールシステムの構築 販売元 リム・アーツソフトウェア クレアル 表 2 ソフトウエアの概要(2) ソフトウェア名 EUDORA PRO Internet Mail Netscape Mail WeMail Winbiff バージョン Ver3.01J 4.70.1161 Ver3.01Ja Ver1.40(32) Ver1.62 ファイルサイズ - 1,960KB - 1,425KB 必要ディスク容量 8MB 2.3MB 4.5MB *1 10MB 以 上 2.2MB 2,209KB 推奨 ソフトウェアの種類 市販 フリーウェア 市販 シェアウェア シェアウェア 価格 12,800円 無料 3,000 円 著作者 クニリサーチインタ マイクロソフ 日本ネットスケ NECテレコ オレンジソフト ーナショナル ト ープコミュニケ ムシステム 4,000円 3,000 円 ーションズ 販売元 〃 〃 NEC 〃 〃 2.1.3.2 メールの送信/返信機能 以下表 3 は、メールの送信/返信を行うときの機能を比較したものである。主な機能上の相違 点は、添付ファイルのエンコーディング方式への対応にある。一般的には MIME1 0 のマルチパー トを扱う場合 Base64 でのエンコーディングが多い。BinHex、uuencode はそれぞれがもともと、 Macintosh、UNIX で多く使われていたエンコーディング方式である。そのため、それらのプラ ットフォームとのメールの送受信を意識するかしないかが、この対応の程度に影響を与えている ことが分かる。 表 3 メールの送信/返信機能 ソフトウェア名 Becky! Al-Mail akira32 電信八号 Gold EUDORA Internet Netscape PRO Mail Mail WeMail Winbiff CC送信 ○ ○ ○ ○ ○ ○ ○ ○ ○ BCC送信 ○ ○ ○ ○ ○ × ○ ○ ○ 差出人へ返信 ○ ○ ○ ○ ○ ○ ○ ○ ○ 全員へ返信 ○ ○ ○ ○ ○ ○ ○ × ○ 転送 ○ ○ ○ ○ ○ ○ ○ ○ ○ 複数メールの一括送信 ○ ○ ○ ○ ○ ○ ○ ○ ○ 10 RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One, RFC 2046 Multipurpose Internet Mail Extensions (MIME) Part Two, RFC 2047 MIME (Multipurpose Internet Mail Extensions) Part Three, RFC 2048 Multipurpose Internet Mail Extensions (MIME) Part Four, RFC 2049 Multipurpose Internet Mail Extensions (MIME) Part Five, 2231 MIME Parameter Value and Encoded Word Extensions 15 WWW に基づいたインターネットメールシステムの構築 添付ファイル Base64 ○ ○ ○ ○ ○ ○ ○ ○ ○ BinHex ○ ○ × × ○ × × × ○ uuencode ○ ○ ○ △*1 ○ △*2 × ○ ○ 署名の添付 ○ ○ ○ ○ ○ ○ ○ ○ ○ 引用符のカスタマイズ ○ ○ ○ ○ ○ △*3 × ○ ○ 引用文字のカスタマイズ ○ ○ × ○ ○ × × ○ × *1 デコード形式のみ対応 *2 エンコード形式のみ対応 *3 3 種類から選択 2.1.3.3 メールの保守機能 次に、表 4 は、受信メールを保守する機能に関する比較の一覧である。機能は大きく分けて、 着信メールのフォルダ別管理に関する機能、検索・ソート機能、他のメーラからの移行のための 機能に分かれる。フォルダ管理の機能はすべてのメーラが実装しているが、そのフォルダへの自 動振り分けや、フォルダの階層化は実装していないものもある。メールのスレッド表示に関して は、利用/作成者の利用価値観が分かれるところである。他のメーラからのメール取り込み機能 は、メーラ間のデータの普遍性を持たせる意味では良い機能である。 表 4 メールの保守機能 ソフトウェア名 Becky! Al-Mail akira32 電信八号 Gold EUDORA Internet Netscape PRO Mail Mail WeMail Winbiff 着信メールの自動振り分け機能 ○ ○ ○ ○*2 ○ × × ○ ○ 着信メールフォルダの作成 ○ ○ ○ ○ ○ ○ ○ ○ ○ メールフォルダの階層化 ○ × ○ × ○ ○ × ○ ○ 検索機能 ○ ○ ○ ○ ○ ○ ○ ○ ○ ソート機能 ○ ○ ○ ○ ○ ○ ○ ○ ○ 送信/着信メールのツリー(スレ ○ × ○ ○ × × ○ × ○ ○ △*1 ○ △*3 × × × × × ッド)表示 他のメーラーからのメールの取り 込み *1 設定が必要 *2 FOLDERS.DEF ファイルを編集して指定 *3 ヘルパーアプリケーションによって可能 2.1.3.4 その他の機能 表 5 では、上記にもれた様々な機能の一覧・比較を行う。これらの機能はほとんどが付加的な 機能で、メーラの使い勝手の部分に関係する機能である。これらは、各メーラがそれぞれに特徴 やメーラのあり方などを考えた上でのものである。そのため、漢字コードへの対応状況とごみ箱 16 WWW に基づいたインターネットメールシステムの構築 の処理、オフラインでメールを書くこと以外では、それぞれがそれぞれ全く違う対応状況を見せ ている。 表 5 その他の機能 ソフトウェア名 Becky! Al-Mail akira32 電信八号 Gold EUDORA Internet Netscape PRO Mail Mail WeMail Winbiff 複数プロバイダに対応 ○ △*1 ○ ○ ○ × × × ○ 複数アカウントに対応 ○ × ○ ○ ○ × × × × 対応漢字コード JIS ○ ○ ○ ○ ○ ○ ○ ○ ○ シフトJIS ○ ○ ○ × ○ ○ ○ ○ ○ EUC ○ ○ ○ ○ ○ ○ ○ ○ ○ 自動改行機能 ○ × ○ △*3 ○ ○ × ○ × クリッカブル URL ○ ○ ○ △*3 ○ ○ ○ × ○ アドレス帳の階層化 × ○ ○ ○ × × ○ × × 複数ユーザーをグループとして登 ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ × △*3 ○ × ○ × ○ 録可能か? 着信メールからアドレス帳への自動 登録 ごみ箱の処理 終了時 ○ ○ ○ ○ ○ ○ × ○ × 任意 ○ ○ ○ ○ ○ ○ ○ ○ ○ オフラインでメール作成 ○ ○ ○ ○ ○ ○ ○ ○*2 ○ メールエディタの任意設定 ○ ○ × ○ × × × ○ ○ 送信と受信を単独で実行可能 ○ × ○ ○ ○ × ○ ○ × *1 設定が必要 *2 自動受信をしないで送信時「送信保留」を選択する *3 ヘルパーアプリケーションによって可能 2.1.3.5 まとめ これらの機能の表 1∼表 5 から言えることは、 • 表 3、4 のメールの送受信・保守の機能はメーラの標準的・共通的機能を示している • 表 5 のその他の機能は各メーラを特徴付ける機能を示している ということである。共通的機能は、本質的に必要な機能であり、その他の機能は各メーラをさ らに使いやすくするための工夫が見られる非常に重要な部分であるということである。この特徴 となる機能によってそのメーラがどのような利用の仕方を前提とした設計をしているかが分か る。 17 WWW に基づいたインターネットメールシステムの構築 複数プロバイダ・アカウントへの対応は、メールをユーザの端末側に集める機能である。プロ バイダの運営方針によっては、メールサーバ側での転送ができない場合も多いので、有効な機能 である。 自動改行機能は、入力された内容を送信時にある一定の文字数で自動改行を入れる機能であ る。受け取り側でメールに返事を書く際に、改行が入っていない長い段落等があると、引用符が 最初にしか付かずに読みにくい文章になってしまう。それを避けるために、メール送信者は、文 章が折り返さないところで改行を入れる配慮をするのだが、文章の推敲時には、改行位置が何度 も変わることがありわずらわしい。この機能があれば、入力者は文章の入力に専念できる。 クリッカブル URL は、URL と判断される文字列をメール中に発見した場合、クリックするこ とにより、Web ブラウザを立ち上げその URL へ案内する機能である。メール中で URL を連絡 し合うことは多々あり、そのたびにその内容をコピー、ペーストでブラウザに貼り付けるのは、 面倒である。この機能により、頻繁に起こりうる定型作業を短縮できる。 アドレス帳の階層化は、電子メールを日常的に利用するユーザには必要な機能である。電子メ ールでのコミュニケーションが増えてくると、アドレス帳の中もコミュニティ毎や組織毎等整理 する必要が出てくることがある。このアドレス帳の階層化ができないと、アドレス帳は収集がつ かなくなることが多い。 着信メールからアドレス帳への自動登録の機能は、場合によっては不必要なアドレスを登録し てしまう可能性がある。しかし、ひとつひとつのアドレスを手作業で登録するよりは、自動登録 をした後に、不必要なアドレスだけ削除するほうがずっと効率がよい。 メールエディタの指定機能は、コンピュータの利用になれたユーザにはありがたい機能であ る。多くの場合、メーラでの文章入力機能は貧弱で、文章の編集等には向いていない。慣れてい るエディタを入力用に利用できば便利である。ただし、この機能はコンピュータに不慣れなユー ザにとっては理解が難しいため、この機能を実装するメーラはある程度上級ユーザを対象として いるといえる。 以上のように、各メーラはメーラ毎に独自の使い勝手向上のための機能を提供している。使い 勝手の機能の他にも、セキュリティ上の機能(メッセージの暗号化や、電子署名)や、対応してい る受信方式(POP3、IMAP、ローカルメールスプール 等)も利用者にとって重要な機能といえる。 2.2 メールシステム管理の現状: 管理者の視点 管理者の視点からの解析の対象は、ユーザ管理および、システム運用になる。ユーザ管理では、 ユーザアカウントの運用からユーザサポートまでを考察する。システム運用では、メールサーバ の設定、メンテナンスを考察する。前半では、問題点の所在を解析し、後半では、経験に基づき、 UNIX でのメールアカウントの運用を対象として解析する。対象プラットフォームを限定するの は、実際問題としてインターネットメールシステムの運用は UNIX 上か、Windows NT 上で行 われていることがほとんどであり、その中でも UNIX 上での管理と、Windows NT 上での管理 双方に本質的な違いは無いからである。 18 WWW に基づいたインターネットメールシステムの構築 2.2.1 問題点の所在 管理側の問題点は、管理者不足、管理コストの増大等があげられる。すでに一章で述べた通り、 現在インターネット利用ユーザ数は急速に増加している。また、インターネットの利用を組織単 位で導入するケースも急速に増加している。今までは、インターネットを利用する組織はある程 度、インターネットを研究対象にしていたり、業務の対象にしているケースが多かったため、専 門の部署がある場合も多く、様々な知識や、技術の蓄積があった。 現在では、いままでインターネットとはまったく関係がなかった組織でも、専用線に接続をし、 自サーバを立ち上げるケースも珍しくない。この場合、今までは管理者でなかったものが即席の 管理者を任されて、信頼度の低い運用環境になってしまったり、新たに管理者を採用することに よって、今までに無かったコストが生じたりする。すでに導入している組織でも、利用人数の増 加や、ユーザの入れ替わり等のため今まで以上に管理コストが増加している。 ユーザ管理、システム運用業務では、以下のような業務が日常的に発生し、様々な問題が生じ る可能性がある。 1) ユーザアカウントの運用 2) ユーザサポート 3) メールサーバの設定 4) メンテナンス 「ユーザアカウントの運用」に関しては、アカウントの作成、アカウントの存続性、妥当性の チェック(パスワードを定期的に変えているか、そのユーザは存在しているか、利用規約を守っ ているか)、アカウント情報の変更、アカウントの削除等が発生する。小さな組織での運用では、 さほどの作業量ではない。組織の規模が大きくなると、セキュリティ上の問題等を考慮する必要 があり、ユーザの把握すら大変な作業になる。 「ユーザサポート」に関しては、前述の通り、以前は利用者全員が自己の知識で利用ができた ので、作業としてあげるほどのものではなかった。近年では、初心者の急激な増加のため、サポ ート業務は非常に大きな労力を必要とする。多くの場合サポート内容は同じになる傾向があるの で、マニュアルの作成や、FAQ の作成で作業量は減らせそうである。しかし、メーラの問題点 のところで扱った通り、ユーザの利用する環境によってサポート内容は少しずつ違ってくるた め、一本化されたマニュアルや、FAQ の作成が難しくなる。 また、ユーザが利用するプラットフォームは Windows 95/98/NT、Macintosh、UNIX 等様々 である。管理サイドでは、すべてのプラットフォームについて精通している必要が生じる。その ため、管理者の育成や、新規雇用でのコストが増大する。組織内部で使う場合のメーラのインス トールからバージョンアップのための再インストール等も各プラットフォームごとに生じる。 「メールサーバの設定」に関して。以前は、サーバの立ち上げ時に一度の設定で基本的にはよ かった。近年では、”スパムメール”と呼ばれる、外部のメールサーバを踏み台にして、大量のメ ールを送りつける悪質な悪戯が横行している。立ち上げ時に設定したままでは、セキュリティ上 19 WWW に基づいたインターネットメールシステムの構築 の問題点があり、対策を講じる必要性が生じている。内部ネットワークからのメール送信以外を させないようにすればいいのだが、 組織のメールサーバは外部からも利用する必要がある場合が 多い。そのため、問題のあるホストからのみ制限する形を取らざるを得ないので、その都度設定 を変更しなければならない。 「メンテナンス」に関して。ユーザアカウントを管理・維持する業務では、ディスクスペース の問題がある。ユーザによってはメールスプールに大量のメールを溜め込み、ディスクスペース を圧迫する場合がある。ユーザのホーム領域を確保しないメール専用サーバとして利用している 場合でも、メールスプールを常に監視し、問題のあるユーザに警告を送ったり、不要なメールの 削除するという業務が必要になる。多くのユーザを抱えている場合は、それだけ管理するユーザ 数が増えるため、大変な作業になる。 以上の業務の増加から発生する問題点をまとめると、以下のようになる。 • 管理者の学習・教育コストの増加 • ユーザサポートによる管理コストの増加 • セキュリティ対策による管理コストの増加 現状のシステムを使用する限り、これらのコストの増大は運用する組織側でコントロールする ことは難しい。 2.2.2 実際の経験から この項では、今までに携わったいくつかの管理業務の経験から、現状のシステム管理、特にメ ールアカウントの管理、がどのような問題を抱えているかを述べる。経験上のものなので、 UNIX(Solaris 2.x, SunOS 4.1.x)での管理を基本とする。 2.2.2.1 アカウント作成業務 アカウント作成の業務がシステム化されている組織では、作成の依頼は決まったフォーマット で行われる。管理者は、その申し込み用紙を見ながらアカウントを作成していくことになる。 作成の手順としては、1)ユーザアカウントの作成、2)ユーザホームディレクトリの作成、3)初 期設定ファイルのコピー、4)テスト、5)通知となる。システムの運用状況によっても違うのだが、 この業務において最低限度理解する必要のあるコマンドは、su, vipw/useradd/admintool, passwd/yppasswd, mkdir, chown, chmod, ls, cd, pwd, mkdir, rmdir, cp, mv, rm, more/less, vi/emacs/ed/ex1 1 などになる。各作成の手順でこれらのコマンドを適切に使いこなすためには、 ある程度の準備期間が必要となる。そのため、管理者不足の組織でにわかに管理者になった程度 では大変である。 11 /で区切ったコマンドは、代替的なコマンドで、システムの運営状況・使用者の好みにより選択するひつ ようがある。 20 WWW に基づいたインターネットメールシステムの構築 インターネットの利用に関してある程度の認識があり、アカウント作成に対して何らかのシス テム化された登録手続きが存在していれば、管理者は勉強期間を設ければ業務は成り立つ。しか し、アカウント作成の業務がシステム化されていない組織では、話はずっと込み入ったものとな る。 ユーザアカウントを作成するにあたっての必要事項として、1)アカウント名、2)パスワードが ある。こういった組織では、アカウント作成の申し出の時点では、申し込み者または指示をする 人は、パスワードの必要性を認識していないことが多い。経験的には、しつこく何度も言わない と認識してもらえない。また、アカウントで使える文字の種類や、アカウント・パスワードの文 字数の制限等も認識していない。これらの項目は、最終的に明文化するまでは認識されない。こ のため、管理者は、アカウント作成依頼を受けてから業務を終了するまでに、何度も依頼者とや り取りを行い確認をすることになる。作成依頼が重なった場合は、それだけでかなりの時間を浪 費してしまう。 2.2.2.2 ユーザサポート業務 メールアカウント運用におけるユーザサポート業務は、1)メーラ設定事項の指示、2)転送先の 設定がある。 メーラ設定事項の指示は、ユーザサポート業務中もっとも頻出する業務である。各々のユーザ は、自分がメーラの設定をはじめたときに管理者を呼んで設定を聞くことになる。2.1.2.3 にも 記述したが、メーラの基本設定項目として、SMTP サーバ、POP/IMAP サーバ、アカウント、 パスワード等がある。多くの場合、SMTP サーバや POP/IMAP サーバは同じホストであるが、 管理者は気を利かせて smtp.foo.ac.jp や pop.foo.ac.jp(または、mail.foo.ac.jp)等の別名をホスト に付けたりする。そして、それの設定用のサーバ名の一覧をイントラネットサイトに記載する。 しかし、実際にはユーザはそのページを見て自分でメーラの設定ができることは少ない。その理 由はすでに述べたが、メーラによって設定項目の名前が違っていたり、設定の仕方が違うからで ある。かくして、管理者は依頼のあったユーザのところまで行って、メーラの設定を行うことに なる。 ユーザが物理的に接触できるところにいればいいのだが、電話でのサポートはずっと厳しい状 況になる。各ユーザ毎にどのプラットフォーム(OS)を使っており、どのメーラを使っているか は分からない。管理者でもすべてのメーラを把握しているわけではないので、電話越しに手探り でユーザを支持するのだが、 使ったことも見たこともないソフトウエアの操作方法を教えるのは 容易ではない。また、ユーザが指示通りの正しい入力をしているかを確認することもできない。 このような状況では、熟達した管理者でさえサポートはままならない。にわか管理者では、サ ーバの仕組みの理解から初めて、様々なプラットフォーム独自の知識・ノウハウを蓄積しなくて はならないので、大変な業務になる。 次に、転送先の設定に関して。業務としては、ユーザディレクトリに転送設定ファイルを置く かまたは、システムファイルに転送設定を追加するだけである。前者は、ユーザホームディレク トリに”.forward”というファイルを作成し、後者は”/etc/aliases”というファイルを編集すること 21 WWW に基づいたインターネットメールシステムの構築 になる。利用するコマンドとしては、ユーザ作成時に利用したコマンドの範囲内なので、この二 つのファイルの仕組を理解することにより可能となる。 2.2.2.3 システムメンテナンス業務 システムメンテナンス業務としては、1)ディスク使用状況のチェック、2)セキュリティ上のチ ェック、3)ディスクのバックアップ等がある。これらの業務を行うためには、UNIX システムそ のものの深い理解が必要である。最低限新規に覚えるべきコマンドとしても、df, du, quot, quota, find, finger, last, grep, ps, netstat, tar, dump, … 他多数がある。それらのコマンドを活 用して、多くのシステムファイル、ログファイルの確認等を行うための理解が必要となる。もと もと管理者のいなかった組織では、ノウハウの蓄積が無いので、新管理者がこれらのスキルを独 学で学ぶ敷居は非常に高い。 これらの業務は直接ユーザ等からの依頼のある作業ではない。しかし、システム側にトラブル が起きた場合や、トラブルを防止することにおいて必ず必要となる業務である。 2.3 メールシステム発展に関する歴史的認識 本節では、第一章で述べてきた様々な問題に至る経緯を考察する。様々な問題が起きはじめて いるのは、インターネットメールシステムが、開発当時からいうと、様々に変化してきたことに 起因すると思われる。その変化は、インターネットメールシステムの利用のされ方が、様々に変 化してきたことに対して、適応するためにシステム自体の拡張、変更、新システムの開発が行わ れてきたために生じたといえる。 主な原因になっている変化として、メールが蓄積される場所(メールスプール)とメールが確認 される場所の変化があげられる。以下では、この変化に着目しインターネットメールシステムの 発展の流れを把握する。具体的なメーラの紹介は各段階で利用されていた(いる)代表的なメーラ である。 2.3.1 メールは UNIX 上で もともとインターネットメールは、UNIX 上でのみ利用されるものであった。メールを読む場 合は、メールが届いている UNIX ホストにログインし、直接蓄積されたメールを読んでいた。 したがって、メール自体は、UNIX ホスト上に常に残ることになる。概念的なイメージは、以下 図 3 のようになる。 メールの管理者、ユーザともにメールは、UNIX 上で確認し、管理者はホスト上のスプールを 管理していればよかった。 22 WWW に基づいたインターネットメールシステムの構築 メールスプール UNIXホスト 図 3 メールサーバイメージ 1 2.3.1.1 この段階での具体的なメーラ • ucb mail ucb mail は、UNIX システム上でメールシステム初期に利用されたメーラである。 ユーザインタフェイスとしてコマンド入力の対話形式の CUI1 2 を採用し、目的のメール に対して、読込み、削除の機能のみをサポートする。また、受信と送信は、起動時のオプ ションによって別々のインタフェイスが呼び出される。 受信方式は、UNIX システム上に蓄積されているメールスプールを直接読み編集するタ イプで、ローカルマシン以外のスプールを読むことはできない。 • Emacs rmail Emacs rmail は、UNIX 上のエディタである Emacs の拡張機能として呼び出すことの できるメーラである。 ユーザインタフェイスとしては、CUI で、キーコンビネーション(ショートカットキー) により一連の機能を実現し、熟達した利用者には便利になっている。また、コマンド入力 の対話形式での利用も可能である。Emacs の拡張機能として利用するため、受信メール への返信メールの作成の機能を同一プログラム中に内包している。送信メールの作成も同 様に Emacs 上で実現しているが、rmail とは別に mail コマンドとして呼び出さなくては ならない。 受信方式は、もともと UNIX システム上のメールスプールを直接読むタイプであった が、後のバージョンアップで POP に対応し、現在 IMAP への対応を進めている。 2.3.2 POP の利用 次第に、PC や Macintosh 等のユーザ用の端末でインターネットの利用が可能になった。作業 端末が UNIX から PC に移行するにしたがって、ユーザは telnet によって UNIX ホストにログ インしてメールを読むのではなく、 メールそのものを自分の端末に置きたいという要望が出てき た。POP は、メールスプールのあるサーバからメール単位でメールデータを受け取る仕組みで ある。 12 Character User Interface の略。文字を使ったユーザインタフェイス。 23 WWW に基づいたインターネットメールシステムの構築 ユーザは、POP の利用により、メールを自分の端末に読み出し、自分の端末上に置くように なった。また、管理者は依然として UNIX 上でメールを読んでいる場合もあった。概念イメー ジは以下図 4 のようになる。 メールスプール POP 3 UNIXホスト ユーザ毎の メール ユーザ端末 図 4 メールサーバイメージ 2 2.3.2.1 この段階での具体的なメーラ • Eudora 等 Eudora に代表されるメーラは、GUI ベースの OS 上で利用されるメーラである。 これらのメーラは、ユーザインタフェイスとして、GUI を採用している。各メーラに よって多少の差異はあるが、各メールのヘッダの一覧を見せるウィンドウから、目的のメ ールを選び別ウィンドウで表示する。送信メールの作成や、返信メールの作成も同一のイ ンタフェイス上で実現されており、すべての機能が同一アプリケーション上で実現されて いる。 インタフェイスで、以前の CUI ベースのメーラから大きく改善された点として、メー ルボックスの分割・階層化がある。前述までのメーラでは、単一のメールボックスを対象 としていたが、これらのメーラでは、ユーザが自分の用途に合わせてメールボックスを分 割整理することができる。受信メールを自動的にフィルタリングし、該当メールボックス に保存する機能は、この整理機能をさらに拡張したものである。 もうひとつの大きな特徴としては、メールの受信方式に POP を採用している点である。 メーラが GUI ベースの OS 上で利用されることからも分かるように、ローカルマシンは、 直接メールが届くマシンではない。自分のメールスプールのあるマシンに POP を利用し て接続し、該当メールをダウンロードする。そのため、最終的にユーザのメールは、利用 しているユーザの端末に蓄積される。 また、スプールのあるマシン上で作業をする必要がないため、メールをオフラインで書 いて、送信時にオンラインにすることが可能である。 • mh-mew mh-mew は、rmail と同じく、Emacs の拡張機能として呼び出すことのできるメーラ である。 24 WWW に基づいたインターネットメールシステムの構築 このメーラは、基本的には、UNIX 上で利用するメーラである。Eudora 等の GUI ベー スのメーラの出現により、CUI ベースのメーラもインタフェイスの改善が行われた。 mh-mew では、Eudora 等のメーラと同様に、メールヘッダの一覧と、内容の表示を別々 のウィンドウ(正確には、フレーム)に表示する方式を採用したり、メールボックスの分 割・階層化、メールのフィルタリング等を実現している。また、送信、返信も同一アプリ ケーション内で実現している。コマンドの発行は rmail と同様にキーコンビネーションに より実現している。 一方で、受信方式は、スプールを直接読む方法と、POP を利用して受信する方法を選 択することができる。 2.3.3 IMAP の利用 次の段階では、ユーザ、管理者ともに利用端末としては、PC、Macintosh 等を用いるように なってきた。また、各メールシステム利用者は、単一の端末からのアクセスだけでなく、複数の 端末からアクセスする可能性も出てきた。 利用者は、基本的にメールを端末上で読みたいのだが、メールそのものは、どこから読んでも 同じように同期していることを望むようになってきた。この要求に対して POP を利用して、受 信メールをサーバから削除せずに、 メールのコピーをサーバ上にも、端末上にもおく方法がある。 しかし、蓄積するメール量が増えると、この方法では、現実的なパフォーマンスが得られなくな った。 そこで、利用され始めたのが、IMAP である。IMAP では、 • メール本体はサーバ側にある。 • メールを読むのは、端末側である。 • サーバ側に、端末側からフォルダ等を作成することもできる。 • メールの検索はプロトコル側で実装している 等の利点から、上記のような、新たな要求に答えることができるようになった。この概念イメ ージは以下図 5 のようになる。 メールスプール IMA P4 UNIXホスト ユーザ毎の メール (実際には、サー バ上にある) ユーザ端末 図 5 メールサーバイメージ 3 25 WWW に基づいたインターネットメールシステムの構築 このモデルでは、利用者は自分の端末上にメールを置いていない。IMAP クライアントでは、 基本的には、メールはすべてサーバ上にある。メーラの機能により、オフラインでメールを読む ために、サーバからの情報をキャッシュすることもできる。これによって、利用者はメールのデ ータ管理をサーバの管理者に任せることができるようになる。 2.3.3.1 この段階での具体的なメーラ • Outlook Express 等 Outlook Express に代表されるメーラは、GUI ベースの OS 上で利用されるメーラであ る。 これらのメーラは、インタフェイスとしては、Eudora タイプのメーラとほぼ同じで、 目立った改善点はない。 一方、メールの受信方式として、POP 以外に新たに、IMAP を採用している。IMAP は、POP と違い、受信メールをサーバ上に残したままローカルマシンで、受信メールの 閲覧、送信、返信をする。このため、送信メールをオフラインで書くことができるだけで なく、クライアントとして利用するマシンが変わっても、自分のメール環境が影響を受け ない。 • im-mew, pine im-mew は、mh-mew が利用していた mh が im に変わったもので、同じく Emacs 上 で利用できる。pine は、UNIX 上で利用できる CUI ベースのメーラである。 ユーザインタフェイスの特徴は、いずれも mh-mew と大きくは変わっていない。 メールの受信方式として、CUI ベースのメーラも im-mew や、pine などは、POP、IMAP を採用し、ローカルマシン以外のマシン上に蓄積されたメールを読むことができるように なった。 2.3.4 WWW1 3 を利用 次の段階で、利用者は、メールの蓄積場所、メールサーバの存在場所等の認識はなくなる。前 段階では、すくなくとも利用者は利用する端末には、自分の権限でメーラをインストールしたり、 すくなくとも組織内で用意された環境下での利用が前提となっていた。 WWW の利用により、利用者はあらゆる場所(所属する組織の内外、国内外等)から、比較的制 限なしに、インターネットにアクセスすることができるようになった。インターネットカフェ等 でも、WWW の利用に関しては制限がない。その結果利用者の中には、WWW を介してメール を読みたいという要求を持つものが現れる。 このタイプの利用形態と、POP、IMAP 等の接続方式、メールの蓄積場所の問題とは基本的に 別の問題である。HTTP で接続された側のホストは、依然として POP または、IMAP を使って 実際のメールサーバと通信をしている。 13 RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1.を利用したサービス。HTTP のバージョンは、0.9、 1.0、1.1 となっている。 26 WWW に基づいたインターネットメールシステムの構築 WWW を使ったメールの送受信は、イントラネットサイトなどのように、いずれにしても管 理者側の負担がある場合での運用で利用価値がある。また、 自組織外からの利用、モバイル環境・ 海外等からの利用等など、自分の通常のメール利用環境が実現できないときなどの利用には非常 に便利である。 この概念イメージは以下図 6 のようになる。 メールスプール HTT P UNIXホスト Webブラウザ ユーザ端末 図 6 メールサーバイメージ 4 この段階は重要なのでこの後 2.4 で詳しく述べる。 2.3.5 各メーラの位置関係 具体的な例として述べたメーラ(Web メーラは概念のみ)の位置関係を、ユーザインタフェイス と受信方式によって示すと以下の図 7 のようになる。 図 7 からも分かるように、Web メーラは、受信方式に依存せず、ユーザインタフェイスもプ ラットフォーム間で共通のものが採用できるため、新しいメーラの形として着目する意味があ る。 27 WWW に基づいたインターネットメールシステムの構築 ユーザインタフェイスの進化 Webメーラ GUI Outlook Express等 Eudra等 im-mew, pine mh-mew CUI Emacs RMAIL ucb mail スプール直接 POP3 IMAP4 メール受信方式 図 7 各メーラの位置関係 2.4 WEB メーラの現状 WWW に基づくメールシステムの現状の調査として、管理側のシステムを評価することは難 しい。その理由は、ユーザ側の立場では見えないところにシステムがあるからである。したがっ て、仕組み、機能の比較等に関しては、現在利用可能な主な WEB メーラについてのみ行う。 2.4.1 インターネットサイトのサービスとしての WWW メール Web サイトの構築競争において、1998 年の中盤から「ポータルサイト」という言葉が聞かれ るようになった。これは、ブラウザを起動したときなどに、デフォルトサイトとして登録するサ イトのことである。今日、Web サイトは爆発的な増加をしつづけており、利用者は過剰な情報 を把握しきれない状態になっている。また、サイト構築側も、多くのサイトの中から自サイトを 利用してもらうためには、様々な付加的なサービスを提供する必要が生じてきた。この「ポータ ルサイト」はいわば、ユーザの囲い込みのための仕組みである。無限に広がっている WWW へ の入り口として利用してもらうことにより、固定ユーザを得ることができるのである。 「ポータルサイト」機能の一環として、WEB メーラサービスを提供するサイトは多い。メー ルアドレスを無料で提供し、そのサイト内にメールの送受信機能をつけることによって、ユーザ はそのサイトを「ポータルサイト」として利用する可能性が高いのである。 また、ISP(インターネットサービスプロバイダ)でも、自サイト内に WWW メールサービスを 提供しているところがある。この場合は、メールアドレスはそのプロバイダのもの限定で、会員 28 WWW に基づいたインターネットメールシステムの構築 のみが利用できるという形態をとり、新たな会員獲得のための手段として利用しているようであ る。 いずれにせよ、サービスとして提供する WWW メールはユーザ、会員、潜在的顧客等の獲得 の意味が大きいといえる。 2.4.2 イントラネットサイトで導入される WWW メール 一方、本論文が対象にしている利用目的は、イントラネットでの利用を主眼に置いている。イ ンターネットサイトでの導入は、管理コスト削減や、運用効率の向上等の目的よりは、顧客の獲 得の目的になり、少しずれがあると思われる。 イントラネットサイトでの導入事例は、現時点では未確認であるが、1998 年 8 月 20 日に、ぷ らっとホーム株式会社から「WallEdge メールサーバ」という興味深いパッケージが発売された。 WWW メールシステムを製品として販売するものである。今までは、CGI ベースのイントラネ ット Web アプリケーションは、規模もそれほど大きくなく、要求される機能が各組織に特化し ているため、組織内で開発されることが多かったと思われる。製品化されるに至ったということ は、ある程度の需要が見込まれたことを示している。 同社の Web ページによると1 4 、下表(表 6)のような機能が上げられている。 表 6「WallEdge メールサーバ」の機能概要 1. HTML メール対応 2. 日本語処理 (日本語で書かれたメールを正しく送受信できます。) 3. MIME 対応 4. cc:Mail の添付ファイル対応( cc:Mail から メールサーバーに送信された、添付ファイル 付きのメールも、正常に表示・展開できます。) 5. 「Apache-SSL」対応の認証証明書「ベリサイン・セキュア・サーバ ID」 (別途クーポン券 で購入可能)を利用することで追加機能として SSL 暗号化通信を実現します。 6. DeleGate1 5 対応(DeleGate と併用することで、非日本語表示環境における日本語メール表 示が可能です。海外に出張や旅行したときでも、日本のメールサーバーに届いた日本語のメール を読めるようになります。 ) この製品は、管理側の機能が WWW で利用できないことを除くと、本論文で設計するシステ ムと非常に近い概念を持っていることがわかる。 14 15 http://www.plathome.co.jp/hqsales/pr/980817.html 佐藤豊氏が開発した WWW(ポート 80)以外にも様々なサービスに対して proxy, cache 等を実現する proxy サーバ (http://wall.etl.go.jp/delegate/) 29 WWW に基づいたインターネットメールシステムの構築 2.4.3 WEB メーラの機能比較と本論文での開発との関係 本項では、現在サービスとして利用可能な主な WEB メーラの機能、制約等の比較を行う。今 日では、すでに様々なサイトが中心となるサービスとして、または、付随するサービスとして WWW 上でのメール送受信システムを構築している。比較に際しては、1)メールアドレスを新 たに取得できるもの、2)既存アドレスのメールを読むもの、3)メールの送信のみ可能なものに分 けて比較する(表 7-9)。 表 7 メールアドレスを新たに取得できるもの サービス名称 メールアドレス例 初期費用 年額料金 Web上からの送信 外部POPの受信 Mail Box容量 備 考 24H WWW Mail Service ***@24h.co.jp 無料 無料 ○ × ?MB Curio Mail ***@curio-city.com 無料 無料 ○ ○ 0.5MB JMAIL ***@jmail.co.jp (※) 無料 無料 ○ × ?MB (※)ドメイン選択可 RobotMail ***@***.dddd.ne.jp 無料 無料 ○ ○ 5MB 有料オプション(メ ール自動収集、メー ル自動転送、メール ボックス容量拡張) あり excite Mail ***@excite.co.jp 無料 無料 ○ ○ 3MB Free Mail goo ***@mail.goo.ne.jp 無料 無料 ○ ○ 3MB ProntoMail ***@prontomail.ne.jp 無料 無料 ○ ○ 3MB (http://kitty.udn.ne.jp/mail/mail_web1.html 1998/9/20 現在) 表 8 既存アドレスのメールを読むもの サービス名称 InfoMail メールアドレス例 なし 初期費用 年額料金 無料 無料 Web上からの送信 外部POPの受信 ○ ○ Mail Box容量 備 考 × 受信機能を利用す るには、オンライン登 録が必要 WebMailer なし 無料 無料 ○ ○ × Netscape Navigator3.0 以上ま たは、かMS Internet Explorer4.0のブラウ ザーが必要 Web-POPPER なし 無料 無料 △ ○ × メール一覧表示、メ ー ル 選 択 表 示、返 信も可能/△:返信 のみ可能 Web Based Mail Service なし 無料 無料 × ○ × メール一覧表示、特 定メール内容表示、 30 WWW に基づいたインターネットメールシステムの構築 特定メール削除も可 能 (http://kitty.udn.ne.jp/mail/mail_web1.html 1998/9/20 現在) 表 9 )メールの送信のみ可能なもの サービス名称 メールアドレス例 初期費用 年額料金 Web上からの送信 外部POPの受信 Mail Box容量 備 考 Umetaro's Mail Form なし 無料 無料 ○ × × 電子郵便送信所 なし 無料 無料 ○ × × 会員制(無料) (http://kitty.udn.ne.jp/mail/mail_web1.html 1998/9/20 現在) 以上のように、すでにいくつかの WEB メーラが出現している。これらは、ほとんどが無料の サービスであるが、RobotMail のように一部有料の追加サービスを行っているものもある。ど のサービスも基本的には、ユーザの囲い込みを行い、広告収入等で実現されているものである。 これに対して、イントラネットサイトのサービスとして、組織内でやり取りされるメールのセ キュリティを確保したり、組織の正式なサービスとして運用するためには、メーラレベル(利用 者側)だけではなく、システムレベル(運用者側)で導入しなければならない。 これらのソフトウエアは、国際標準となる JDK1.2 ベースで開発されているものではないの で、将来的に利用可能である保証がない。また、ソースコードも公開されていないるものではな いので、組織内の開発のために利用したり、学校・研究機関において研究を進める上での障壁が ある。 このように、国際標準をベースとして開発されているもので、利用ライセンスが公開されてい るものが無いので、本論文では、これらの組織内でのサービスとして運用する目的で使用する場 合に有用なように、論文として設計概念を示し、構築の手法を述べている。 31 WWW に基づいたインターネットメールシステムの構築 3 WWW を採用したメールシステムの概念設計 本章では、前章で述べてきた、現状のインターネットメールシステムの問題点を改善するシス テムとして、WWW を基本としたシステムを採用し、その設計方について述べる。WWW はイ ンターネットの普及に大きく貢献したアプリケーションであるため、新規インターネットユーザ でも親しみやすく、利用できるようになるまでの敷居も低いことが予想される。 本論文の構想段階では、WWW 上のメーラは数も限られており、利用率もそれほど高くなか った。しかし、この数ヶ月で状況は大きく変化し、多くのサイトで採用されるようになった。こ のことからも、WWW を基本としたメールシステムの構築は意味があることが裏付けられる。 第 1 節では、全体的な概念設計を示す。第 2 節では、本論文で提案するシステムの利点を述べ、 第 3 節では、現状で存在する WWW ベースのメールシステムについて考察する。 3.1 構築する体系の基本概念 本節では、本論文で構築するインターネットメールシステムの概念設計を示す。本システムで は、(1)ユーザ側(メールの送受信を行うため)のインタフェイス、(2)管理者側(ユーザ管理・運用 のため)のインタフェイスの双方を WWW 化したシステムの概念を構築する。実際に第三章以降 で設計するサーバ OS は UNIX であるが、概念設計上は、UNIX、Windows NT を問わない。 Windows NT サーバで IIS1 6 を Web サーバとして利用する場合は、CGI1 7 の部分を、ISAPI1 8 や、 ASP1 9 等サーバサイドで利用する CGI よりも効率のよい機能に置き換えて開発することが望ま しい。 WWW は本来 HTML2 0 でかかれたドキュメントを表示するための、クライアント/サーバシス テムであった。しかし、クライアント/サーバ双方の機能は、開発された当時から大きく発達し、 現在では、Web アプリケーションと呼ばれるレベルの WWW 上でのアプリケーションが比較的 16 17 18 19 20 Internet Information Server の略。Microsoft 社が提供している Windows NT 上で動作する Web サー バ。GUI での管理コンソールや、Web 上からの管理機能を提供する。 Common Gateway Interface の略。Web サーバがサーバ内の別アプリケーションの実行結果を Web ク ライアントに渡すための仕組み。 Internet Server Application Program Interface の略。IIS が提供する機能で、Web サーバが別アプリケ ーションの出力を Web クライアントに渡す点では同じだが、別アプリケーションは、サーバプロセス内 のスレッドとして起動されるため、CGI と比べて、パフォーマンスが高い。 Active Sever Page の略。ISAPI アプリケーションの一種。サーバ側で VBScript や、Jscript 等のスク リプトプログラムを実行する仕組み。 RFC 1866 Hypertext Markup Language - 2.0。RFC となっているのはバージョン 2.0 までであるが、 W3C(http://www.w3c.org) では、HTML 4.0 の規格を打ち出している。 32 WWW に基づいたインターネットメールシステムの構築 容易に開発可能なまでになっている。本論文では、現時点で利用可能な様々なクライアント側/ サーバ側の拡張された機能を利用する。 3.1.1 ユーザ側の概念設計 ここでは、メールシステムを利用するユーザにとっての設計と、それを実現するための基本原 則を述べる。 3.1.1.1 利用ユーザにとっての設計 このシステムは、すべて WWW 上での作業を前提としている。ユーザは Web ブラウザの起動 だけをすればよい。あとは、ブラウザの中でメーラと対話する。 メーラの設計の中心になる問題として、どのような機能を実装するかがある。2.1.3 で取り上 げた表の中から、本システムで実装するべき機能/そうでない機能を示す。取り上げた機能は、 「メールの送信/返信に関する機能」 、 「受信メールの保守に関する機能」、 「その他の機能」と分け た。各機能は以下のようになる。 メール送信/返信に関する機能 1. Cc 送信 2. Bcc 送信 3. 差出人へ返信 4. 全員へ返信 5. 転送 6. 複数メールの一括送信 7. 添付ファイルのエンコーディング方式 (Base64、BinHex、uuencode) 8. 署名の添付 9. 引用符のカスタマイズ 10. 引用文字のカスタマイズ 受信メール保守に関する機能 1. 着信メールの自動振り分け 2. 着信メールフォルダ作成 3. メールフォルダ階層化 4. 検索機能 5. ソート機能 6. メールフォルダのスレッド表示 7. 他のメーラからのメールの取り込み その他の機能 1. 複数プロバイダに対応 2. 複数アカウントに対応 3. 対応漢字コード (JIS、Shift-JIS、EUC) 33 WWW に基づいたインターネットメールシステムの構築 4. 自動改行機能 5. クリッカブル URL 6. アドレス帳の階層化 7. 複数ユーザのグループ化 8. アドレス帳の自動登録 9. ごみ箱の処理 (終了時、任意) 10. オフラインでメール作成 11. メールエディタの任意設定 12. 送信と受信を単独で実行 本システムで設計する概念は、複雑になったメーラの機能の中で不必要なものを排除し、シン プルでわかりやすいものを目標とする。以上の機能一覧から、本システムにおいて実装するべき と考える機能と、その必要/不要の理由は以下通りである。 1) メール送信/返信に関する機能: 1. Cc 送信、4. 全員へ返信 • メールの送信/返信では、Cc で複数に対して送れる機能と、全員への返信機能で十分だ と思われる。 • Bcc を排除したのは、もともと頻繁に使われる機能ではなく、初心者で用語にも慣れず に混乱する例が多いからである。 • 返信に関しては、差出人だけに限定して返信をすると、Cc 等が含まれずディフォルト の返信を全員を対象にしたほうが好ましいと判断したからである。 • 添付書類機能は、本論文の目的を超えて実際の利用上の問題となるので、今後の研究 にゆだねることとして省略した。 2) 受信メール保守に関する機能: 2. 着信メールフォルダの作成、3. メールフォルダの階層化 • フォルダ作成機能、階層化機能はメールの整理のために必要である。 • メールの自動振り分けを除外したのは、ディフォルトのフォルダを見れば一応のすべ てのメールに目を通せるからである。 • 検索、ソート、スレッド表示等の機能は、高度な使い方なので、除外した。 • 他のメーラの使用を前提としないので、取り込み機能は除外した。 3) その他の機能: 3. 対応漢字コード(JIS、Shift-JIS、EUC)、12. 送信と受信を単独で実行、アドレス帳 • 文字化けは極力起きないようにするために、漢字コードはすべて対応するものとする。 34 WWW に基づいたインターネットメールシステムの構築 • 送信・受信は、単独で実行できたほうがわかりやすいので、送信・受信の単独の実行 は必要である。 • アドレス帳は、機能一覧では単独の機能としては定義されていない。これは、現在利 用されている GUI ベースのメーラではアドレス帳は、当然の機能として実装されてい るからである。ここでは、アドレス帳の機能は必要だと考えたので、一覧とは別に挙 げておいた。 • その他の機能は、基本的に高度な使い方となり、複雑になるので、ほとんどの機能を 除外する。 非常にシンプルで機能が少ないように見えるが、初めて使うユーザを対象としたシステムでは この程度の機能で十分である。必要な設定項目等は、サーバ側から Web ブラウザが受け取り設 定をする。従って、初心者にとって分かりにくい専門用語を多く含む設定項目を無くすことがで きる。 3.1.1.2 上記設計を実現するための基本原則 システムとして機能するには、以下のような項目を基本とする。まず、利用のための手順とし ては、次のような流れとする。利用するユーザがすでに利用登録を済ませ、利用 ID の発行を受 けている場合は、メールの送受信のため、システムにログインする。未登録の場合は、登録画面 へとすすむ。 ソフトウエアの構築においては、以下の手順をとる。 (1) 基本部分は CGI を利用 ユーザが登録作業をしたり、ログイン作業をする部分は、CGI を利用する。ユーザ登録 データは、CGI を介して、RDBMS2 1 上に格納される。 (2) メーラ部分は Java アプレットを利用 ログイン後のメールの送受信機能は、Java アプレットを利用して実現する。ログイン 時に、Java アプレットに対して CGI がパラメータを与える形で、HTML を出力する。 それによって、ユーザは自分の設定で Java アプレットを初期化することができるように なる。 この結果、全体の大まかなフローは以下図 8 のようになる。 21 Relational Database Management System の略。リレーショナルデータベースの運用エンジン。 35 WWW に基づいたインターネットメールシステムの構築 初期画面 ユーザ登録完了し ている いいえ ユーザ登録 はい ID,パスワード入力 いいえ ID,パスワードは正 しいか はい ログイン メールの処理 ログアウト 図 8 ユーザ側フロー 3.1.2 管理側の概念設計 3.1.2.1 利用ユーザ(管理者)にとっての設計 管理者もメーラ利用ユーザと同様に、WWW 上の操作ですべての管理が行えるものとする。 WWW 上での操作の実現は、2.2.1 で述べた管理上の様々な問題点を解決する手段と考える。シ ステム管理側の場合でも、急速なインターネットの普及により管理のための知識や技術を持った 人材が不足している。WWW を利用したシステムでは、管理者も専門の知識なしに、ほとんど の管理業務ができる。 管理側として利用できる必要のある機能は、1)各ユーザの登録情報の変更、2)ユーザのメール 蓄積量の管理、3)ユーザの削除、4)システムパラメータの変更である。本システムでのユーザに 提供する機能を管理するものとしては、この 4 つで十分である。 3.1.2.2 システム製作者にとっての設計 管理側の機能は、すべて CGI により提供するものとする。管理側の機能としては、上記の 1) 各ユーザの登録情報の変更、2)ユーザのメール蓄積量の管理、3)ユーザの削除、4)システムパラ メータの変更とする。構築するサーバは、メールの送受信機能をユーザに提供することが主な目 的である。そのため、管理者の業務も上記の点に絞ることができる。 作業フローは以下図 9 のようになる。 36 WWW に基づいたインターネットメールシステムの構築 初期画面 ユーザ登録情報の変更 ユーザのメール蓄積量 の管理 ユーザの削除 システム パラメータの管理 図 9 管理者側のフロー 3.1.2.3 管理者のセキュリティ コンピュータシステムにとって、システムのセキュリティ設計は重要である。得に、インター ネットに接続するコンピュータは、全世界からアクセス可能であり、セキュリティの欠陥に対し ての危険性が高い。 しかし、現実の運用に際しては、システムが不特定多数からアタックされる可能性も高いが、 実際に外部からのアタックによりセキュリティが破られることは比較的少ない。逆に、システム 内部、特にシステム管理者の設計ミスや、操作ミスによるり問題が起きる可能性は大きい。 管理者は、システム・利用ユーザの規模が大きくなると 1 人で管理できる限界がある。本シス テムでは、管理者が複数人数で管理することを前提として、管理者の権限のレベルを 2 段階に 分け、低いレベルの管理者権限と、高いレベルの管理者権限を設定する。 低いレベルでは、管理者はユーザの管理情報や、システムの運用情報を見ることはできるが、 変更や削除はできないように設計する。高いレベルでは、管理者は、すべての情報の把握と変更 や削除ができるようにする。 このように、管理レベルを分けることによって、詳しい専門的な知識のないユーザが、最終権 限を持った管理者をサポートする形で管理に参加することができるようになる。また、専門知識 を持った管理者は、誰でもできるレベルの作業を低レベルの管理者に任せて、最終的な判断に専 念することができるようになる。 37 WWW に基づいたインターネットメールシステムの構築 3.2 WWW を基本としたメールシステムの期待する利点 本システム利用の利点は、ユーザ側、管理者側双方で得られる。この利点は、技術的な利点と 経済的な利点に分けることができる。これらを以下に順に記述する。これらの利点のほとんどが 2.1、2.2 での現状での問題点を改善する。本節では、この双方での利点を解析する。 3.2.1 プラットフォーム独立性 WWW 上にシステムを構築することの第一の利点には、 「プラットフォーム独立性」があげら れる。従来のインターネットメールシステムでは、ユーザ側、管理側ともに特定のプラットフォ ームに依存した利用環境を持たざるを得なかった。 例えば、あるユーザが Windows を利用している場合は、Windows 上のメーラを利用する以外 はメールシステムを利用することはできなかった。管理側でも、メールシステムが Solaris 上に あるとしたら、メンテナンス業務は、そのシステム上で行う意外には選択肢はなかった。 WWW 上からの利用を基本にしたシステムでは、Web ブラウザさえあればどの OS を利用し ているかは問題ではなくなる。 3.2.2 アクセスの普遍性 次の利点は、 「アクセスの普遍性」である。本システムでは利用者は常に Web ブラウザを介し て利用することになる。その場合、使用する場所、システム等を選ぶことなく自分のメールにあ くアクセスすることができる。 通常、メールを送受信するためには、メーラが必要である。そのため、自宅、会社または、そ の他の場所(旅行先)等からアクセスするときに、自分が利用しているメーラが入っているか、少 なくとも、メーラをインストールして利用できる場合でなければメールを送受信することはでき ない。UNIX に遠隔ログインしてメールの読み書きをする方法もあるが、telnet を利用できる環 境でなければ利用できない。また、telnet や、メーラにより直接メールを読もうとしても、その 組織内のファイアウォールにより、23(telnet)や、110(POP3)、143(IMAP)、25(SMTP)等のポ ートが閉じられていることも多い。そのような場合でも、WWW 上でのシステムは proxy サー バ経由でアクセスするため、外部のメールの送受信を行うことができる。 これらの事柄は、管理者側でも言えることである。 このように、本システムは、メールシステムへの普遍的なアクセスを提供する。 3.2.3 ユーザインタフェイスの統一 第 3 の利点は、 「ユーザインタフェイスの統一」である。前述の通り、現状のメーラは書くメ ーラ毎にさまざまな独自機能を持ったり、操作方法や、用語の統一がなされていない。これは、 メーラのバージョンアップ等にも影響をうけ日々変化している。この状況では、新規ユーザは利 用方法を把握できないし、どんどん変化していく内容を追いかけることすら難しい状態になる。 38 WWW に基づいたインターネットメールシステムの構築 WWW 上でインタフェイスを構築することにより、ユーザは日ごろ慣れ親しんだ Web ブラウ ザ上での操作ができ、戸惑いは少なくなる。また、Web ブラウザがバージョンアップしてもメ ーラのインタフェイス自体は変化しないので、バージョンアップでの問題も回避できる。 本システムで構築するメーラでは、多くのメーラのような高度な機能は実装しない。代わりに、 最低限度の利用環境を考慮し、シンプルでわかりやすい機能のみを実装する。 3.2.4 セキュリティ対策の容易さ 第 4 の利点は、 「セキュリティ対策の容易さ」である。WWW を基本としたシステムであるた め、SSL を通すことにより、すべての通信が暗号化されることになる。 通常は、各ユーザが自分で暗号化のための機能をメーラに導入する作業が発生する。メーラに よっては、暗号化機能を持たないものもある。この作業は、初心者にとっては、非常に複雑な作 業であり、導入後も利用の際はメール送受信の手順が倍増する。そのため、多くの場合が、導入 しても実際には利用しなくなる。 前提として SSL を利用した場合は、ユーザが意識する・しないは別にして、必ず暗号化され セキュアな通信が実現される。ユーザ側での操作は暗号化しない場合と全く同じ(ブラウザの設 定によっては一度だけ確認のダイアログが出る)である。 ただし、この暗号化は本文全体を暗号化するだけであって、電子署名の追加、解読等を行って くれるものではない。したがって、メールの差出人、内容等を保証するものではないことを注意 しておく必要がある。 3.2.5 プログラム・システムのライフサイクルの独立化 第 5 の利点は「プログラム・システムのライフサイクルの独立化」である。現在コンピュータ 技術、特に、インターネットに関連する技術はめまぐるしく変化している。OS レベルでも常に バージョンアップがされている状況である。通常のメールシステムの場合は、このシステムレベ ルでの変化に対して、対応を余儀なくされるケースも少なくない。 WWW 上にシステムを構築した場合には、プラットフォームに非依存になるため、メーラや、 システムのライフサイクルを設計者自身で設定することができるようになる。これにより、シス テム運用の追加コスト等が発生することを防ぐことができる。 3.2.6 システム運用の効率化 第 6 の利点は、 「システム運用の効率化」である。5 項までの技術的な利点が達成できれば、 表記のように経済的効果が得られる。それは、主にシステム運用で生じるコストを削減できるこ とを示している。 前項までの「プラットフォーム独立性」、 「ユーザインタフェイスの統一」や「アクセスの普遍 性」により、ユーザはシステム利用においてスムーズな利用が可能になる。そのため、従来のシ ステム運用生じていたサポートのためのコストを削減することができる。 「ユーザインタフェイスの統一」により、管理者の学習コストも削減される。また、 「プログラ ム・システムのライフサイクルの設定」が可能になることによって、システムの管理・運用の効 率化が促進される。 39 WWW に基づいたインターネットメールシステムの構築 4 システムの具体的な設計 本章では、詳細なシステム設計を示す。このシステムは大きく分けて、三つのシステムから成 る。「ユーザ登録から認証システム」、 「メーラ」そして、「ユーザ管理システム」である。第 1 節では、 「ユーザ登録から認証」のシステム設計、第 2 節では「メーラ」の設計、第 3 節では、 「ユーザ管理システム」の設計をそれぞれ示す。内容は、具体的なサーバ側でのセッティング、 各コンポーネントにおいて、各々の技術を利用する利点/問題点を挙げ、解析する。この章は、 主に、技術的な側面を考察することになる。 4.1 ユーザ登録から認証システムの設計 ユーザ登録から認証のプロセスは、すべてサーバ側のプロセスになる。従って、WWW との 連携をするためには、CGI を利用する必要がある。ユーザは初期画面から、1)新規ユーザ登録 か 2)ログイン認証を行うことになる。以下設計を示す。 4.1.1 ユーザ登録 ユーザ登録では、ユーザはブラウザ上から FORM2 2 を介して必要登録事項を入力する。 HTTPd2 3 は、ユーザ登録用の CGI を起動する。登録された内容は、CGI により処理される。ユ ーザの登録は、システムのユーザデータベース(UNIX でいうと/etc/passwd)に直接反映される。 ユーザの詳細情報は、DB のレコードとして保存される。その後、CGI は、登録したユーザのホ ームディレクトリ等を作成し、初期設定を完了する。 従来は、管理者が登録申請をされたユーザに関して、手作業でユーザ登録をし、各ユーザのホ ームディレクトリを作成したり、初期設定ファイルをコピーしたりする必要があった。このシス テムでは、ユーザの登録をシステム側で行うため、登録がリアルタイムで行われ、登録ミス等が 起きることもない。 プロセスのフローは以下図 10 のようになる。 22 23 HTML で、ユーザからの入力を受け付けるインタフェイスを作成する場合に利用するタグ。 Web サーバのこと。 40 WWW に基づいたインターネットメールシステムの構築 クライアント側 FORMに入力 サーバ側 入力データ 入力 データ システム ユーザデータベース CGI プロセス 結果表示 出力 HTML 出力HTML SQL DB HTTPd 図 10 ユーザ登録フロー 4.1.2 認証システム ユーザ登録の終わっているユーザは、メール送受信のためにログインをする。ログイン時のユ ーザ ID とパスワードは、HTTP の認証機構2 4 に渡される。今回は、認証機構にシステムのユー ザ DB を利用する。HTTPd は、システムのユーザ DB に対してユーザ ID とパスワードの確認 を行い、一致するかテストをする。一致した場合は、メール送受信のためのプロセスに進み、一 致しなかった場合は、ユーザ ID、パスワードの再入力を求められる。プロセスのフローは以下 図 11 のようになる。 クライアント側 サーバ側 ログインを選択 401 Unauthorized 認証の必要性 を認識 HTTPd ログインを選択 ユーザID パスワード ID パスワード システム ユーザDB HTTPd ログイン完了 認証失敗 はい 200 OK ユーザID, パスワード は一致して いるか いいえ 401 Unauthorized 図 11 ユーザ認証フロー 24 HTTP では、Authorization ヘッダを使ってクライアントの認証ができる。 41 WWW に基づいたインターネットメールシステムの構築 4.1.2.1 認証後の流れ ユーザ認証を完了したユーザは、ログイン後の作業が可能になる。ログイン後に可能になるの は、1)登録情報の変更、2)メールの送受信、3)ログアウトである。具体的なフローは以下図 12 のようになる。 ログイン完了 登録情報の変更 メールの送受信 ログアウト 図 12 ログイン後のフロー 4.1.3 RDBMS 利用の利点 ユーザ情報の管理に RDBMS 利用の利点は、二つある。 一つ目として、一般的にデータベースを利用する利点と同じで、パフォーマンスの維持である。 ユーザ情報などのようなデータを保持するために、テキストファイル (CSV 等)ベースの運用方 法を選択した場合、件数がある程度の規模になると、パフォーマンスは確実に低下する。その理 由は、テキスト中のデータから該当するデータをさがす度に、全文検索をしなければ成らないか らである。データベースを利用した場合は、件数の増加に対して、パフォーマンスの低下を押さ えることができる。 二つ目として、HTTP の認証機構は、標準認証機構として Basic という認証がある。この認証 の仕組みは、ユーザの ID とパスワードの組をテキストファイルとして保存しておき、認証時に その内容とユーザの入力をチェックするものである。この仕組みは、テキストファイルを使うた め、手軽に実現できる。しかし、今回のように、ユーザのその他の情報を含めて管理する場合は、 ユーザ情報のファイルと、認証用のファイルを別にしなくてはならない。別にする場合は、ユー ザ登録の時点で、別々のファイルに書き出すようにしなければ成らないので、プログラム上、メ ンテナンス上都合がよくない。 DB に保存しておいて、その中の特定のカラムをユーザ ID、パスワードとして利用する場合 は、Basic 認証機構ではなく、各 RDBMS 用に用意された認証機構を使わなければならない。 ユーザの情報と、認証情報を一元管理できる意味で、RDBMS の利用は利点がある。 4.2 メーラの設計: Java の利用 本節では、具体的にメールの送受信を可能にする部品の設計を示す。内容は順に、メーラが起 動、実行されるプロセスフローの設計、Java 利用の利点、問題点、JDK1.2 利用の利点、問題 点等を述べる。このメーラは Java アプレット(以下アプレット)で作られており、ユーザからの 要求時にサーバからダウンロードされて利用されることになる。 42 WWW に基づいたインターネットメールシステムの構築 4.2.1 詳細な設計 ログイン後の作業で、メールの送受信を選ぶと、本節で述べるメーラが起動されることになる。 メールの送受信を選択した時点で、CGI は DB 上から要求を出したユーザの情報を引き出す。 そして、ブラウザに対して送る際に、アプレットへの引数として各ユーザ情報、サーバ固有の情 報等を渡す。 ダウンロードされたアプレットはサーバと、SMTP および IMAP を使って通信をする。その 結果、メールの送受信が実現される。現在アプレットの制限により、アプレットが通信できるサ ーバは、アプレットがダウンロードされたサーバに限られている。現時点では、ユーザはアプレ ットが置かれているサーバにメールアカウントが作成され、そのサーバ上のメールを読むのが目 的である。今後、このアプレットがダウンロードされたサーバ以外のサーバと通信をするために は、proxy サーバを経由する必要がある。 メール送受信選択後の作業のフローは以下図 13 のようになる。 クライアント側 メールの送受信 を選択 サーバ側 ユーザID パスワード ユーザID パスワード CGI プロセス SQL 設定情報 出力HTML DB 出力HTML HTTPd Javaアプレット を要求 アプレット HTTPd アプレット 起動 sendmail (SMTPサーバ) imap4d (IMAP4サーバ) 図 13 メール送受信のフロー 4.2.2 メールの保存場所 標準的な UNIX システムを利用した場合、システムが受信したメールは、/var 以下に保存さ れる2 5 。/var はメールス以外にもさまざまなシステムファイルが保存される。そのため、/var 領 域が上限を超えた場合システム自身が正常に利用できなくなってしまう。 本論文のシステムでは、メール受信プロトコルとして IMAP を利用する。IMAP では、受信 したメールをサーバ側に保存する機能を持っている。受信直後のメールは IMAP とは無関係な ので、システムの標準的な場所(/var 以下)に保存される。ユーザがメーラを介してメールを保存 するフォルダを作成する際は、ユーザのホームディレクトリに作成され、 メールを保存する際は、 そこに保存される。ユーザは、一時的な受信場所としてシステム側のディレクトリを使い、受信 25 システムによって、/var/mail、/var/spool/mail 等さまざまである。 43 WWW に基づいたインターネットメールシステムの構築 後のメールの整理には、自分のホームディレクトリを利用する。このことにより、管理者は、/var が圧迫されシステム運用ができなくなる心配が少ない。 4.2.3 メールの保存形式 現在さまざまなメーラが存在するが、メールを受信し保存する際に各メーラはそのメールを、 様々さ形式で保存する。最も標準的な形式は、RFC 8222 6 で規定されている形式で、サーバのメ ールスプール上では通常のこの形式で保存されている。各メーラは、POP3 や、IMAP を使って スプールからメールを受信した後、各々で再利用しやすい形式に変換して保存する。 ソフトウエアによっては、各形式間の変換機能を備えている場合もある。双方向の変換機能を 提供している場合もあれば、一方向の変換機能だけの場合もある。ほとんどの形式が何らかの方 法で変換可能ではあるが、ユーザは専門知識を持っていないので一度受信したメールの形式を変 換できないことも多い。 メーラの設計においてこの形式の選択は、重要である。さまざまなメーラの形式に対応したメ ーラを作るのは非常に効率が悪く、随時新しい形式への対応を考慮しなくてはならなくなるの で、標準的な RFC 822 の形式が最も望ましい。この形式は、普通の ASCII テキスト2 7 なので、 テキストエディタ等で開き内容を確認することも容易であるし、サーバに転送すればそのままメ ールボックスとして利用できる。 幸い、本論文で採用した IMAP のメールの保存形式は標準的な形式のままなので、特に変換 機能を提供することなく利用可能である。 4.2.4 Java 利用の利点 WWW ベースとしたインターネットメールシステムを構築する場合、メール送受信機能を現 在の WWW ブラウザの上で実現するためには、その機能を、 1) CGI を利用して実現するか、 または、2) Java アプレットとして実現するかどちらかで実現する必要がある。最初に、この双 方の技術の利点/問題点を分析する。 CGI 利用では、連続した操作 (受信メールを次々に読んでいくなど) ごとにサーバに接続をす る。その際、 • CGI では、サーバ側でその都度プロセスが起動する。そのため、サーバに大きな負担 がかかる。同時に接続するユーザ数が多い場合、現実的な処理速度を実現することは、 難しくなる。 • CGI では、接続ごとにネットワークトラフィックが生じることになる。この接続は、 HTTP セッションとなるので、ネットワークトラフィックに関してプロトコルオーバ ーヘッドが非常に大きくなる。 26 27 RFC 822 Standard for The Format of ARPA Internet Text Messages 日本語メールの場合は、ヘッダ部分が MIME エンコーディングされていたり、本文が ISO-2022JP で 構成されているので、US-ASCII ではない。 44 WWW に基づいたインターネットメールシステムの構築 というような問題がある。一方 Java を利用した場合は、個々の操作に対する大部分の処理が クライアント側で行われるので、 • サーバ側では、メールの送受信に関して sendmail(SMTP)と、imapd(IMAP4)が起動 されるが、各クライアントに関して 1 プロセスとなりる。どちらも、実際の操作が行 われたときにのみ起動するので、サーバ側の負担は非常に小さくなる。 • ネットワークトラフィックに関しても、送受信操作の時のみ発生する。それ以外の処 理は、クライアント側で処理されるのでネットワークトラフィックは発生しない。 というような利点がある。 CGI 利用では、すべての操作が Web ブラウザ上(HTML レベル)で行われる。上記のとおり、 ほとんどすべての操作に関して、CGI プロセスをサーバ側で起動し、その結果をブラウザ上で 見ることになる。そのため、 • CGI 利用では、1 つ 1 つの動作ごとにユーザは待ち時間がある。これは、日常よく利 用されるメールクライアントとしては、ユーザにかなりの精神的負担をかけることに なる。 • Java を利用した場合は、クライアントサイドでの動作なのでユーザに負担をかけるよ うな待ち時間が動作ごとに生じることはない。 4.2.5 Java 利用の問題点 Java を利用した場合は、現在の Java の実行形態では、最初にアプレットのダウンロードから 作業が始まる。ダウンロードには、アプレットのサイズに応じた時間がかかる。そのため、以下 のような問題点が生じる可能性がある。 • Java 利用では、アプレットサイズによっては、1 回 1 回のダウンロードが負担になる ほどの時間がかかる。 • ダウンロード後は、JIT コンパイルの時間等があるので、これも Class ファイルのサイ ズによっては、ユーザに負担がかかるほどの時間を要する。 現時点では、 各 Class ファイルが 1k - 2k 程度だが、 mail.jar (JavaMail API) と、activation.jar (Java Beans Activation Framework) が数十 k あるので、最終的には 150k - 200k ほどの大き さになることが考えられる。これは、現在のネットワークインフラを考えた場合、快適に動作す る大きさではない。 今後、ネットワークインフラの整備と、JVM や、JRE の方での Class ファイルのキャッシン グ等(ファイルそのもののディスクへのキャッシュ、実行イメージのメモリへのキャッシュ) が 普通に利用できるようになることを考えると、大きな問題ではないと考えることもできます。 一方、CGI 利用の場合は、以下のようなことが考えられる。 45 WWW に基づいたインターネットメールシステムの構築 • CGI 利用では、すべての動作は、HTTP 上で行われ、アプリケーションはクライアン トに依存しないので、動作の開始までにかかる時間は、それほどではない。 • メールの送受信作業は、数通の最新メールを読み出して終わることが多いので、Java アプレットがダウンロード、コンパイルされている間にかかる時間内にはに終わって しまう。 4.2.6 JDK 1.2 利用の利点/問題点 このアプリケーションの開発は、JDK1.2 を前提としている。JDK 1.2 でメールクライアント を作る主な利点は、以下の通りある。 4.2.6.1 国際化への対応 これは、JDK 1.1 で取り入れられたものを強化するものである。JDK 1.2 では、国際化 対応の強化がなされている。主な内容は、 • Locale のサポート (日本語は、JAPAN, JAPANESE) • Resource のローカライズ • Calendar, TimeZone Class • 各フォーマットのローカライズ (日付け、数字等) • 各操作の Locale に即した動作 • Unicode とのコンバート (各ローカルエンコーディングへの対応) • AWT の Locale 対応 • Stream I/O (入出力に関してプラットフォーム用のエンコーディングにする) • Character Classification (常に文字を Unicode 2.0 としてアクセスできる) • Internationalization Font と、Unicode Font のサポート この国際化のおかげで、プログラミングに関して、日本語の扱い、Unicode の扱いを気 にしなくても、入出力されるデータはプラットフォームのディフォルト Locale に合わせ てくれる。例えば、日本語版の Windows を使っている場合は、S-JIS になる。フォント に関しても、いくつかの 2 バイトフォントを実行時環境に内包しているので、日本語の 表示も問題がない。 4.2.6.2 JFC (Java Foundation Classes) JDK 1.2 には、JFC として AWT を拡張し、以下のようなさまざまな機能を追加してい る。 • Abstract Window Toolkit for basic GUI programming. • Swing Components 46 WWW に基づいたインターネットメールシステムの構築 • 2D Advanced Graphics and Imaging. • Input Method Framework • Accessibility • Drag-and-Drop data transfer 今回の GUI の構築にあたっては、この中の Swing を利用している。Swing 利用の利点 は、各グラフィックコンポーネントがプラットフォームに依存していないことである。従 来の AWT の GUI 部品は各プラットフォームで用意されている部品を使っていたので、 プラットフォーム毎で見え方が違っていた。 Swing では、Look & Feel UI2 8 として、Metal、Motif、Windows、Macintosh という ようなさまざまな外観を持っている。各外観はプラットフォームから独立して Swing に より提供される。部品そのものでも、AWT にはない新しい部品が数多く追加された。追 加された主な機能は以下の通りである。 4.3 • Look & Feel の切り替え • メニュー、ボタン、ラベルの各細かい設定 • ツールチップ • コンボボックス、リストボックス • スライダ • ツリー表示 • 内部 フレーム • スクロールバーを持った部品 • 表示領域の分割 • 各種ボーダーの設定 • 表 表示機能 • テキスト, HTML の表示機能 管理システムの設計 本節では、ユーザ管理システムの設計の詳細を示す。ユーザ管理システムは、四つの管理モジ ュールからなる。それぞれ、 「ユーザ登録情報変更」 「メール蓄積量管理」 「ユーザの削除」 「アプ レットへのパラメータの管理」の機能を持っている。 28 User Interface の略 47 WWW に基づいたインターネットメールシステムの構築 管理システムは、ユーザ側のシステムとは違って、すべての機能が CGI を介して提供される。 その理由は、変更・管理される情報がすべてサーバ側にあるため、CGI の利用以外ではそれら の機能を実現できないからである。 4.3.1 ユーザ情報変更システムの設計 ユーザ情報変更システムは、管理者が各利用登録をしているユーザの情報を変更するために、 使用する。基本的にユーザ情報は各ユーザが自分で情報を変更できるようにできているが、管理 者権限ですべてのデータにアクセスできる必要があると考えたので、このシステムを設計した。 このシステムは、アルゴリズム的には、ユーザ側の登録情報の変更のそれと同じである。相違 点は、管理側では変更するユーザを指定してどのユーザの情報でも変更できる点である。 具体的なフローは以下図 14 のようになる。 クライアント側 ユーザの指定 サーバ側 ユーザ名 ユーザ名 CGI プロセス ユーザ情報 SQL CGI プロセス 出力HTML DB 出力HTML 出力HTML HTTPd ユーザ情報 の一覧 ユーザ情報 の変更 変更情報 変更情報 SQL 出力HTML DB 出力HTML HTTPd 変更完了 図 14 ユーザ情報変更フロー 4.3.2 メール蓄積量管理システムの設計 管理者は、ユーザのメール蓄積量をモニタリングできる必要がある。このシステムでは、ユー ザのメールの蓄積量(ディスク使用量)を計算して、管理者が規定する容量を越えて使用している ユーザに 1)警告を出したり、2)実際にファイルを削除することができる。 48 WWW に基づいたインターネットメールシステムの構築 具体的なフローは以下図 15 のようになる。 クライアント側 サーバ側 出力HTML CGI プロセス (ディスク 領域確認) 出力HTML HTTPd 蓄積量一覧 警告メール送信 ユーザIDの一覧 ID一覧 出力HTML メール削除 ユーザIDの一覧 CGI プロセス (メール送 信/メール 削除) HTTPd 結果出力 出力HTML 図 15 メール蓄積量管理フロー 4.3.3 ユーザ削除機能の設計 管理者は、ユーザの中で利用権限の不要になったり、不当な利用しているユーザ等を任意に指 定して削除することができる。このシステムでは、1)ユーザアカウントの削除、2)データベース レコードの削除、3)ユーザディレクトリ、ファイルの削除、4)メールの削除を実行する。 具体的なフローは以下図 16 のようになる。 クライアント側 ユーザの指定 サーバ側 ユーザ名 ユーザ名 出力HTML CGIプロセス (アカウント削除 DB削除 ディレクトリ削除 メール削除) 出力HTML HTTPd 結果出力 図 16 ユーザ削除フロー 49 SQL ユーザ情報 DB WWW に基づいたインターネットメールシステムの構築 4.3.4 システムパラメータの管理 このシステムは、すべての事項に関して固定パラメータでは成り立たないので、システムを設 計するためのパラメータの変更を指定できるようにする。パラメータの一覧および、プロセスの フローは、以下図 17 のようになる。 クライアント側 サーバ側 CGI プロセス 出力HTML 出力HTML HTTPd パラメータ一覧 パラメータ変更 変更情報 CGI プロセス 出力HTML 出力HTML HTTPd 結果出力 図 17 システムパラメータ管理フロー パラメータ一覧: • ユーザディスク使用量の上限 • ユーザアカウントの利用期限 • 管理者パスワード • メーラアプレットに与えるパラメータ • SMTP サーバ名 • IMAP サーバ名 • ドメイン これらのパラメータを変更することができる。 50 WWW に基づいたインターネットメールシステムの構築 5 システムの試作とその評価 本章では、本論文で述べるシステム概念の実現形態の一例として試作したの内容を説明する。 システムは、メーラ部分、ユーザ登録・認証、管理システムの 3 つの部分に分かれる。これら のシステムの試作を順に紹介していく。 その後に、3 章で構築した概念設計との比較・評価を行う。 メーラの試作では、現時点でのインタフェイス、機能概要、問題点を述べる。メーラには、3.1.1 で述べたように、ユーザが混乱しないような、最小限度の機能を想定している。WWW 上でメ ールの送受信をするユーザにとっては、これらの機能で基本は十分である。 ユーザ登録・認証、管理システムの試作では、各画面での機能概要と利用方法の説明をする。 試作用のサーバ OS は、 Sun Microsystems 社の Solaris 2.6 日本語 Sparc 版を採用した。HTTP サーバとしては、現在全世界で最もシェアのある、Apache2 9 のバージョン 1.3.3 を利用している。 5.1 ユーザ登録・認証システムの概要 ユーザ登録・認証システムは、4.1 で具体的に述べたように、CGI と RDBMS の連携により実 現している。CGI の開発言語としては、Perl3 0 と一部ラッパとして C 言語を利用している。 RDBMS としては、オーストラリアの Hughes Technologies 社3 1 の開発した「Mini SQL3 2 」を 利用している。 5.1.1 ユーザ登録機能・概要 ユーザがメールの送受信を行うためには、まず最初に利用登録をする必要がある。登録に必要 な項目は、システム的に必ず必要な項目および、運用上確認するべき最低限の情報として以下の ものを採用した。 29 30 31 32 • 希望ユーザ ID • 希望パスワード • 希望パスワード(確認用) もともと NCSA HTTPd のクローンとして発足したプロジェクトで、現在はこちらの方が一般的に利用 されるサーバとなっている。バージョン 1.3 からは、Windows NT 上でも利用できるようになっている。 プロジェクト URL は、http://www.apache.org/。 http://www.perl.com/ http://www.hughes.com.au/ Hughes Technologies 社の開発した RDBMS で、 学術利用等に対してライセンスフリーで配布している。 UNIX 上で利用できる、SQL を介して管理できるデータベースサーバである。 51 WWW に基づいたインターネットメールシステムの構築 • 漢字氏名 • ローマ字氏名 • 電話番号 • 郵便番号 • 住所 連絡先として、すでに持っているメールアドレスの入寮項目も考慮したが、このシステムで初 めて e-mail を利用するユーザが多いことを想定して省略した。最低限度の入力項目した設定し ていないため、各項目はすべて必須入力項目としている。 実際の登録画面は以下図 18 のようになる。 図 18 ユーザ登録画面 また、これらのデータを格納するデータベースのフィールドとしては、 UID INT NOT NULL, # システム側で設定する UID ID CHAR(8) NOT NULL, # ユーザ ID Password CHAR(8), # パスワード CPassword CHAR(24), # 暗号化されたパスワード Name CHAR(32) NOT NULL, # 漢字氏名 RName CHAR(32) NOT NULL, # ローマ字氏名 52 WWW に基づいたインターネットメールシステムの構築 Phone CHAR(14), # 電話番号 PostalCode CHAR(8), # 郵便番号 Address CHAR(256), # 住所 Remarks CHAR(256) # 備考 「備考」は、ユーザ側では設定できないが、管理画面からは設定できるように設計してある。 登録されたデータが、Mini SQL 側のデータベースに格納されたのち、CGI は実際のシステム アカウントの作成をし、パスワードを設定する。これによりユーザはサーバ上にアカウントを 持つことになり、メールの送受信の際も、一般的な運用と同じになる。 5.1.2 ユーザ認証、ログイン機能・概要 ユーザ認証には、Apache の外部モジュールである mod_auth_sys3 3 を利用して、システムのパ スワードデータベースをユーザ認証用のデータベースとして利用できるようにしている。システ ムアカウントを認証用に使えること自体は、データの一元管理ができるようになる反面、セキュ リティホールになる可能性があるので十分注意が必要である。 登録を済ませたユーザが認証を経てシステムにログインしたあとは、以下図 19 のような画面 になる。 図 19 ログイン画面 33 http://www.cybercell.net/~hsf/sources/mod_auth_sys/ 53 WWW に基づいたインターネットメールシステムの構築 メール送受信を選択すると、5.2 でのメーラの起動画面に移る。登録情報の変更を選択すると、 利用登録時の情報を修正することができる。ログアウトを選択すると、このメニューから抜けト ップページに戻る。 登録情報の変更画面は、以下の図 20 のようになる。 図 20 登録情報変更画面 ユーザ側の情報変更画面では、ログインしたユーザ ID が最初から指定されているので、ID の 変更や他人の情報の変更ができないようになっている。 5.2 メーラの概要 メーラは、4.2 で述べたとおり、Java アプレットで作成している。開発は、JDK1.2 ベースで 行っているので、現在ブラウザレベルでサポートしているのは Hot Java3 4 しかない。Netscape、 Internet Explorer 等でも表示ができるように、ブラウザで表示するときは Java プラグインを 利用する。 34 Sun Microsystems 社が開発している Web ブラウザ。 54 WWW に基づいたインターネットメールシステムの構築 5.2.1 ユーザインタフェイス・機能概要 第一章で述べたように、近年のメーラは機能が非常に豊富になった。しかし、不慣れなユーザ にとっては、メールの送受信に必要な機能と、そうでない機能の区別がつきにくく混乱を招くこ とが少なくない。このメーラではそのようなことが無いように、機能は必要な機能だけに絞って ユーザの混乱を招かないようにした。 5.2.1.1 起動画面 以下の図 21 は、このメーラの起動画面のスクリーンショットである。各数字に対応する機能 は、以下の通りである。 1. 新規メール作成用のウインドウを開く 2. 返信メール作成用のウインドウを開く 3. メールの削除 4. メールフォルダの作成 5. メールフォルダの削除 6. メールフォルダの名前変更 7. タイムアウトした接続を回復 8. アドレス帳用のウインドウを開く 9. メーラ終了 10. 11 で選択されているフォルダの中のメールの一覧 11. メールフォルダの一覧 12. 10 で選択されているメールの内容 なお、 • 起動直後は、接続先のサーバ上の INBOX(IMAP のディフォルトメールフォルダ)を表 示する。 55 WWW に基づいたインターネットメールシステムの構築 • 8 のメールフォルダの一覧(メールボックス)に表示されるのは、各ユーザのホームディ レ ク ト リ 以 下 の IMAP と い う フ ォ ル ダ (UNIX の 環 境 変 数 を 使 っ て 書 く と、”$HOME/IMAP”)の中身である。 図 21 Java メーラの起動画面 5.2.1.2 新規メール作成画面 新規メール作成用のウインドウは、メーラ起動画面で、1(新規メール)を押した場合に開くウ インドウである。こちらも機能は非常にシンプルである。 各数字の内容は、以下の通り。 1. メール送信 2. ウインドウを閉じる 56 WWW に基づいたインターネットメールシステムの構築 3. メールの宛先(To)入力フィールド 4. メールの同報先(Cc)入力フィールド 5. メールの表題(Subject)入力フィールド 6. メールの本文入力フィールド 以下の図 22 は、送信メールの作成画面である。 図 22 新規メールの作成画面 5.2.1.3 返信メール作成画面 返信メール作成用のウインドウは、起動画面で、2 を押したときに表示されるウインドウであ る。プログラム側では、新規メール作成用と同じプログラムを使っているので、機能等は全く同 じである。返信用に開いた場合は、 • 自動的に相手のアドレス(From)を返信用の宛先(To)に表示する • 表題(Subject)に「Re:」を付ける • 本文に引用符「>」を付ける 以下の図 23 は、返信メール作成ボタンを押したときの画面である。 57 WWW に基づいたインターネットメールシステムの構築 図 23 返信メールの作成画面 5.2.2 開発環境の現時点での問題点 現在 Java 言語の標準仕様自身が制定の途中であり、また、JDK1.2 というバージョンが将来 的に標準言語仕様となる予定である。JDK1.2 やその他の API 等も開発中のものなので、メー ラの開発には、各リリース版を利用している。リリース版は、まだ安定したバージョンではない ので、現時点ではまだ多くの問題がある。 5.2.2.1 JDK 1.2 の問題 1) JVM がアプリケーションエラーで終了する これは、まれに起こる。起動時に落ちる場合と、あるイベントを送った時に落ちる場合 とある。イベントを送ったときも新しい Class ファイルを読みこむことを考えると、同 じと考えることもできる。ある状況下という再現性はないが、NullPointerException を キャッチしたときに起きるように思われる。 Java では、Pointer は存在しないはずなので、対処が難しい。連続的におきることが多 く、作業が中断してしまうことがよくある。 2) Swing の画面描画のバグ [1] Swing を利用して、GUI コンポーネントを構築した場合、Windows のマウスポイ ンタの奇跡を表示した場合に限って、画面描画が乱れる。乱れるのは、マウスのポ インタのある位置なので、マウスのポインタの描画とのマスキング等がうまくでき 58 WWW に基づいたインターネットメールシステムの構築 ていないようである。あらゆるイベント毎に起こる。これは、再現性があり、必ず おかしくなる。 5.3 管理システム概要 管理システムは、ユーザの登録・認証システムと背中合わせになる裏側の部分である。扱うデ ータは同じで、アクセスの制限が違っている。利用する技術としては、CGI と RDBMS(Mini SQL)の連携である。開発言語としても、ユーザ側と同様に Perl を利用している。 5.3.1 管理メニュー機能一覧 管理者が利用できる機能は 4.3.1 で設計した通り以下のようになっている。管理者は以下の機 能から必要な機能を選んで、システムメンテナンス、ユーザ管理を行うことになる。 • ユーザ登録情報変更 • メール蓄積量の管理 • ユーザの削除 • システムパラメータの設定 各機能のための管理画面は以下図 24 のようになる。 図 24 管理機能一覧画面 59 WWW に基づいたインターネットメールシステムの構築 5.3.2 ユーザ情報管理機能・概要 ユーザ情報管理では、登録されている全ユーザの一覧を見ることができる。一覧には、以下の 情報が含まれており、全体として把握すべき情報を得ることができる。 • UID • ユーザ ID • 漢字氏名 • ローマ字氏名 • メール蓄積量 また、各ユーザのレコードには、 「登録情報の変更」と「ユーザの削除」ボタンがついており、 管理者側で登録されたデータの変更が必要になった場合や、そのユーザをその場で削除する必要 がある場合に利用する。 各情報の一覧は、「UID 順(登録順)」と「蓄積メール量の多い順」に並び替えることができる。 新規登録ユーザを探す場合は UID で並び替え、ユーザのメール蓄積量のチェックを行いたい場 合は、メール蓄積量で並び替える。 実際の画面は、以下の図 25 のようになる。 図 25 ユーザ情報一覧画面 60 WWW に基づいたインターネットメールシステムの構築 ユーザ情報変更用のボタンを押した後の変更画面は、以下の図 26 のようになる。ほとんどが、 ユーザ側の変更画面と同じだが、管理者側はユーザの情報に「備考」を追加することができる。 図 26 管理者側ユーザ情報変更画面 5.3.3 ユーザ削除画面 ユーザの削除は、ユーザ情報管理画面でもできるが、複数のユーザを削除するには手間がかか る。このユーザ削除画面は、削除するユーザがすでに決まっており、複数を指定したい場合に便 利である。 以下の図 27 はユーザ削除画面のものである。 61 WWW に基づいたインターネットメールシステムの構築 図 27 ユーザ削除画面 「完了」を押すと選択されているユーザが削除される。 5.3.4 メール蓄積量管理機能・概要 メール蓄積量管理画面では、5.3.5 のシステムパーラメータ設定で設定する「メール蓄積量上 限」を超えているユーザの一覧を、蓄積量順に出力することができる。管理者は、一覧にあるユ ーザに対して警告を発することができる。 メール蓄積量の一覧の画面は以下図 28 のようになる。 62 WWW に基づいたインターネットメールシステムの構築 図 28 メール蓄積量管理画面 5.3.5 システムパラメータ設定機能・概要 システムパラメータを Web 上から設定することによって、管理者はサーバにログインし様々 な設定ファイルを書きなおしたり、プログラム自身を書き直すことなく一元管理ができる。シス テムパラメータ設定では、以下のパラメータが設定できる。 • 作成するユーザの UID の下限・上限 • ユーザのホームディレクトリの設置場所 • ユーザのログインシェル • ユーザの所属するグループ • メール蓄積量の上限 • ユーザアカウントの利用期限 • SMTP サーバになるサーバ名 • IMAP サーバになるサーバ名 • メールアドレスにつくドメイン名 63 WWW に基づいたインターネットメールシステムの構築 例えば、ユーザのログインシェルを実際に存在しないシェルに設定(例えば「/dev/null」等)に することによって、ユーザのシェルの利用を制限したり、利用期限を設定することによって、作 成時に期限を過ぎたときの作業を減らすことができる。各パラメータを適切に設定すると、シス テムはその組織に適切な形で、ある程度の自動運転が可能になる。 パラメータの設定画面は以下図 29 のようになる。 図 29 システムパラメータ設定画面 メール蓄積量設定はバイトで設定するが、数式をそのまま使うことができるので、 「10 * 1024 * 1024」のように設定しておけば、 「10M」等の設定も容易である。 64 WWW に基づいたインターネットメールシステムの構築 5.4 試作評価 3 章では、WWW ベースのメールシステムの概念設計をし、4 章では、その具体的な設計をし た。それに対し、この 5 章では、具体的な設計の実現形態の一例として実際にシステムの試作 をした。本節では、その試作を 1) 3.2 で示した設計目標、2) 4.1-4.3 で示した具体設計と比較評 価する。それにより、1) 4 章で示した具体的な設計が 3 章の設計目標を満たしているか、2) 4 章で示した具体設計はどの程度実現可能か、をそれぞれ述べ、本論文の評価とする。 5.4.1 設計目標との比較・評価 / 理論上の評価 3.2 では、設計目標として以下の項目を挙げた。 1. プラットフォーム独立性 2. アクセスの普遍性 3. ユーザインタフェイスの統一 4. セキュリティ対策の容易さ 5. プログラム・システムのライフサイクルの設定 6. システム運用の効率化 これらの目標に対して試作したシステムをそれぞれ比較・評価する。 5.4.1.1 「プラットフォーム独立性」の評価 設計したシステムは、ユーザ登録・認証・管理部分を CGI/HTML ベースで、メーラ部分を Java アプレットベースで作成することとしている。 CGI/HTML 部分に関してはどの OS を利用した場合でも Web ブラウザを介してアクセスする ために依存関係はない。メーラ部分に関しては、JDK1.2+Java Plug-in を利用しているため、 現状で利用できるのは Windows プラットフォーム+Netscape または、Internet Explorer に限 定されてしまう。しかし、この問題は JDK1.2 および Java Plug-in が新しい規格であり現状で ブラウザ等への対応状況が遅れていることが原因であり、設計そのものの問題ではない。 以上のことから、プラットフォーム独立性を満たしているといえる。 5.4.1.2 「アクセスの普遍性」の評価 設計したシステムは、Web ブラウザを介してアクセスする以上は、インターネット上のどの ネットワークからアクセスしても全く同じようにアクセスすることができる。このことから、ア クセスの普遍性を満たしているといえる。 5.4.1.3 「ユーザインタフェイスの統一」の評価 設計したシステムは、インタフェイスを HTML と Java アプレットで実現している。ユーザ 側の機能はすべて単一のプログラムが生成し、プラットフォーム独自機能を使っていない。Web 65 WWW に基づいたインターネットメールシステムの構築 ブラウザ内での表示とアプレットのみの表現となるので、ユーザインタフェイスの統一を満たし ているといえる。 5.4.1.4 「セキュリティ対策の容易さ」の評価 本論文述べたセキュリティ対策は SSL の利用による通信内容の暗号化である。設計したシス テムでの通信プロトコルは、HTML/CGI 部分では HTTP、Java アプレット部分は IMAP とな る。そのため、SSL の適用可能範囲は HTML/CGI 部分に限定される。 Java アプレットとサーバの通信部分となるメールの送受信は暗号化されない。もともとネッ トワーク内を流れるメールの情報は暗号化されていないので、受信部分だけの暗号化は必要ない といえる。また、プライバシーの問題となるユーザ登録情報や、管理上のセキュリティホールと なる管理者ようの機能部分の通信は暗号化することができるため、利用上の問題はないといえ る。 以上のことから、イントラネット標準の共通基準と合致しているため、セキュリティ対策の容 易さを満たしているといえる。 5.4.1.5 「プログラム・システムのライフサイクルの設定」の評価 設計したシステムは、HTML/CGI+Java アプレットなので、OS のバージョンアップやブラウ ザのバージョンアップに対応してバージョンアップをする必要はない。このことから、プログラ ム・システムのライフサイクルの設定をプログラム製作者側で行えることが分かる。 5.4.1.6 「システム運用の効率化」の評価 設計目標では、システム運用上のコストの中で、 「管理者の学習コスト」と「システムの管理 コスト」を減少できるとした。 システム全体が Web ベースになったことで、管理者はサーバ毎の専門的な知識や技術を学ぶ 必要がなくなるため、学習コストを低く押さえることができる。 管理コストに関しても、Web 上で管理することによって管理が容易になるので、より短時間・ 小人数での管理が可能になる。また、管理者のレベルを 2 つに分けて設定しているため、専門 知識を持った管理者と事務処理に近いレベルの管理者に分けて管理させることができるために、 専門知識を持った管理者の人数が少なくてもシステム運用が可能になる。 以上のことから、システム運用の効率化を満たしているといえる。 5.4.2 具体設計との比較・評価 / 技術的評価 5.4.1 で概念設計での設計目標を具体的な設計が満たしていることは分かった。次にこの項で は、その具体的な設計が実際に実現可能であるか、また、どこに技術的な問題点があるかを、シ ステムの試作と具体設計を比較することにより評価する。 66 WWW に基づいたインターネットメールシステムの構築 5.4.2.1 ユーザ登録・認証システムの評価 ユーザ登録・認証システムは完全に設計どおりに試作が完了し、動作している。このことから、 具体的な設計が実現可能であるといえる。 5.4.2.2 メーラの評価 メーラ部分の試作において、基本的なメールの送受信、メールの削除、整理用のフォルダの作 成等の機能は問題無く動作している。メーラの設計としては実現可能であるといえる。 また、最終的に JDK1.2+Java Plug-in でのテストには成功していない。その理由は、いくつ かの問題に起因する。 1) 試作したメーラをアプレットにしてブラウザから Java Plug-in を介して呼び出した時点で Windows がアプリケーションエラーを起こしてしまい、その後、続行不能になってしまう。 それぞれ特性の違う数台のコンピュータで試したが、いずれも同じ結果であった。 2) アプレットの作成方法によっては、アプリケーションエラーは避けられたが、JDK1.2 から 導入されたセキュリティモデルが複雑で、どの部分にどのように適用して良いかが分かり にくく、最終的にメーラの起動までたどり着けない。 3) appletviewer もコードによっては、アプリケーションエラーを起こしてしまい続行不能に なる。 現状では、このような結果になってしまったが、JDK1.2 は 1998 年夏頃から利用可能な状態 であったが、まだ 1998 年 12 月にリリースされたばかりであり、Java Plug-in も実際の利用は まだ少ない。今後これらの問題が解決されはずである。 設計理念のひとつである「プラットフォーム独立性」および「プログラム・システムのライフ サイクルの独立化」を実現するためには、Java Plug-in との組み合わせによりアプレットを実 行できる環境を得る必要があるので設計上は間違っていないといえる。 次に、アドレス帳の機能はボタンとしては、存在しているが実装していない。概念設計の上で、 アドレス帳機能は現在の他のメーラの状況や使用上の便を考えると無くては成らない存在であ るとした。しかし、現実的には開発のための工数が非常に多く、論文のコンセプトを検証する上 では省略可能だと考えたため、実装しなかった。この部分は、今後の開発にゆだねることにする。 5.4.2.3 管理システムの評価 管理システムはユーザ登録・認証システムと同様の情報を同様の方法で扱うため、問題無く試作 が完了し、動作している。このことから、具体的な設計が実現可能であるといえる。 67 WWW に基づいたインターネットメールシステムの構築 6 まとめ 本論文で構築したソフトウエアの試作動作デモは、http://noa.sipeb.aoyama.ac.jp/webmailer/ で見ることができる。また、Java、perl、データベースのテーブル定義用の sql 文等のソフト ウエアソースコードは、http://noa.sipeb.aoyama.ac.jp/webmailer/src/ 以下に公開する(1999 年 1 月 12 日現在)。 6.1 結論 設計概念を示したシステムの試作プロセスを通じて、5.4 において、当初目標とした「プラッ トフォーム独立性」 、「アクセスの普遍性」、 「ユーザインタフェイスの統一」、「セキュリティ対 策の容易さ」 、 「プログラム・システムのライフサイクルの設定」および「システム運用の効率化」 が、WWW を基本としたメールシステムにより実現できることを示した。 6.2 今後の課題 今後への課題としては、システムとしての機能の充実・使い勝手の向上がある。これは、ユー ザ・管理者ともに使い勝手が向上する必要がある。 今回作成したメーラでは必要最小限度の機能は実現したが、現存のほとんどのメーラが実装し ている本文中の MIME への対応がなされていない。添付ファイルの送受信には必ず必要な機能 である。システムの部分では、メールの転送設定、外部 POP/IMAP サーバからのメールの取り 込み機能を実装することにより、システム自身の汎用性が高まる。 学部学生などの初心者への電子メール機能の供給にも有効と考えられるが、今後実際に試みる 機会があればそれを実現できる。 Acknowledgement 本論文の枠組の示唆は指導教員井田昌之教授による。 付録のソフトウエアソースコードの内、Java ソースコードに関しては、FolderMode.java、 FolderTreeNode.java を、Sun Microsystems Java 開発グループによる Java Mail API のデモ ソースコードを参考にした。それ以外の部分も全体としてこのデモを参考に作成し、その後改良 した。Window.java は、大村忠志著「Swing による Java GUI プログラミング」を参考にした。 68 WWW に基づいたインターネットメールシステムの構築 Perl ソースコードに関しては、lockfile.pl を友人である新見覚志氏の作成したものをそのまま利 用した。 5 章のシステムの試作は、すべて公文善之によるものである。 69 WWW に基づいたインターネットメールシステムの構築 参考文献・参考 WWW サイト 1. The Source For Java Technology (http://java.sun.com/) 2. The Swing Connection (http://java.sun.com/products/jfc/tsc/) 3. Java Developer Connection (http://developer.java.sun.com/) 4. 大村忠志 著, 「Swing による Java GUI プログラミング」, カットシステム, 1998 5. Clinton Wrong 著, 法林 浩之 監訳, 須田 隆久, 「Web クライアントプログラミング」, オ ライリー・ジャパン, 1997 6. Robert Englander 著, 鷹見 豊 訳, 「Java Beans 基礎から開発まで」, オライリー・ジャ パン, 1997 7. David Flanagan 著, 小俣 裕一 監訳, 豊福 剛 訳, 「Java プログラムクイックリファレン ス」, オライリー・ジャパン, 1998 8. Gary Cornell, Cay S.Horstmann 共著, 岩本 信一 訳, 「コア Java 2nd Edition」, アスキ ー, 1997 9. Aeleen Frisch 著, 谷川 哲司 監訳, 黒岩 真吾, 株式会社ユニテック 共訳, 「UNIX シス テム管理 改訂版」, オライリー・ジャパン, 1998 10. Stephen R. Davis 著, 松田 晃一 監訳, 桑田 雅彦, 地引 昌弘, 小野 剛 共訳, 「Visual J++セルフマスターブック」, アスキー, 1996 11. 大野 侚朗, 前田 英明, 井田 昌之, 松岡 聡, 中田 秀基 編, 「Java プログラミング例題 集」, 共立出版, 1997 70 WWW に基づいたインターネットメールシステムの構築 付録 プログラムソースコード [A] メーラ Java ソースコード Window.java 基本的な Swing を用いたフレームの作成を助けるためのクラス。機能は、すべてコンストラ クタ内部に持っていて、UI(ユーザインタフェイス)の設定、ウインドウタイトルバー文字列の指 定、クローズボックスを押したときのアプリケーション終了の是非の決定ができる。GUI 部品 の追加を簡略化するために、フレームの中にメニュー項目、ツールバー項目、ツールティップス 項目の追加のためのメソッドが用意されている。また、各項目に対して、イベントを受け取る側 のクラスを引数として渡すことができる。このクラスは継承して使うことを前提として作られて いる。 FolderModel.java 受信メールを表示をするときの、ヘッダ一覧を作成するためのクラス。このクラスは、Swing の テ ー ブ ル 表 示 を 行 う ク ラ ス で 、 AbstractTableModel ク ラ ス を 継 承 し て 作 成 さ れ る 。 AbstractTableModel は抽象クラスで、テーブルが外部に内容データを知らせたり、テーブルヘ ッダの文字列を知らせたりするためのメソッドをオーバーライドする必要がある。このクラスで は、メールヘッダのうち、From、Subject、Date を内容として扱うテーブルを作成する。 FolderTreeNode.java IMAP での通信結果、ユーザディレクトリが内包するフォルダ、ファイルの一覧を JTree に加 えるためのクラス。これは、DefaultMutableTreeNode を継承したもので、ツリー表示、ツリ ーのノードが持つデータを外部から扱うためのメソッドをオーバーライドする必要がある。この クラスでは、各ユーザディレクトリが内包するノードがディレクトリであった場合は、さらに StoreTreeNode を呼び出して内容の処理をする。 Header.java メールのヘッダを表示するためのクラス。ヘッダ部分は、JTable を用いて作られるが、JTable はテーブルの内容定義をするクラスをコンストラクタの引数として与えなければならない。この 内容定義が、上記の FolederModel である。このクラスでは、ヘッダ表示用のテーブルを作成し、 テーブルのセルが選択されたときのイベントの処理として Viewer クラスをよぶ処理と、IMAP 71 WWW に基づいたインターネットメールシステムの構築 のディレクトリツリーのノードが選択されたときの選択されたフォルダ/ファイルのセットをす る機能がある。 Mail.java メーラのメインになるクラス。Window を継承して作られている。コンストラクタでは、各ユ ーザ情報を受け取りメールの送受信を行う準備をする。その他のクラスの初期化等もすべてこの クラスで行われ、Connect クラスや Exit クラス等のいくつかのクラスはこのクラスの内部クラ スとして作られる。また、IMAP のユーザディレクトリツリーの内容を JTree にマッピングす る作業はこのクラスの中で行われる。そのため、JTree が受け取るイベントの処理等もこのクラ スの中に記述されている。 New.java 新規メール作成、返信メール作成、送信を行うためのクラス。BasicWindow2 を継承している。 To、Cc、Subject、Body を入力するために JTextField、JTextArea を内包する JPanel を作っ ている。メール送信用には、JavaMail API の MimeMessage クラスを利用している。 Viewer.java Header クラスにより選択されたメールの中身を表示するためのクラス。受け取った Message クラスの From、To、Cc、Subject、Body 等を各必要な場所に表示する。今のところ、text/plain 以外の Body は表示することができない。 WaitingFor.java Mail クラスや New クラスがネットワークにアクセスしている間にその旨を表示するスレッド を作成するクラス。表示は、Mail クラスの下部に位置するテキストフィールドにされる。 72 WWW に基づいたインターネットメールシステムの構築 Window.java /* * @(#) Window.java * * 作成者: 大村忠志(「SwingによるJava GUIプログラミング」より) * 修正者: 公文善之 1998年修士論文 * */ import javax.swing.*; import java.awt.*; import java.awt.event.*; /* * Swingを用いたフレームの作成を助けます。 * */ class Window extends JFrame { protected JMenuBar menuBar; protected Container pane; protected JToolBar toolBar; protected JMenu menu=null; public static void main(String[] args) { Window w = new Window("Basic Window", 0); w.setSize(500, 300); w.setVisible(true); } Window (String title, int ui, boolean exitOnClose) { this (title, ui); if (exitOnClose) { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); } } Window (String title, int ui) { super(title); setupUI(ui); menuBar = new JMenuBar(); setJMenuBar(menuBar); pane = getContentPane(); } toolBar = new JToolBar(); pane.add(toolBar, BorderLayout.NORTH); protected void setupUI(int ui) { try{ if (ui==0) { UIManager.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel"); } else if (ui==1) { UIManager.setLookAndFeel( "javax.swing.plaf.motif.MotifLookAndFeel"); } else if (ui==2) { UIManager.setLookAndFeel( "javax.swing.plaf.windows.WindowsLookAndFeel"); } else if (ui==3) { UIManager.setLookAndFeel( "javax.swing.plaf.mac.MacLookAndFeel"); } SwingUtilities.updateComponentTreeUI(this); } catch (UnsupportedLookAndFeelException e) { } catch (ClassNotFoundException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { } } protected JMenu addMenu( String text ) { menu = new JMenu( text ); menuBar.add( menu ); return( menu ); } protected JMenu addMenuOnToolBar( String text ) { menu = new JMenu( text ); if( toolBar==null ){ toolBar = new JToolBar(); } 73 WWW に基づいたインターネットメールシステムの構築 JMenuBar mb = new JMenuBar(); mb.add( menu ); toolBar.add( mb ); return( menu ); } protected JMenuItem addMenuItem( String text, ActionListener listener ){ return( addMenuItemInternal( text, null, listener ) ); } protected JMenuItem addMenuItem( String text, Icon icon, ActionListener listener ){ return( addMenuItemInternal( text, icon, listener ) ); } protected JMenuItem addMenuItem( String text, String iconFilePath, ActionListener listener ){ ImageIcon icon = new ImageIcon( iconFilePath ); return( addMenuItemInternal( text, icon, listener ) ); } protected JMenuItem addMenuItem( String text, String iconFilePath, String toolTip, ActionListener listener ){ ImageIcon icon=null; if( iconFilePath!=null ) icon = new ImageIcon( iconFilePath ); JMenuItem mi = addMenuItemInternal( text, icon, listener ); mi.setToolTipText( toolTip ); return( mi ); } private JMenuItem addMenuItemInternal( String text, Icon icon, ActionListener listener ){ if( menu==null ) return(null); JMenuItem item = new JMenuItem( text, icon ); menu.add( item ); item.addActionListener( listener ); return( item ); } protected void addMenuSeparator(){ menu.addSeparator(); } protected JButton addTool( String text, ActionListener listener ){ return( addToolInternal( text, null, listener ) ); } protected JButton addTool( String text, Icon icon, ActionListener listener ){ return( addToolInternal( text, icon, listener ) ); } protected JButton addTool( String text, String iconFilePath, ActionListener listener ){ ImageIcon icon = new ImageIcon( iconFilePath ); return( addToolInternal( text, icon, listener ) ); } protected JButton addTool( String text, String iconFilePath, String toolTip, ActionListener listener ){ ImageIcon icon=null; if( iconFilePath!=null ) icon = new ImageIcon( iconFilePath ); JButton bt = addToolInternal( text, icon, listener ); bt.setToolTipText( toolTip ); return( bt ); } private JButton addToolInternal( String text, Icon icon, ActionListener listener ){ if( toolBar==null ){ toolBar = new JToolBar(); pane.add( toolBar, BorderLayout.NORTH ); } JButton item = new JButton( text, icon ); toolBar.add( item ); item.addActionListener( listener ); return( item ); } } protected void addToolSeparator(){ toolBar.addSeparator(); } FolderModel.java /* * @(#) FolderModel.java * * 作成者: Christopher Cotton * Bill Shannon 74 WWW に基づいたインターネットメールシステムの構築 * (「http://java.sun.com/products/javamail/index.html」より) * 修正者: 公文善之 1998年修士論文 * */ import javax.mail.*; import java.util.Date; import javax.swing.table.AbstractTableModel; /* * メールヘッダ表示用に AbstraceTableModel を継承したものです。 * From, Subject Date を表示します。 */ class FolderModel extends AbstractTableModel { Folder folder; Message[] messages; String[] columnNames = {"From", "Subject", "Date"}; Class[] columnTypes = {String.class, String.class, String.class}; public void setFolder (Folder what) throws MessagingException { if (what != null) { // open folder if (!what.isOpen()) { what.open(Folder.READ_WRITE); } // get messages messages = what.getMessages(); cached = new String[messages.length][]; } else { messages = null; cached = null; } // close previous folder and switch to new folder if (what != null) { folder.close(true); } folder = what; } public Message getMessage(int which) { return messages[which]; } public String getColumnName (int column) { return columnNames[column]; } public Class getColumnClass (int column) { return columnTypes[column]; } public int getColumnCount () { return columnNames.length; } public int getRowCount () { if (messages == null) { return 0; } return messages.length; } public Object getValueAt (int aRow, int aColumn) { switch (aColumn) { case 0: case 1: case 2: String[] what = getCachedData (aRow); if (what != null) { return what[aColumn]; } else { return ""; } default: return ""; } } protected static String[][] cached; protected String[] getCachedData (int row) { if (cached[row] == null) { try { Message m = messages[row]; String[] theData = new String[4]; //From Address[] adds = m.getFrom (); 75 WWW に基づいたインターネットメールシステムの構築 if (adds != null && adds[0] != null) { theData[0] = adds[0].toString(); } else { theData[0] = ""; } //Subject String subject = m.getSubject (); if (subject != null) { theData[1] = subject; } else { theData[1] = "(No Subject)"; } //Date Date date = m.getSentDate (); if (date == null) { theData[2] = "Unknown"; } else { theData[2] = date.toString(); } cached[row] = theData; } catch (MessagingException e) { e.printStackTrace (); } } return cached[row]; } } FolderTreeNode.java /* * @(#) FolderTreeNode.java * * 作成者: Christopher Cotton * (「http://java.sun.com/products/javamail/index.html」より) * 修正者: 公文善之 1998年修士論文 * */ import import import import import javax.swing.*; javax.swing.tree.DefaultMutableTreeNode; javax.mail.Store; javax.mail.Folder; javax.mail.MessagingException; /* * IMAP のフォルダが内包するフォルダ、ファイルの一覧を JTree に加えます。 * */ public class FolderTreeNode extends DefaultMutableTreeNode { protected Folder folder = null; protected boolean hasLoaded = false; public FolderTreeNode (Folder what) { super(what); folder = what; } public boolean isLeaf () { try { if ((folder.getType() & Folder.HOLDS_FOLDERS) == 0) return true; } catch (MessagingException me) {} } return false; public Folder getFolder () { return folder; } public int getChildCount () { if (!hasLoaded) { loadChildren(); } return super.getChildCount(); } protected void loadChildren () { if (isLeaf()) { hasLoaded = true; return; } try { 76 WWW に基づいたインターネットメールシステムの構築 Folder[] sub = folder.list(); int num = sub.length; for (int i = 0; i < num; i++) { FolderTreeNode node = new FolderTreeNode(sub[i]); insert(node, i); } } catch (MessagingException me) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog(frame, me); } } public String toString () { return folder.getName(); } } Header.java /* * @(#) Header.java * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. */ import import import import import import import import javax.mail.*; javax.swing.*; javax.swing.event.*; javax.swing.table.*; javax.swing.tree.*; java.awt.*; java.awt.dnd.*; java.awt.event.*; /* * メールヘッダを表示するための表を作成します。 * */ public class Header extends JPanel { FolderModel model = new FolderModel(); JScrollPane scrollpane; JTable table; int minSelected; int maxSelected; Message draggingMsg; public Header () { this(null); } public Header (Folder what) { super(new GridLayout(1,1)); setPreferredSize(new Dimension(480, 150)); scrollpane = new JScrollPane(null); add(scrollpane); // set folder if (what != null) { setFolder(what); } } public void setFolder (Folder w hat) { JFrame frame = new JFrame(); model = new FolderModel(); WaitingFor wait = new WaitingFor(Mail.status, what.toString()); table = new JTable(model); table.setShowGrid(true); table.addEventListener(new dragMsg()); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.getSelectionModel().addListSelectionListener(new FolderPressed()); table.setModel(model); wait.start(); try { table.getSelectionModel().clearSelection(); if (Mail.mv != null) { Mail.mv.setMessage(null); } 77 WWW に基づいたインターネットメールシステムの構築 if (what != null) { model.setFolder(what); } scrollpane.invalidate(); scrollpane.validate(); } catch (MessagingException me) { JOptionPane.showMessageDialog(frame.getContentPane(), me); } catch (NullPointerException npe) { } scrollpane.setViewportView(table); updateUI(); wait.myStop(); } public void setSelectedRange (int Min, int Max) { minSelected = Min; maxSelected = Max; } public int[] getSelectedRange () { int[] Range = {minSelected, m axSelected}; return Range; } public int getMin () { return minSelected; } public int getMax () { return maxSelected; } public void deleteMessage (Message msg) { JFrame frame = new JFrame(); if (msg == null) { JOptionPane.showMessageDialog(frame.getContentPane(), "削除するメールが選択されていません。"); return; } try { Folder folder = msg.getFolder(); Message[] msgs = new Message[getMax() - getMin() + 2]; if (folder != null) { if (!folder.isOpen()) { folder.open(Folder.READ_WRITE); } // Set deleted messages msgs = folder.getMessages(getMin()+1, getMax()+1); // Set DELETED flag folder.setFlags(msgs, new Flags(Flags.Flag.DELETED), true); // Append copy of deleted messages, if it is not trash folder if (!folder.toString().equals(Mail.TRASH)) { Folder trash = Mail.store.getFolder(Mail.TRASH); if (!trash.isOpen()) { trash.open(Folder.READ_WRITE); } trash.appendMessages(msgs); trash.close(true); } folder.close(true); setFolder(folder); } else { JOptionPane.showMessageDialog(frame.getContentPane(), "フォルダが選択されていません。"); } } catch (MessagingException me) { JOptionPane.showMessageDialog(frame.getContentPane(), me); } catch (NullPointerException npe) { } catch (Exception e) { JOptionPane.showMessageDialog(frame.getContentPane(), e); } } // Table List Selection Listener class FolderPressed implements ListSelectionListener { public void valueChanged (ListSelectionEvent e) { if (model != null && !e.getValueIsAdjusting()) { ListSelectionModel lm = (ListSelectionModel) e.getSource(); int which = lm.getMaxSelectionIndex(); if (which != -1) { Message msg = model.getMessage(which); Mail.mv.setMessage(msg); Mail.header.setSelectedRange (lm.getMinSelectionIndex(), lm.getMaxSelectionIndex()); table.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } } } 78 WWW に基づいたインターネットメールシステムの構築 } } Mail.java /* * @(#) Mail.java * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. * */ import import import import import import import import import import import import java.util.*; java.io.*; javax.mail.*; javax.mail.internet.*; javax.activation.*; java.awt.*; java.awt.event.*; javax.swing.*; javax.swing.table.*; javax.swing.tree.*; javax.swing.event.*; javax.swing.border.*; /* * メールクライアントのメインです。 * 初期フレームの作成、メールの受信、その他のボタンのイベント処理等を行います。 */ public class Mail extends Window { // Get From Browser static String host = "noa.sipeb.aoyama.ac.jp"; static String user; static String password; static String SMTPhost = "kumon1.honya.co.jp"; static String useraddr = "[email protected]"; // System static static static static static static static static Statics String url; String protcol = "imap"; String RootNode = "Mail Boxes"; final final final final final String String String S tring String MAILERNAME = "Java Mailer"; IMAPFOLDER = "IMAP"; INBOX = "INBOX"; SENT = "SENT"; TRASH = "TRASH"; static final String TITLEIMG = "img/bluemountain.gif"; // Static static static static static static static static Objects Header header; Viewer mv; JTree mailtree; Folder folder; JTextField status; Store store; FolderTreeNode root; static Properties props; static Session session; // main public static void main (String argv[]) { // Create new frame Mail w = new Mail(MAILERNAME, 0); w.setSize(640, 480); w.setVisible(true); // Get inbox header.setFolder(folder); } // Constructor public Mail (String title, int ui) { super(title, ui, true); showTitle(); authUser(); addMouseListener(new MouseControl()); url = protcol + "://" + user + ":" + password + "@" + host; try { 79 WWW に基づいたインターネットメールシステムの構築 // Get a properties object props = new Properties(); props.put("mail.smtp.host", SMTPhost); // Get a session object session = Session.getDefaultInstance(props, null); // Get a store object store = null; URLName urln = new URLName(url); store = session.getStore(urln); // Get default folder & Check if system folders exist store.connect(); folder = store.getFolder(INBOX); Folder trash = store.getFolder(TRASH); if (!trash.exists()) { trash.create(Folder.HOLDS_MESSAGES); } Folder sent = store.getFolder(SENT); if (!sent.exists()) { sent.create(Folder.HOLDS_MESSAGES); } // Create Folder Tree DefaultMutableTreeNode root = new DefaultMutableTreeNode(RootNode); FolderTreeNode inbox = new FolderTreeNode(folder); Folder imapFolder = store.getFolder(IMAPFOLDER); FolderTreeNode imap = new FolderTreeNode(imapFolder); FolderTreeNode sentNode = new FolderTreeNode(sent); FolderTreeNode trashNode = new FolderTreeNode(trash); root.add(inbox); root.add(sentNode); root.add(trashNode); root.add(imap); DefaultTreeModel treeModel = new DefaultTreeModel(root); mailtree = new JTree(treeModel); mailtree.addTreeSelectionListener(new TreePress()); mailtree.setCellRenderer (new TreeIcons()); mailtree.setRootVisible(false); JScrollPane mtsp = new JScrollPane(mailtree); mtsp.setPreferredSize(new Dimension(160, 480)); // Add GUI components header = new Header(); mv = new Viewer(); JScrollPane mvsp = new JScrollPane(mv); mvsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); JSplitPane jsp1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, header, mvsp); JSplitPane jsp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mtsp, jsp1); jsp1.setDividerSize(2); jsp2.setDividerSize(2); pane.add(jsp2); JButton JButton JButton JButton JButton JButton JButton JButton JButton newbutton = addTool("", "img/new.gif", "新規作成", new New(useraddr)); reply = addTool("", "img/reply.gif", "返信", new New(useraddr, mv)); delete = addTool("", "img/delete.gif", "削除", new Delete()); createf = addTool("", "img/make.gif", " フォルダ作成", new CreateF()); deletef = addTool("", "img/remove.gif", "フォルダ削除", new DeleteF()); renamef = addTool("", "img/rename.gif", "フォルダ名変更", new RenameF()); connect = addTool("", "img/connect.gif", " 再接続", new Connect()); address = addTool("", "img/address.gif", " アドレス帳", new Address()); exit = addTool("", "img/exit.gif", "終了", new Exit()); status = new JTextField(); status.setEditable(false); status.setBackground(new Color(200, 200, 200)); pane.add(status, BorderLayout.SOUTH); } } catch (NullPointerException npe) { } catch (Exception ex) { JOptionPane.showMessageDialog(pane, ex.toString()); ex.printStackTrace(); System.exit(1); } // Start Title protected void showTitle () { JFrame frame = new JFrame(); ImageIcon icon = new ImageIcon(TITLEIMG); JButton button = new JButton(icon); ActionListener closeListener = new Close(frame); button.addActionListener(closeListener); 80 WWW に基づいたインターネットメールシステムの構築 frame.getContentPane().add(button); frame.setSize(244, 330); frame.setVisible(true); } // Check UserID & Password protected void authUser () { if (user == null && password == null) { JFrame frame = new JFrame(); JTextField userField = new JTextField(); JTextField passField = new JTextField(); userField.setBorder(new TitledBorder("ユーザ名")); passField.setBorder(new TitledBorder("パスワード")); Object[] obj = {userField, passField}; int ans = JOptionPane.showConfirmDialog(frame, obj, "ユーザ名、パスワード確認", JOptionPane.OK_CANCEL_OPTION); if (ans == 0) { if (userField == null || passField == null) { System.exit(0); } user = userField.getText(); password = passField.getText(); } else { System.exit(0); } } } // Get INBOX protected void getInbox () { try { if (!store.isConnected()) { store.connect(); } Folder inbox = store.getFolder(INBOX); header.setFolder(inbox); } catch (MessagingException me) { JOptionPane.showMessageDialog(pane, me.toString()); } } // Button Action class Connect implements ActionListener { JFrame frame = new JFrame(); Folder folder; FolderTreeNode node; public void actionPerformed (ActionEvent e) { try { TreePath path = mailtree.getSelectionPath(); node = (FolderTreeNode)path.getLastPathComponent(); if (!store.isConnected() && folder == null) { store.connect(); folder = store.getFolder(INBOX); } else { folder = null; store.close(); store.connect(); if (path != null) { folder = node.getFolder(); } else { folder = store.getFolder(INBOX); } } } catch (MessagingException me) { JOptionPane.showMessageDialog(frame, me); } header.setFolder(folder); } } class Address implements ActionListener { public void actionPerformed (ActionEvent e) { System.out.println("Address"); } } class Delete implements ActionListener { public void actionPerformed (ActionEvent e) { header.deleteMessage(mv.msg); } } class CreateF implements ActionListener { JFrame frame = n ew JFrame(); Folder sfolder; FolderTreeNode node; public void actionPerformed (ActionEvent e) { try { TreePath path = mailtree.getSelectionPath(); if (path == null) { JOptionPane.showMessageDialog(frame, " フォルダが選択されていません。"); return; 81 WWW に基づいたインターネットメールシステムの構築 } DefaultTreeModel treeModel = (DefaultTreeModel)mailtree.getModel(); mailtree.clearSelection(); // Get selected folder class node = (FolderTreeNode)path.getLastPathComponent(); sfolder = node.getFolder(); // Make new folder if selected folder can hold folders if ((sfolder.getType() & Folder.HOLDS_MESSAGES) == 0) { JTextField tx = new JTextField(); String dialog_mes = sfolder.toString() + "にフォルダを作成します。¥n" + "フォルダの名前を決めてください。¥n" + "フォルダが、ほかのフォルダを内包することの出来る¥n" + "フォルダにする場合は、名前の最後に¥"/¥"を付けてください。"; Object[] obj = {dialog_mes, tx}; int ans = JOptionPane.showConfirmDialog(frame, obj, "フォルダ作成", JOptionPane.OK_CANCEL_OPTION); if (ans == 0) { //OK Folder newFolder = store.getFolder(sfolder.toString() + "/" + tx.getText()); if (newFolder.exists()) { JOptionPane.showMessageDialog(frame, "そのフォルダはすでに存在しています。"); return; } if (tx.getText().endsWith("/")) { newFolder.create(Folder.HOLDS_FOLDERS); } else { newFolder.create(Folder.HOLDS_MESSAGES); } FolderTreeNode newNode = new FolderTreeNode(newFolder); node.removeAllChildren(); node.insert(newNode, 0); treeModel.nodeChanged(node); treeModel.nodeStructureChanged(node); } } else { JOptionPane.showMessageDialog(frame, " そこにはフォルダを作ることはできません。"); } } catch ( MessagingException me) { JOptionPane.showMessageDialog(frame, me); } catch (Exception ex) { System.out.println(ex+":"); ex.printStackTrace(); } } } class DeleteF implements ActionListener { JFrame frame = new JFrame(); public void actionPerformed (ActionEvent e) { try { TreePath path = mailtree.getSelectionPath(); if (path == null) { JOptionPane.showMessageDialog(frame, " フォルダが選択されていません。"); return; } FolderTreeNode node = (FolderTreeNode)path.getLastPathComponent(); Folder folder = node.getFolder(); DefaultTreeModel treeModel = (DefaultTreeModel)mailtree.getModel(); if (folder.toString().equals(INBOX) || folder.toString().equals(TRASH) || folder.toString().equals(SENT) || folder.toString().equals(IMAPFOLDER)) { JOptionPane.showMessageDialog(frame, " そのフォルダは削除できません。"); return; } String dialog_mes = " フォルダ" + node.toString() + " を削除します。¥n" + "このフォルダに内包されるフォルダもすべて削除されます。"; Object[] obj = {dialog_mes}; } } int ans = JOptionPane.showConfirmDialog(frame, obj, "フォルダ削除", JOptionPane.OK_CANCEL_OPTION); if (ans == 0) { //OK folder.close(true); folder.delete(true); node.removeFromParent(); treeModel.nodeStructureChanged(node); } } catch (ClassCastException cce) { } catch (Exception me) { JOptionPane.showMessageDialog(frame, me); } class RenameF implements ActionListener { JFrame frame = new JFrame(); public void actionPerformed (ActionEvent e) { try { 82 WWW に基づいたインターネットメールシステムの構築 TreePath path = mailtree.getSelectionPath(); if (path == null) { JOptionPane.showMessageDialog(frame, " フォルダが選択されていません。"); return; } FolderTreeNode node = (FolderTreeNode)path.getLastPathComponent(); Folder folder = node.getFolder(); Folder parentFolder = folder.getParent(); DefaultTreeModel treeModel = (DefaultTreeModel)mailtree.getModel(); if (folder.toString().equals(INBOX) || folder.toString().equals(TRASH) || folder.toString().equals(SENT) || folder.toString().equals(IMAPFOLDER)) { JOptionPane.showMessageDialog(frame, "そのフォルダ名は変更できません。"); return; } } } JTextField tx = new JTextField(); String dialog_mes = node.toString() + "の名前を変更します。¥n新しい名前: "; Object[] obj = {dialog_mes, tx}; int ans = JOptionPane.showConfirmDialog(frame, obj, "フォルダ名変更", JOptionPane.OK_CANCEL_OPTION); if (ans ==0) { //OK Folder newFolder = store.getFolder(parentFolder.toString() + "/" + tx.getText()); if (newFolder.exists()) { JOptionPane.showMessageDialog(frame, "そのフォルダはすでに存在しています。"); return; } folder.close(true); folder.renameTo(newFolder); node.setUserObject(newFolder); treeModel.reload(node); } } catch (Exception me) { JOptionPane.showMessageDialog(frame, me); } class Exit implements ActionListener { public void actionPerformed (ActionEvent e) { System.exit(0); } } class Close implements ActionListener { JFrame frame = new JFrame(); public Close (JFrame frame) { this.frame = frame; } public void actionPerformed (ActionEvent e) { frame.dispose(); } } // My tree cell renderer class TreeIcons extends JLabel implements TreeCellRenderer { Icon file = new ImageIcon("img/mailfolder.gif"); Icon closedFolder = new ImageIcon("img/folderclose.gif"); Icon openFolder = new ImageIcon("img/folderopen.gif"); Icon folder = new ImageIcon("img/folder.gif"); public Component getTreeCellRendererComponent ( JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { if (selected) { setOpaque(true); } if (hasFocus) { setOpaque(true); } else { setOpaque(false); } DefaultMutableTreeNode node =(DefaultMutableTreeNode) value; if (leaf) { this.setIcon(file); } else { if (expanded) { this.setIcon(openFolder) ; } else { this.setIcon(closedFolder); } if (row == 0) { this.setIcon(folder); } } 83 WWW に基づいたインターネットメールシステムの構築 if (node.toString().equals(INBOX)) { this.setText("受信トレイ"); } else if (node.toString().equals(TRASH)) { this.setText("削除メール"); } else if (node.toString().equals(SENT)) { this.setText("送信メール"); } else if (node.toString().equals(IMAPFOLDER)) { this.setText("メールボックス"); } else { this.setText(node.toString ()); } return this; } } } // Tree selection listener class TreePress implements TreeSelectionListener { } public void valueChanged (TreeSelectionEvent e) { TreePath path = e.getNewLeadSelectionPath(); if (path != null) { try { Object o = path.getLastPathComponent(); FolderTreeNode node = (FolderTreeNode) o; Folder folder = node.getFolder(); if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) { Mail.header.setFolder(folder); } } catch (ClassCastException cce) { } catch (Exception me) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog(frame, me); } } } New.java /* * @(#) New.java * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. * */ import import import import import import import import import import java.util.*; java.io.*; java.awt.*; java.awt.event.*; javax.mail.*; javax.mail.internet.*; javax.activation.*; javax.swing.*; javax.swing.border.*; javax.swing.text.*; /* * 新規メール作成、返信メール作成、メール送信を行います。 * */ class New extends Window implements ActionListener { String from; JTextField to, cc, subject; JTextArea body; Viewer mv; public New () { this("New Mail", 0); } public New (String from) { this("New Mail", 0); this.from = from; } public New (String from, Viewer mv) { this("New Mail", 0); this.from = from; this.mv = mv; String subjecttext; 84 WWW に基づいたインターネットメールシステムの構築 if (mv.msg != null) { try { Address[] adds = mv.msg.getFrom(); if (adds != null && adds.length > 0) { this.to.setText(adds[0].toString()); } if (mv.msg.getSubject() != null) { subjecttext = mv.msg.getSubject(); } else { subjecttext = ""; } this.subject.setText("Re:" + subjecttext); StringBuffer sb = new StringBuffer(); sb.append ("Reply to ¥"" + subjecttext + "¥" from " + to.getText() + ": ¥n¥n"); StringTokenizer st = new StringTokenizer(mv.body.getText(), "¥n"); while (st.hasMoreTokens()) { sb.append("> " + st.nextToken() + "¥n"); } this.body.setText(sb.toString()); } catch (MessagingException me) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog(frame, me); } } } public New (String title, int ui) { super (title, ui); JPanel header = new JPanel(new GridLayout(3, 1)); this.to = new JTextField(); to.setBorder(new TitledBorder("To:")); to.setFont(new Font("Monospaced", Font.PLAIN, 12)); header.add(to); this.cc = new JTextField(); cc.setBorder(new TitledBorder("Cc:")); cc.setFont(new Font("Monospaced", Font.PLAIN, 12)); header.add(cc); this.subject = new JTextField(); subject.setBorder(new TitledBorder("Subject:")); subject.setFont(new Font("Monospaced", Font.PLAIN, 12)); header.add(subject); this.body = new JTextArea(); body.setBorder(new TitledBorder ("Body:")); body.setFont(new Font("Monospaced", Font.PLAIN, 12)); body.setLineWrap(true); JScrollPane textPane = new JScrollPane(body); JSplitPane jsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, header, textPane); jsp.setDividerSize(2); pane.add(jsp); } JButton send = addTool("", "img/send.gif", "Send Mail", new Send(to, cc, subject, body, this)); send.setBorder(new EmptyBorder(1, 1, 1, 1)); JButton close = addTool ("", "img/close.gif", "Close", new Close(to, cc, subject, body, this)); close.setBorder(new EmptyBorder(1, 1, 1, 1)); public void actionPerformed (ActionEvent e) { New w; if (mv != null) { w = new New(from, mv); } else { w = new New(from); } w.setSize(480, 400); w.setVisible(true); } class Send implements ActionListener { JTextField to, cc, subject; JTextArea body; JFrame frame; Send (JTextField to, JTextField cc, JTextField subject, JTextArea body, JFrame frame) { this.to = to; this.cc = cc; this.subject = subject; this.body = body; this.frame = frame; } public void actionPerformed (ActionEvent e) { try { MimeMessage msg = new MimeMessage (Mail.session); msg.setFrom(new InternetAddress (from)); InternetAddress[] address = {new InternetAddress(to.getText())}; 85 WWW に基づいたインターネットメールシステムの構築 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to.getText(), false)); if (cc.getText() != null) { msg.setRecipients (Message.RecipientType.CC, InternetAddress.parse(cc.getText(), false) ); } msg.setSubject(subject.getText(), "ISO-2022-JP"); msg.setSentDate(new Date()); msg.setContent(body.getText(), "text/plain; charset=ISO-2022-JP"); WaitingFor wait = new WaitingFor(Mail.status, msg.getSubject()); wait.start(); Transport.send(msg); Folder sent = Mail.store.getFolder(Mail.SENT); Message[] msgs = {msg}; sent.appendMessages(msgs); wait.myStop(); to.setText(null); cc.setText(null); subject.setText(null); body.setText(null); dispose(); } catch (MessagingException me) { Object[] msg = {"Error!", me}; JOptionPane.showMessageDialog (pane, msg); } } } class Close implements ActionListener { JTextField to, cc, subject; JTextArea body; JFrame frame; Close (JTextField to, JTextField cc, JTextField subject, JTextArea body, JFrame frame) { this.to = to; this.cc = cc; this.subject = subject; this.body = body; this.frame = frame; } public void actionPerformed (ActionEvent e) { to.setText(null); cc.setText(null); subject.setText(null); body.setText(null); dispose(); } } } Viewer.java /* * @(#) Viewer.java * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. * */ import import import import import import import import java.awt.*; java.awt.event.*; javax.mail.*; javax.activation.*; java.util.Date; java.io.IOException; javax.swing.*; javax.swing.border.*; /* * 選択されたメールを表示します。 * */ public class Viewer extends JPanel { Message msg; JTextArea headers; JTextArea body; DataHandler dataHandler = null; String verb = null; 86 WWW に基づいたインターネットメールシステムの構築 public Viewer () { this (null); } public Viewer (Message what) { super (new GridBagLayout ()); JTextArea headercaption; GridBagConstraints gb = new GridBagConstraints (); gb.fill = GridBagConstraints.BOTH; gb.weightx = 0; gb.weighty = 0; headercaption = new JTextArea ("From:¥nTo:¥nCc:¥nSubject:"); headercaption.setFont(new Font("Monospaced", Font.PLAIN, 12)); headercaption.setEditable (false); add (headercaption, gb); gb.gridwidth = GridBagConstraints.REMAINDER; headers = new JTextArea (""); headers.setFont(new Font("Monospaced", Font.PLAIN, 12)); headers.setEditable (false); add (headers, gb); gb.weightx = 1.0; gb.weighty = 1.0; body = new JTextArea (""); body.setFont(new Font("Monospaced", Font.PLAIN, 12)); body.setEditable (false); body.setBorder (new LineBorder (Color.gray)); body.setLineWrap (true); add (body, gb); } setMessage (what); public void setMessage (Message what) { msg = what; if (body != null) { body.setText(""); } if (what != null) { getHeader(); getBody(); } else { headers.setText(""); body.setText(""); } invalidate(); validate(); } public Message getMessage () { return (msg); } protected void getHeader () { String String String String String String header = new String(); from = new String(); to = new String(); cc = new String(); subject = new String(); date = new String(); try { // date Date date_tmp = msg.getSentDate(); if (date_tmp != null) { date = date_tmp.toString(); } else { date = "Unknown"; } // from Address[] adds = msg.getFrom(); if (adds != null && adds.length > 0) { from = adds[0].toString(); } else { from = "Unknown"; } // to adds = msg.getRecipients (Message.RecipientType.TO); 87 WWW に基づいたインターネットメールシステムの構築 if (adds != null && adds.length > 0) { to = adds[0].toString(); } // cc adds = msg.getRecipients (Message.RecipientType.CC); if (adds != null && adds.length > 0) { to = adds[0].toString(); } // subject subject = msg.getSubject(); if (subject == null) { subject = ""; } header = from + "¥n" + to + "¥n" + cc + "¥n" + subject; headers.setText (header); } catch (MessagingException me) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog(frame, me); } } protected void getBody () { String bodystring = new String(); Object o = new Object(); try { o = msg.getContent(); } catch (Exception e) { JFrame frame = new JFrame(); JOptionPane.showMessageDialog(frame, e); } } } if (o instanceof String) { bodystring = (String)o; body.setText (bodystring); } WaitingFor.java /* * @(#) WaitinigFor.java * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. * */ import javax.swing.*; class WaitingFor extends Thread { Thread blinker; String[] message = {"データ転送中...", "しばらくお待ちください"}; JTextField Status; String OtherComment; public WaitingFor (JTextField Status, String OtherComment) { this.Status = Status; this.OtherComment = OtherComment; } public void run() { Thread thisThread = Thread.currentThread(); blinker = thisThread; Status.setText(message[0] + " [ " + OtherComment + " ] " + message[1]); while (blinker == thisThread) { try { thisThread.sleep(10); } catch (InterruptedException e) {} } Status.setText("転送終了 [" + OtherComment + "]"); } } public void myStop () { blinker = null; } 88 WWW に基づいたインターネットメールシステムの構築 [B] CGI、サーバサイドプログラム ソースコード ファイルの構造3 5 COPYRIGHT admin/ index.html src/ mailer/ user/ admin: delusers.cgi* mail.cgi* users.cgi* delusers2.cgi* modifysys.cgi* .htaccess index.html sbin@ chuserinfo.cgi* lib@ sys.cgi* mailer: activation.jar index.html chuserinfo.cgi* index.pl* .htaccess img/ mailer/img: connect.gif delete.gif address.gif bluemountain.gif close.gif src: sql/ mail.html mail.jar lib@ sbin@ folderopen.gif rename.gif mailfolder.gif reply.gif exit.gif make.gif folder.gif new.gif folderclose.gif remove.gif send.gif wrapper/ src/sql: userdb.sql src/wrapper: Makefile useradd.c userdel.c user: lib/ register.html register.cgi* sbin/ user/lib: chpass.pl commify.pl conf.pl crypter.pl user/sbin: checkPasswd* useradd* httpdie.pl jcode.pl lockfile.pl mailspool.pl* userdel* user/register.html 利用登録フォームの HTML。 user/register.cgi 利用登録用 CGI。引数その他により、ユーザ側の情報変更、管理側の情報変更もこの CGI が 行う。CGI 内部では、1) DB のアップデート、2)ユーザアカウントの作成、3)ユーザパスワード の変更をそれぞれ行う。 user/lib/chpass.pl パスワード変更用の Perl ライブラリ。システムのパスワードデータベースファイルを直接書 きかえる。 user/lib/commify.pl 35 末尾それぞれ「/」がディレクトリ、「*」が実行可能ファイル、「@」がシンボリックリンク。「:」は、 それ以降がそのディレクトリの内容であることを意味する。 89 WWW に基づいたインターネットメールシステムの構築 数字に 3 桁ずつカンマを打つための Perl ライブラリ。メールの蓄積量の表示の際に利用して いる。 user/lib/conf.pl 全体の定数を集めた Perl ライブラリ。C 言語でいうヘッダファイルのようなもの。 user/lib/crypter.pl 引数として受け取った変数の無いようをシステム標準の暗号化アルゴリズム(Solaris では DES)で暗号化するためのライブラリ。パスワードの暗号化に利用している。 user/lib/httpdie.pl プログラム実行中にエラーが起きた場合に、ブラウザに対してエラーメッセージを出力するた めのライブラリ。 user/lib/jcode.pl 日本語の漢字コードを変換するためのライブラリ。 user/lib/lockfile.pl ファイルに排他ロックを掛けたり、ロックを解除するためのライブラリ。 user/lib/mail.pl メール送信用のライブラリ。引数を渡すと sendmail を呼び出してくれる。 user/lib/mailspool.pl 各ユーザのメールスプールの総量を計算するためのライブラリ。全ユーザを対象とする場合 と、引数のユーザを対象にする場合と選べる。 user/lib/mime.pl 引数をメールヘッダ用に Base64 でエンコーディングおよび、ディコーディングするためのラ イブラリ。漢字コードの変換はしないので、ISO-2022JP にのみ対応。 user/sbin/checkPasswd Apache の mod_auth_sys モジュールが /etc/shadow を読込みパスワードの一致を確認するた めの setuid されたプログラム。 90 WWW に基づいたインターネットメールシステムの構築 user/sbin/useradd /usr/sbin/useradd を呼び出すための setuid されたラッパプログラム。情報登録 CGI から呼び 出される。 user/sbin/userdel /usr/sbin/userdel を呼び出すための setuid されたラッパプログラム。情報登録 CGI から呼び 出される。 mailer/.htaccess 一般ユーザの認証を促すための設定ファイル。 mailer/index.html ログイン後のユーザメニューの HTML。 mailer/index.pl ユーザ名を取得し、表示するための SSI3 6 。 mailer/mail.html メーラアプレットを起動する HTML。 mailer/chuserinfo.cgi ユーザ用の登録情報変更フォーム CGI。変更プロセスでは、user/register.cgi が呼び出される。 admin/.htaccess 管理者の認証を促すための設定ファイル。 admin/index.html 管理者用のメニューの HTML。 admin/chuserinfo.cgi 36 Server Side Include の略。HTML 中にサーバ側で様々なインクルードをする機能。 91 WWW に基づいたインターネットメールシステムの構築 管理者用の登録情報変更フォーム CGI.変更プロセスでは、同じく user/register.cgi が呼び出 される。 admin/delusers.cgi 削除用にユーザ一覧を出力する CGI。削除を決定すると、delusers2.cgi を呼び出す。 admin/delusers2.cgi Delusers.cgi で指定されたユーザを削除する CGI。 admin/mail.cgi システムが設定した制限を越えてメールを蓄積しているユーザを蓄積量順に出力するための CGI. admin/modifysys.cgi システム設定を更新するための CGI。sys.cgi から呼び出される。 admin/sys.cgi シ ス テ ム 設 定 の 一 覧 を 更 新 用 に フ ォ ー ム と し て 出 力 す る CGI 。 更 新 を 決 定 す る と 、 modifysys.cgi を呼び出す。 admin/users.cgi ユーザ情報の一覧を表示する CGI。この中から削除をえらん場合は、delusers2.cgi を変更を 選んだ場合は chuserinfo.cgi を呼び出す。 src/sql/userdb.sql ユーザ情報データベース定義用の SQL 文。 src/wrapper/Makefile useradd.c、userdel.c をコンパイルするためのマクロ定義。 src/wrapper/useradd.c useradd の C 言語ソースコード。 src/wrapper/userdel.c 92 WWW に基づいたインターネットメールシステムの構築 userdel の C 言語ソースコード。 93 WWW に基づいたインターネットメールシステムの構築 COPYRIGHT Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON This program is modify it under as published by of the License, free software; you can redistribute it and/or the terms of the GNU General Public License the Free Software Foundation; either version 2 or (at your option) any later version. This program 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. To contact the author, please send Email at [email protected]. His current address is Kanbe-building 4F, 1-1-23 Uehara, Shibuya-ku, Tokyo, Japan, 151-0064. This work is done entirely as his Master thesis supervised by Prof. Masayuki Ida as one of his laboratory projects. To contact the project leader, please send Email at [email protected]. This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. admin/ .htaccess # # Auth setting for login # AuthSystem On AuthSystemAuthorative On AuthType Basic AuthName "Administrators only" <Limit GET POST> require user admin subadmin </Limit> chuserinfo.cgi #!/usr/local/bin/perl # User Administration CGI: Change each user information # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib "./lib"; require 'jcode.pl'; require 'httpdie.pl'; require 'conf.pl'; # Get input CGI::ReadParse(¥%Q); # Get information from db 94 WWW に基づいたインターネットメールシステムの構築 $dbh = Msql->connect($DBHOST, $DB); $sql_statement = <<EOF; SELECT * FROM $TABLE WHERE ID='$Q{'ID'}' EOF $sth = $dbh->query($sql_statement); @data = $sth->fetchrow(); if ($ENV{'REMOTE_USER'} eq $L1ADMIN) { $HTML = <<EOF; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 transitional//EN"> <HTML> <HEAD> <TITLE>WWW メールシステム</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ情報変更</H1> <P>以下の項目すべてに記入してください。</P> <UL> <LI>英数字、記号はすべて半角で入力してください。 <LI>半角カナは使用しないでください。 </UL> <FORM action="../user/register.cgi" method="POST"> <TABLE> <TR> <TD bgcolor=#dddddd>ユーザID (8文字まで)</TD> <TD>$data[1]<INPUT type="hidden" name="ID" value="$data[1]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>パスワード (8文字まで)</TD> <TD><INPUT type="password" size="8" name="Password" value="$data[2]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>パスワード (確認用)</TD> <TD><INPUT type="password" size="8" name="Password2" value="$data[2]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>漢字氏名</TD> <TD><INPUT type="text" size="32" name="Name" value="$data[4]" maxlength=32></TD> </TR> <TR> <TD bgcolor=#dddddd>ローマ字氏名</TD> <TD><INPUT type="text" size="32" name="RName" value="$data[5]" maxlength=32></TD> </TR> <TR> <TD bgcolor=#dddddd>電話番号</TD> <TD><INPUT type="text" size="14" name="Phone" value="$data[6]" maxlength=14></TD> </TR> <TR> <TD bgcolor=#dddddd>郵便番号 (3文字 + 4文字)</TD> <TD><INPUT type="text" size="7" name="PostalCode" value="$data[7]" maxlength=7></TD> </TR> <TR> <TD bgcolor=#dddddd>住所</TD> <TD><TEXTAREA name="Address" cols=48 rows=4>$data[8]</TEXTAREA></TD> </TR> <TR> <TD bgcolor=#dddddd>備考</TD> <TD><TEXTAREA name="Remarks" cols=48 rows=4>$data[9]</TEXTAREA></TD> </TR> <TR> <TD colspan=2 align="right"><INPUT type="submit" value="完了"> <INPUT type="reset" value="やり直し"> <INPUT type="button" value="キャンセル" onClick="history.go(-1)"></TD> </TR> </TABLE> <INPUT type="hidden" name="rq" value="update"> <INPUT type="hidden" name="next" value="users.cgi"> </FORM> $COPYRIGHT </BODY> </HTML> EOF } else { $HTML = <<EOF; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 transitional//EN"> <HTML> <HEAD> <TITLE>WWW メールシステム</TITLE> </HEAD> 95 WWW に基づいたインターネットメールシステムの構築 <BODY bgcolor=#ffffff> <H1>ユーザ情報確認</H1> <P>このページでユーザの情報を変更することはできません。</P> <TABLE> <TR> <TD bgcolor=#dddddd>ユーザID (8文字まで)</TD> <TD>$data[1]</TD> </TR> <TR> <TD bgcolor=#dddddd>漢字氏名</TD> <TD>$data[4]</TD> </TR> <TR> <TD bgcolor=#dddddd>ローマ字氏名</TD> <TD>$data[5]</TD> </TR> <TR> <TD bgcolor=#dddddd>電話番号</TD> <TD>$data[6]</TD> </TR> <TR> <TD bgcolor=#dddddd>郵便番号 (3文字 + 4文字)</TD> <TD>$data[7]</TD> </TR> <TR> <TD bgcolor=#dddddd>住所</TD> <TD>$data[8]</TD> </TR> <TR> <TD bgcolor=#dddddd>備考</TD> <TD>$data[9]</TD> </TR> <TR> <TD colspan=2 align="right"><INPUT type="button" value="戻る" onClick="history.go(-1)"></TD> </TR> </TABLE> $COPYRIGHT </BODY> </HTML> EOF } &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); delusers.cgi #!/usr/local/bin/perl # User Administration CGI: List of user (delete) # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require 'httpdie.pl'; require 'jcode.pl'; require 'conf.pl'; # Sort routine sub byUID { $keyarray{$a} <=> $keyarray{$b}; } # Get infomation from db $sql_statement = <<EOF; SELECT UID, ID, Name FROM $TABLE ORDER BY UID EOF 96 WWW に基づいたインターネットメールシステムの構築 $dbh = Msql->connect($DBHOST, $DB) || &HTTPdie(Msql->errmsg()); $sth = $dbh->query($sql_statement); while (@arr = $sth->fetchrow) { $userinfo{$arr[1]} = "$arr[1] ($arr[2])"; $keyarray{$arr[1]} = "$arr[0]"; } $list = scrolling_list(-name => 'ID', -values => [sort byUID keys(%keyarray)], -size => 10, -multiple => 'true', -labels => ¥%userinfo); if ($list !~ /OPTION/) { $list = p("* ユーザは登録されていません。 *"); } # HTML $HTML = <<EOF; <HTML> <HEAD> <TITLE>ユーザ削除</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ削除</H1> <P>削除するユーザをえらんで、 「完了」をおしてください。</P> <FORM action="delusers2.cgi" method="POST"> $list <BR><BR> <INPUT type="submit" value="完了"><INPUT type="button" value="戻る" onClick="history.go(-1)"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); delusers2.cgi #!/usr/local/bin/perl # User Administration CGI: Delete users # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require 'httpdie.pl'; require 'jcode.pl'; require 'conf.pl'; # Check User if ($ENV{'REMOTE_USER'} ne $L1ADMIN) { &HTTPdie("$ENV{'REMOTE_USER'} ではこの機能を利用できません。"); } $dbh = Msql->connect($DBHOST, $DB) || &HTTPdie(Msql->errmsg()); # Get input @ID = param('ID'); # Delete infomation from db and host foreach $id (@ID) { $sql_statement = <<EOF; 97 WWW に基づいたインターネットメールシステムの構築 DELETE FROM $TABLE WHERE ID = '$id' EOF $sth = $dbh->query($sql_statement); system("$USERDEL -r $id"); } $li = ul(li({-type=>'disc'}, [@ID])); # HTML $HTML = <<EOF; <HTML> <HEAD> <TITLE>ユーザ削除</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ削除結果</H1> <P>削除されたユーザは、以下の通りです。</P> $li <FORM> <INPUT type="button" value="戻る" onClick="document.location='../admin/'"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); mail.cgi #!/usr/local/bin/perl # User Administration CGI: List of system parameters # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require require require require require 'httpdie.pl'; 'mailspool.pl'; 'commify.pl'; 'jcode.pl'; 'conf.pl'; # Check mail spool %spool = &mailspool($DBHOST, $DB, $TABLE); # Get infomation from db $dbh = Msql->connect($DBHOST, $DB) || &HTTPdie(Msql->errmsg()); $sth = $dbh->query("SELECT UID, ID, Name, RName FROM $TABLE ORDER BY UID"); while (@arr = $sth->fetchrow) { $data{$arr[1]} = [@arr]; } # List foreach $user (reverse sort {$spool{$a} <=> $spool{$b}} keys(%data)) { my ($spool) = $spool{$data{$user}[1]}; my ($comspool) = &commify($spool); if ($spool < $MAXMAILSPOOL) { last; } push(@list, "$data{$user}[1] $data{$user}[2] ($comspool Byte)"); } if (defined(@list)) { 98 WWW に基づいたインターネットメールシステムの構築 $list .= ul(li({-type=>'disc'}, [@list])); $msg = <<EOF; 上限を超えているユーザは以下の通りです。</P> $list EOF } else { $msg = <<EOF; 上限を超えてメールを蓄積しているユーザはいません。</P> EOF } # HTML $maxspool = &commify($MAXMAILSPOOL); $HTML = <<EOF; <HTML> <HEAD> <TITLE>メール蓄積量管理</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>メール蓄積量管理</H1> <P>システム側で設定されている上限は、$maxspool Bytes です。<BR> $msg <FORM action="javascript:document.location='../admin/'"> <INPUT type="submit" value="戻る"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); modifysys.cgi #!/usr/local/bin/perl # User Administration CGI: List of users (Mail) # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require require require require 'httpdie.pl'; 'lockfile.pl'; 'jcode.pl'; 'conf.pl'; # Check User if ($ENV{'REMOTE_USER'} ne $L1ADMIN) { &HTTPdie("$ENV{'REMOTE_USER'} ではこの機能を利用できません。"); } # Static vars $CONF = "lib/conf.pl"; %ALT = ("MINUID" => "UID(ユーザ No.) 開始値", "MAXUID" => "UID(ユーザ No.) 終了値", "USERDIR_PREFIX" => "ユーザホームディレクトリ作成場所", "USERSHELL" => "ユーザのログイン shell", "GROUP" => "ユーザのグループ", "MAXMAILSPOOL" => "メールの蓄積量上限 (bytes)", "EXPIRES" => "ユーザアカウントの利用期限", "SMTP" => "SMTP サーバ名称", "IMAP" => "IMAP サーバ名称", "DOMAIN" => "ドメイン名"); # Get input 99 WWW に基づいたインターネットメールシステムの構築 CGI::ReadParse(¥%Q); # Get information open(CONF, $CONF) || &HTTPdie("システム設定ファイルが開けませんでした。"); while (<CONF>) { $conf .= $_; if (/^# System parameters/) { last; } } close(CONF); # Set parameters $parameter = <<EOF; ¥$MINUID = $Q{'MINUID'}; ¥$MAXUID = $Q{'MAXUID'}; ¥$USERDIR_PREFIX = "$Q{'USERDIR_PREFIX'}"; ¥$USERSHELL = "$Q{'USERSHELL'}"; ¥$GROUP = "$Q{'GROUP'}"; ¥$MAXMAILSPOOL = $Q{'MAXMAILSPOOL'}; ¥$EXPIRES = "$Q{'EXPIRES'}"; ¥$SMTP = "$Q{'SMTP'}"; ¥$IMAP = "$Q{'IMAP'}"; ¥$DOMAIN = "$Q{'DOMAIN'}"; 1; EOF open(CONF, ">$CONF") || &HTTPdie("システム設定ファイルが開けません。"); &lock::lock(*CONF); print CONF $conf, $parameter; &lock::unlock(*CONF); close(CONF); # HTML $HTML = <<EOF; <HTML> <HEAD> <TITLE>システムパラメータ</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>システムパラメータ設定結果</H1> <P>システムパラメータの設定は、無事かんりょうしました。</P> <FORM> <INPUT type="button" value="戻る" onClick="document.location='./'"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); sys.cgi #!/usr/local/bin/perl # User Administration CGI: List of users (Mail) # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require 'httpdie.pl'; require 'jcode.pl'; require 'conf.pl'; 100 WWW に基づいたインターネットメールシステムの構築 # Static vars $CONF = "lib/conf.pl"; %ALT = ("MINUID" => "UID(ユーザ No.) 開始値", "MAXUID" => "UID(ユーザ No.) 終了値", "USERDIR_PREFIX" => "ユーザホームディレクトリ作成場所", "USERSHELL" => "ユーザのログイン shell", "GROUP" => "ユーザのグループ", "MAXMAILSPOOL" => "メールの蓄積量上限 (bytes)", "EXPIRES" => "ユーザアカウントの利用期限", "SMTP" => "SMTP サーバ名", "IMAP" => "IMAP サーバ名", "DOMAIN" => "ドメイン名"); %EXP = ("MINUID" => "100 以上の値を指定することが望ましいです。", "MAXUID" => "システム側で指定できる最大値は、65535 となっています。", "USERDIR_PREFIX" => "OS により異なりますが、/home, /export/home 等" . "が一般的です。", "USERSHELL" => "shell の利用を許可しない場合は、存在しない shell を" . "指定してください。", "GROUP" => "システムに存在するグループを指定してください。", "MAXMAILSPOOL" => "メール蓄積量管理でリストアップに利用される値です。", "EXPIRES" => "October 6, 1990 のように指定してください。", "SMTP" => "SMTP サーバとなるホストの名称", "IMAP" => "IMAP サーバとなるホストの名称", "DOMAIN" => "メールアドレスの¥"¥@¥"以降となるドメイン名。ドメイン" . "の MX でないホストの場合は、ホスト名を入力してください。"); # Get information open(CONF, $CONF) || &HTTPdie("システム設定ファイルが開けませんでした。"); while (<CONF>) { my (@line); chomp(); if ($flag) { if (/^#/) { next; } if (/^$/) { last; } $_ =~ s/[¥$¥";]//g; @line = split(/¥s*=¥s*/, $_, 2); if ($ENV{'REMOTE_USER'} eq $L1ADMIN) { push(@input, [$ALT{$line[0]}, $EXP{$line[0]}, textfield( -name=>$line[0], -default=>$line[1], -size=>24, -maxlength=>36 ) ]); } else { push(@input, [$ALT{$line[0]}, $EXP{$line[0]}, $line[1]]); } } if (/^# System parameters/) { $flag ++; } } close(CONF); # Make form foreach $input (@input) { $line .= <<EOF; <TR> <TD nowrap bgcolor=#eeeeee>${$input}[0]</TD> <TD>${$input}[2]</TD> <TD>${$input}[1]</TD> </TR> EOF } # HTML $HTML = <<EOF; <HTML> <HEAD> <TITLE>システムパラメータ設定</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>システムパラメータ設定</H1> <FORM action="modifysys.cgi" methdo="POST"> 101 WWW に基づいたインターネットメールシステムの構築 <TABLE> <TR> <TH bgcolor=#cccccc>パラメータ名</TH> <TH bgcolor=#cccccc>値</TH> <TH bgcolor=#cccccc>説明</TH> </TR> $line <TR><TD colspan=3 align="right"> <INPUT type="submit" value="更新"> <INPUT type="reset" value="元に戻す"> <INPUT type="button" value="キャンセル" onClick="document.location='./'"> </TD></TR> </TABLE> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); users.cgi #!/usr/local/bin/perl # User Administration CGI: List of users (General Information) # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require require require require require 'httpdie.pl'; 'mailspool.pl'; 'commify.pl'; 'jcode.pl'; 'conf.pl'; # Static Vars %ALT = ("UID" => "ユーザ No.", "ID" => "ユーザID", "Password" => " パスワード", "CPassword" => "パスワード", "Name" => "漢字氏名", "RName" => "ローマ字氏名", "Phone" => "電話番号", "PostalCode1" => " 郵便番号前半", "PostalCode2" => " 郵便番号後半", "Address" => "住所", "Remarks" => "備考"); # Get input CGI::ReadParse(¥%Q); # Check mail spool %spool = &mailspool($DBHOST, $DB, $TABLE); # Get infomation from db $dbh = Msql->connect($DBHOST, $DB) || &HTTPdie(Msql->errmsg()); $sth = $dbh->query("SELECT UID, ID, Name, RName FROM $TABLE ORDER BY UID"); while (@arr = $sth->fetchrow) { $userinfo{$arr[0]} = [@arr]; $mailkey{$arr[0]} = $arr[1]; } # Make table foreach $key (sort subSort keys(%userinfo)) { my ($size) = &commify($spool{$userinfo{$key}[1]}); 102 WWW に基づいたインターネットメールシステムの構築 $table .= <<EOF; <TR> <TD align="center" bgcolor=#eeeeee><CODE>$userinfo{$key}[0]</CODE></TD> <TD bgcolor=#eeeeee><CODE>$userinfo{$key}[1]</CODE></TD> <TD bgcolor=#eeeeee nowrap>$userinfo{$key}[2]</TD> <TD bgcolor=#eeeeee nowrap><CODE>$userinfo{$key}[3]</CODE></TD> <TD align="right" bgcolor=#eeeeee><CODE>$size Bytes</CODE></TD> EOF if ($ENV{'REMOTE_USER'} eq $L1ADMIN) { $table .= <<EOF; <TD align="center" bgcolor=#eeeeee>[ <A href="chuserinfo.cgi?ID=$userinfo{$key}[1]">変更</A> ]</TD> <TD align="center" bgcolor=#eeeeee>[ <A href="delusers2.cgi?ID=$userinfo{$key}[1]">削除</A> ]</TD> </TR> EOF } else { $table .= <<EOF; <TD align="center" bgcolor=#eeeeee>[ <A href="chuserinfo.cgi?ID=$userinfo{$key}[1]">確認</A> ]</TD> <TD align="center" bgcolor=#eeeeee>[ 削除 ]</TD> EOF } } # HTML $HTML = <<EOF; <HTML> <HEAD> <TITLE>ユーザ情報</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ情報</H1> <FORM> 表示順序: <INPUT type="button" value="ユーザ No. 順" onClick="document.location='users.cgi'"> <INPUT type="button " value="メール蓄積量順" onClick="document.location='users.cgi?order=byMail'"> </FORM> <TABLE width=90%> <TR> <TH bgcolor=#cccccc nowrap>ユーザ No.</TH> <TH bgcolor=#cccccc nowrap>ユーザ ID</TH> <TH bgcolor=#cccccc nowrap>ユーザ名</TH> <TH bgcolor=#cccccc nowrap>ローマ字名</TH> <TH bgcolor=#cccccc nowrap>メール蓄積量</TH> <TH bgcolor=#cccccc nowrap>ユーザ情報変更</TH> <TH bgcolor=#cccccc nowrap>ユーザ削除</TH> </TR> $table </TABLE> <FORM action="javascript:document.location='../admin/'"> <INPUT type="submit" value="戻る"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); sub subSort { if ($Q{'order'} eq "byMail") { $spool{$mailkey{$b}} <=> $spool{$mailkey{$a}} } else { $a <=> $b; } } mailer/ .htaccess # Auth setting for login 103 WWW に基づいたインターネットメールシステムの構築 # AuthSystem On AuthSystemAuthorative On AuthType Basic AuthName "Registered users only" <Limit GET POST> require valid-user </Limit> chuserinfo.cgi #!/usr/local/bin/perl # User Administration CGI: Change each user information # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib "./lib"; require 'jcode.pl'; require 'httpdie.pl'; require 'conf.pl'; # Get input CGI::ReadParse(¥%Q); $ID = $ENV{'REMOTE_USER'}; # Get information from db $dbh = Msql->connect($DBHOST, $DB); $sql_statement = <<EOF; SELECT * FROM $TABLE WHERE ID='$ID' EOF $sth = $dbh->query($sql_statement); @data = $sth->fetchrow(); if ($#data <= 1) { &HTTPdie("ユーザがデータベースに存在しません。"); } $HTML = <<EOF; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 transitional//EN"> <HTML> <HEAD> <TITLE>WWW メールシステム</TITLE> </HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ情報変更</H1> <P>以下の項目すべてに記入してください。</P> <UL> <LI>英数字、記号はすべて半角で入力してください。 <LI>半角カナは使用しないでください。 </UL> <FORM action="../user/register.cgi" method="POST"> <TABLE> <TR> <TD bgcolor=#dddddd>ユーザID (8文字まで)</TD> <TD>$data[1]<INPUT type="hidden" name="ID" value="$data[1]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>パスワード (8文字まで)</TD> <TD><INPUT type="password" size="8" name="Password" value="$data[2]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>パスワード (確認用)</TD> <TD><INPUT type="password" size="8" name="Password2" value="$data[2]" maxlength=8></TD> </TR> <TR> <TD bgcolor=#dddddd>漢字氏名</TD> <TD><INPUT type="text" size="32" name="Name" value="$data[4]" maxlength=32></TD> </TR> 104 WWW に基づいたインターネットメールシステムの構築 <TR> <TD bgcolor=#dddddd>ローマ字氏名</TD> <TD><INPUT type="text" size="32" name="RName" value="$data[5]" maxlength=32></TD> </TR> <TR> <TD bgcolor=#dddddd>電話番号</TD> <TD><INPUT type="text" size="14" name="Phone" value="$data[6]" maxlength=14></TD> </TR> <TR> <TD bgcolor=#dddddd>郵便番号 (3文字 + 4文字)</TD> <TD><INPUT type="text" size="7" name="PostalCode" value="$data[7]" maxlength=7></TD> </TR> <TR> <TD bgcolor=#dddddd>住所</TD> <TD><TEXTAREA name="Address" cols=48 rows=4>$data[8]</TEXTAREA></TD> </TR> <TR> <TD colspan=2 align="right"><INPUT type="submit" value="完了"> <INPUT type="reset" value="やり直し"> <INPUT type="button" value="キャンセル" onClick="history.go(-1)"></TD> </TR> </TABLE> <INPUT type="hidden" name="rq" value="update"> <INPUT type="hidden" name="next" value="../mailer/"> </FORM> $COPYRIGHT </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); index.pl #!/usr/local/bin/perl # Login SSI for index.html # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use lib "./lib"; require 'jcode.pl'; require 'conf.pl'; $HTML = p("ユーザ名: $ENV{'REMOTE_USER'}"); &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit (0); src/sql/ userdb.sql # # # # # # # # # # User Information Database Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. DROP TABLE userinfo ¥g 105 WWW に基づいたインターネットメールシステムの構築 CREATE TABLE userinfo ( UID INT NOT NULL, ID CHAR(8) NOT NULL, Password CHAR(8), CPassword CHAR(24), Name CHAR(32) NOT NULL, RName CHAR(32) NOT NULL, Phone CHAR(14), PostalCode CHAR(8), Address CHAR(256), Remarks CHAR(256) ) ¥g CREATE UNIQUE INDEX UIDidx ON userinfo(UID) ¥g CREATE UNIQUE INDEX IDidx ON userinfo(ID) ¥g src/wrapper/ Makefile # # # # # # # # # # # # # # Make file for wrappers この wrapper の make 時は、root で作業をしてください。 作成されたプログラムは、setuid されるので非常に危険です。 取り扱いには、ご注意ください。 Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. CC = gcc RM = /bin/rm -f CMD = useradd userdel all: $(CMD) $(CMD): $($@).c $(CC) -O $? -o $@ chown root:root $@ chmod u+s $@ clean: $(RM) $(CMD) useradd.c /* * wrapper for seting UID * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. */ #include <stdio.h> #include <sysexits.h> #include <stdlib.h> #define BIN "/usr/sbin/useradd" main (argc, argv, env) int argc; char * argv[]; char * env[]; { char * prog; 106 WWW に基づいたインターネットメールシステムの構築 if ((prog = (char *) malloc(strlen(BIN)) + 2) == NULL) { fprintf(stderr, "%s: error: malloc failed¥n", argv[0]); exit(EX_OSERR); } setgid(getegid()); setuid(geteuid()); sprintf(prog, "%s", BIN); execve(prog, argv, env); } userdel.c /* * wrapper for seting UID * * Blue Mountain Webmailer * Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> * * This program is licensed under the GPL, whose whole statements * are included in the file 'COPYRIGHT' which must be distributed * with this source program. */ #include <stdio.h> #include <sysexits.h> #include <stdlib.h> #define BIN "/usr/sbin/userdel" main (argc, argv, env) int argc; char * argv[]; char * env[]; { char * prog; if ((prog = (char *) malloc(strlen(BIN)) + 2) == NULL) { fprintf(stderr, "%s: error: malloc failed¥n", argv[0]); exit(EX_OSERR); } setgid(getegid()); setuid(geteuid()); sprintf(prog, "%s", BIN); execve(prog, argv, env); } user/ register.cgi #!/usr/local/bin/perl -U # # User registration CGI # # Blue Mountain Webmailer # Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> # # This program is licensed under the GPL, whose whole statements # are included in the file 'COPYRIGHT' which must be distributed # with this source program. # use CGI(":standard"); use Msql; use lib './lib'; require require require require require 'httpdie.pl'; 'chpass.pl'; 'crypter.pl'; 'jcode.pl'; 'conf.pl'; 107 WWW に基づいたインターネットメールシステムの構築 # Check User if ($ENV{'REMOTE_USER'} eq $L2ADMIN) { &HTTPdie("$ENV{'REMOTE_USER'} ではこの機能を利用できません。"); } # Static Vars @DBKEYS = qw (UID ID Password CPassword Name RName Phone PostalCode Address Remark); @KEYS = qw (ID Password Name RName Phone PostalCode Address); %ALT = ("ID" => "希望ユーザID", "Password" => " 希望パスワード", "Name" => "漢字氏名", "RName" => "ローマ字氏名", "Phone" => "電話番号", "PostalCode" => "郵便番号", "Address" => "住所"); @DIGIT = qw (PostalCode); @DIGITPLUS = qw (Phone); @ONEBYTE = qw (Password RName); # Get Input CGI::ReadParse(¥%Q); if ($Q{'PostalCode'} eq "") { $Q{'PostalCode'} = "$Q{'PostalCode1'}$Q{'PostalCode2'}"; } # Check Input foreach $key (@KEYS) { &jcode::convert(¥$Q{$key}, 'euc'); if ($Q{$key} eq "") { push(@err, $ALT{$key}); } } if ($err[0] ne "") { &HTTPdie("以下の項目に記入してください。", @err); } foreach $key (@DIGIT) { if ($Q{$key} =~ /[^¥d]/) { push(@err, $ALT{$key}); } } if (defined(@err)) { &HTTPdie("以下の項目は、半角数字入力項目です。", @err); } foreach $key (@DIGITPLUS) { if ($Q{$key} =~ /[^¥d¥-¥(¥)]/) { push(@err, $ALT{$key}); } } if (defined(@err)) { &HTTPdie("以下の項目は、半角数字および、 「-」(ハイフン)」" . "「()」(括弧)のみ利用可能です。"); } foreach $key (@ONEBYTE) { if ($Q{$key} =~ /[¥x80-¥xff]/) { push(@err, $ALT{$key}); } } if (defined(@err)) { &HTTPdie("以下の項目では、半角英数字記号のみ利用可能です。"); } if ($Q{'ID'} =~ /[^a-zA-Z0-9]/) { &HTTPdie("ユーザIDでは、半角英数字のみ利用可能です。"); } if ($Q{'Password'} ne $Q{'Password2'}) { &HTTPdie("パスワードが一致しません。"); } # Process vars $Q{'CPassword'} = $Q{'Password'}; &crypter::crypter(¥$Q{'CPassword'}); 108 WWW に基づいたインターネットメールシステムの構築 # Create new one or update if ($Q{'rq'} ne "update") { &ckuser(); &writedb(); &useradd(); &chpass($Q{'ID'}, $Q{'CPassword'}); if ($out =~ /error/i) { &rollback(); &HTTPdie("ユーザの作成に失敗しました。理由: <BR>$out"); } } else { &updatedb(); &chpass($Q{'ID'}, $Q{'CPassword'}); print "Location: $Q{'next'}¥n¥n"; } # Output HTML $HTML = <<EOF; <HTML> <HEAD><TITLE>結果</TITLE></HEAD> <BODY bgcolor=#ffffff> <H1>ユーザ登録結果</H1> <P>ユーザ登録が完了しました。</P> <FORM action="javascript:document.location='../index.html'"> <INPUT type="submit" value="次へ"> </FORM> </BODY> </HTML> EOF &jcode::convert(¥$HTML, $CODE); print header, $HTML; exit(0); # Insert DB record sub writedb { $dbh = Msql->connect($DBHOST, $DB) || HTTPdie($dbh->errmsg()); $sql_statement = <<EOF; INSERT INTO $TABLE VALUES ( $uid, '$Q{'ID'}', '$Q{'Password'}', '$Q{'CPassword'}', '$Q{'Name'}', '$Q{'RName'}', '$Q{'Phone'}', '$Q{'PostalCode'}', '$Q{'Address'}', NULL) EOF $sth = $dbh->query($sql_statement) || HTTPdie($dbh->errmsg()); } # Update DB record sub updatedb { $dbh = Msql->connect($DBHOST, $DB) || HTTPdie($dbh->errmsg()); $sql_statement = <<EOF; UPDATE $TABLE SET Password = '$Q{'Password'}', CPassword = '$Q{'Cpassword'}', Name = '$Q{'Name'}', RName = '$Q{'RName'}', Phone = '$Q{'Phone'}', PostalCode = '$Q{'PostalCode'}', Address = '$Q{'Address'}', Remarks= '$Q{'Remarks'}' WHERE ID = '$Q{'ID'}' EOF $sth = $dbh->query($sql_statement) || HTTPdie($dbh->errmsg()); } # Add user sub useradd { open(USERADD, "$USERADD " . "-c $Q{'RName'} " . "-d $USERDIR_PREFIX/$Q{'ID'} " . "-e ¥"$EXPIRES¥" " . "-g $GROUP " . "-m -k $SKELDIR " . "-u $uid " . 109 WWW に基づいたインターネットメールシステムの構築 "-s $USERSHELL " . "$Q{'ID'} " . "2>& 1 |") || &HTTPdie("ユーザの作成ができませんでした。"); while (<USERADD>) { $out = $_; } close(USERADD); } # Check user existance sub ckuser { setpwent(); while (@pwent = getpwent) { $user{$pwent[0]} = $pwent[0]; if ($pwent[2] <= $MAXUID && $uid < $pwent[2]) { $uid = $pwent[2]; } } endpwent; if (defined($user{$Q{'ID'}})) { &HTTPdie("そのユーザIDは、すでに使用されています。"); } if ($uid >= $MINUID) { $uid ++; } else { $uid = $MINUID; } } # Roll back for error sub rollback { $dbh = Msql->connect($DBHOST, $DB) || HTTPdie($dbh->errmsg()); $sth = $dbh->query("DELETE FROM $TABLE WHERE ID = '$Q{'ID'}'") || HTTPdie($dbh->errmsg()); } user/lib/ chpass.pl # # # # # # # # # # Perl library for change shadow password file entry Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. require 'lockfile.pl'; $SHADOW = "/etc/shadow"; sub chpass() { my ($id, $cpass) = @_; my ($out); open(SHADOW, $SHADOW); while (<SHADOW>) { my (@line) = split(/:/, $_); if ($line[0] eq "$id") { $line[1] = $cpass; $out .= join(':', @line); } else { $out .= $_; } } close(SHADOW); open(SHADOW, ">$SHADOW"); &lock::lock(*SHADOW); print SHADOW $out; &lock::unlock(*SHADOW); close(SHADOW); return $out; 110 WWW に基づいたインターネットメールシステムの構築 } 1; commify.pl sub commify { local($_) = shift; 1 while s/^(-?¥d+)(¥d{3})/$1,$2/; return $_; } 1; conf.pl # # # # # # # # # # Configuration file for WWW Mail System Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. $COPYRIGHT = "<HR size=1 noshade> Yoshiyuki Kumon (kumon¥@sipeb.aoyama.ac.jp)"; # ENV $ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin:/usr/sbin:/etc"; # Output Kanji Code $CODE = "sjis"; # 出力時漢字コード # Database $DBHOST = "localhost"; $DB = "userdb"; $TABLE = "userinfo"; # データベースホスト # データベース名 # データベーステーブル名 # useradd $USERADD = "./sbin/useradd"; $USERDEL = "./sbin/userdel"; $SKELDIR = "/etc/skel"; # useradd コマンドパス # userdel コマンドパス # skel ディレクトリ # Administrators $L1ADMIN = "admin"; $L2ADMIN = "subadmin"; # システム管理者 # サポート管理者 # System parameters $MINUID = 50000; $MAXUID = 59999; $USERDIR_PREFIX = "/export/home"; $USERSHELL = "/usr/bin/csh"; $GROUP = "users"; $MAXMAILSPOOL = 10 * 1024; $EXPIRES = "March 30, 1999"; $SMTP = "noa.sipeb.aoyama.ac.jp"; $IMAP = "noa.sipeb.aoyama.ac.jp"; $DOMAIN = "noa.sipeb.aoyama.ac.jp"; 1; crypter.pl # # # # # # # # # # # Encrypt input with random salt Usage: crypter(¥$input) $input: word to be encrypted Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. 111 WWW に基づいたインターネットメールシステムの構築 # package crypter; sub crypter { local ($in) = @_; my ($key, $salt, @salt); @salt = ('a' .. 'z', 'A' .. 'Z', 0 .. 9, '.', '/'); foreach $i (0, 1) { $key .= $salt[int(rand($#salt))]; } chomp($$in); $$in = crypt($$in, $key); } 1; httpdie.pl # # # # # # # # # # # # # Encrypt input with random salt Usage: httpdie($err_msg, @err_list) $err_msg: Error message @err_list: Error item list Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. use CGI(":standard"); require "jcode.pl"; sub HTTPdie { my ($err_msg, @err_list) = @_; my ($list, $li, $out); foreach $list (@err_list) { $li .= "<LI>$list¥n"; } if ($li ne "") { $li = "<UL>¥n$li</UL>¥n"; } $out = <<EOF; <HTML> <HEAD><TITLE>入力エラー</TITLE></HEAD> <BODY> <H1>入力エラー</H1> <P>$err_msg</P> $li <FORM action="javascript:history.go(-1)"> <INPUT type="submit" value="戻る"> </FORM> EOF &jcode::convert(¥$out, "euc"); print header, $out; exit (0); } 1; jcode.pl ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perlを参照。 lockfile.pl package lock; $LOCK_SH = 1; $LOCK_EX = 2; $LOCK_NB = 4; 112 WWW に基づいたインターネットメールシステムの構築 $LOCK_UN = 8; sub lock { local(*FILEHANDLE) = @_; flock(FILEHANDLE, $LOCK_EX); seek(FILEHANDLE, 0, 2); } sub unlock { local(*FILEHANDLE) = @_; flock(FILEHANDLE, $LOCK_UN); } 1; mailspool.pl # # # # # # # # # # Check and calculate user mail spool Blue Mountain Webmailer Copyright (C) 1999 Yoshiyuki KUMON <[email protected]> This program is licensed under the GPL, whose whole statements are included in the file 'COPYRIGHT' which must be distributed with this source program. use Msql; sub mailspool { my ($HOST, $DB, $TABLE, $USER) = @_; my (%PWENT, $dth, $WHERE, $sth, %hash, %MAILSPOOL); unless ($HOST && $DB && $TABLE) { undef; last; } my (%PWENT); setpwent; while (@pwent = getpwent) { $PWENT{$pwent[0]} = $pwent[7]; } endpwend; $dth = Msql->connect($HOST, $DB); $WHERE = "WHERE ID='$USER'" if $USER; $sth = $dth->query("SELECT ID,UID FROM $TABLE $WHERE ORDER BY UID"); while (%hash = $sth->fetchhash()) { my ($DIR) = "$PWENT{$hash{'ID'}}"; my (@MAILBOX) = &search_files("$DIR/IMAP"); push(@MAILBOX, ("$DIR/TRASH","$DIR/SENT","/var/mail/$hash{'ID'}")); my ($SPOOL); foreach (@MAILBOX) { $SPOOL += (stat $_)[7]; } $MAILSPOOL{$hash{'ID'}} = $SPOOL; } if ($USER) { $MAILSPOOL{$USER}; } else { %MAILSPOOL; } } sub search_files { my ($DIR) = shift; my (@MAILBOX, @buf); opendir(DIR, $DIR); @buf = grep !/^¥.¥.?$/, readdir DIR; closedir(DIR); foreach (@buf) { if (-d "$DIR/$_") { push (@MAILBOX, &search_files("$DIR/$_")); } else { push(@MAILBOX, "$DIR/$_"); } } @MAILBOX; } 113 WWW に基づいたインターネットメールシステムの構築 1; 114