第 12 回 セキュリティ、入力

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

12-1. セキュリティ

セキュリティとは

AUP(Acceptable Users' Policy)
利用者が許容できる利用条件
  1. 自分が使用したい時に利用できる。
  2. 自分の情報を保持でき、他人が自分の情報の削除や改変ができないこと。
  3. 自分の使用権限や情報を他人が利用しないこと。
セキュリティ
AUP が守られている状態

セキュリティへの攻撃

  1. コンピュータを使用不能にする。
  2. 情報の破壊、改竄。
  3. パスワード解析、コンピュータの乗っとり、情報漏洩。

事例

医療データ改竄による殺人事件
1995年オーストラリアにおいて、病院職員が自己の勤務する病院のコンピュー タにアクセスし、患者に投与すべき医薬に関するデータを改竄。看護師が改竄 されたデータ通りに薬を与えたため患者が死亡。
社会安全研究財団「情報セキュリティビジョン策定委員会報告書」より
預金額の改竄による不正送金
1995年ロシアのクラッカーによって、米国の某銀行が、 1000万ドルもの不正 送金をされた。
山田英之「セキュリティの基礎」日経オープンシステム1998年4月号 p.258

攻撃方法の分類

直接的攻撃
  1. 不正なコマンドを利用することによる権限の剥奪
  2. ネットワークやコンピュータを流れるデータを監視してパスワードを盗む
  3. 暗号化されたパスワードを解析する。
  4. 相手のコンピュータに対応不能なほどの大量のアクセスを発生させ、使用 不能に陥らせる(フラッディング、DOS(Denial of Service)、 DDOS(Distributed DOS)。
間接的攻撃
  1. コンピュータウィルスやワームをばらまく(自動的に感染するもの)。
  2. トロイの木馬をばらまく(罠にはまった人間が被害を発生させるもの)。

身近なセキュリティ対策

セキュリティを守るために、次のようなことをすると良いです。 但し、利便性は大きく失われることがありますので、状況を判断できるように なったら自己判断でセキュリティを甘くする機能を使う必要が出てくるかも知 れません。

  1. 出処が不明なソフトウェアを実行しない。
  2. フロッピーディスクでのファイルのやりとりをなるべくしない。
  3. 電子メールで添付ファイルを開かない。
  4. Java, JavaScript など他人の作成したソフトウェアを自動的に実行しな いように設定する。

    設定例

    Java を off に
    Javascript を off に
  5. WWW のサーバがブラウザに情報を送ったり、抜き取ったりする cookie を 無効にする。

12-2. 標準入出力(Standard I/O)

MS-DOS プロンプトやコマンドプロンプトでは、キーボードを押すと字が入力 され、画面に字が表示されます。 しかし、このキーボードや画面の関係を変えることが可能です。 例えば、プログラムの実行結果をファイルに残したり、プログラムにキーボー ドからではなくファイルの内容を入力したりできます。 コンピュータの入出力は基本的にはキーボードと画面が対応していますが、特 定のファイルに変更が可能になっています(この入出力の変更のことをリ ダイレクトと言います)。

標準出力

標準出力を変更するにはコマンドを入力した後、「> 出力ファイル名」 を付け足します。 例えば、ディレクトリの内容をファイルに保存するには次のようにします。

dir > file1

このようにするとディレクトリの内容は画面に表示されず、 file1 に保存さ れます。 echo コマンドは「画面に文字を出すコマンド」として紹介しましたが、 実際は標準出力に対して文字を出すコマンドです。 次のようにすると、 file2 に abc という内容が書かれます。

echo abc > file2

演習12-1

  1. コマンド verの出力をファイルに保存しなさい。
  2. コマンド dir /wの出力をファイルに保存しなさい。
  3. 次のプログラムの出力をファイルに保存しなさい。
    #include <stdio.h>
    main(){
      printf("Hello World!\n");
    }
    

標準入力

標準入力を変更するにはコマンドを入力した後、「< 入力ファイル名」を つけます。 例を説明する前に、次のファイルを作って下さい。ファイル名は file3 にして下さい。

3
1
2

このファイルを sort コマンドに入力するには次のようにします。

sort < file3
すると、画面に与えた数が小さい順に出力されます。

EOF

sort コマンドはファイルの内容を小さい順に並べるコマンドです。 ファイルの最後に一番小さい値が来たら、その値を先頭に表示する必要がある ため、 sort の処理はファイルを全て読み終えてからでないと実行できません。 sort に限らず、ファイルを処理するプログラムはファイルの終りを知る必要 があります。 そのため、 OS はファイルが終ると EOF記号(End of File)という特殊な記号 (番兵)をプログラムに与えます。これにより、プログラムは ファイルが終ったことを知ることができます。 MS-DOS や Windows では Ctrl-Z という記号になります。 例えば、次のようにすると、 sort コマンドはキーボードから入力した数字を 並べ替えます。

例
sort[Enter]
3[Enter]
1[Enter]
2[Enter]
[Ctrl-Z][Enter]

その他

コマンドの出力をファイルに「追加」したい時は >> を使用 します。

例
echo abc > file1
echo def >> file1

コマンドの出力を、他のコマンドの入力にしたい時は |(縦棒) を使用しま す。このように複数のコマンドをつなげて処理することをパイプ処理 と言います。

例
dir | sort
dir | more
dir | sort | more

12-3. 入力

getchar

C 言語で標準入力から一文字得るには getchar() 関数を使います。 この関数を使用すると、入力された文字が文字型の値として得ることができま す。 つまり c=getchar(); とすると、一文字得ることができます。 ファイルの終りに達すると EOF という値になります。

ファイルの終りまで一文字ずつ読みながら処理をするには、一文字読む毎に EOF かどうか判定する必要があります。 つまり、プログラムは「(A)一文字読み、読んだ文字が EOF でないとき→(B) 読んだ文字を処理をする」ということ繰り返すことになります。 つまり概念的には次のようなプログラムになります。

while(一文字読み、読み込んだ文字が EOF でないとき){
  読んだ文字を処理する
}

while 文の条件は式の値を利用すると次のように書けます。

while((c=getchar())!=EOF){
  読み込んだ文字の入っている変数 c に対する処理
}

次は標準入力を標準出力にただ書き写すプログラムです。

#include <stdio.h>
main(){
  char c;
  while((c=getchar())!=EOF){
    printf("%c",c);
  }
}

なお、 MS-DOS プロンプトはキーボードから EOF(Ctrl-Z) を受けとると次の 出力文が無効になるというバグがあります。 入力を受けとり終ってから何か出力する際は、空の行を打つ printf 文が必要 になります。但し、コマンドプロンプトでは大丈夫です。

演習12-2

次のプログラムを完成させ、ファイルの文字数を数えるようにしなさい。 また、このプログラムが何文字あるか、このプログラムの標準入力に与えて調 べなさい(つまり 「.\a.exe < このプログラム.c」 を行う)。

#include <stdio.h>
main(){
  char c;
  int n=0;
  while((c=getchar())!=EOF){
    /* 一文字受けとったら、 n を一増やす */
  }
  printf("\n"); /* MS-DOS プロンプトのバグ対策 */
  printf("合計 %d 文字\n",n);
}

演習12-3

ファイルの行数を数えるプログラムを書きなさい。 また書いたプログラムが何行あるか作ったプログラムで調べなさい。

ヒント

実は正確にやろうとすると難しい。 「改行の数を数える」という方法で妥協して良い。


演習12-4

変数 x に文字を与えておき、その文字がファイル中に何文字現れたかを数え るプログラムを書きなさい。


演習12-5

ファイルの最初から 5 行だけを表示するプログラムを作りなさい (ファイルが全部で 5 行以下の時にどうするかも考えなさい)。


演習12-6

ファイルに行番号をつけるプログラムを作りなさい。 例えば次のようなファイルがあったとします。

abc
def
ghi

このときこのファイルを入力すると次の出力が出るようにしなさい。

1: abc
2: def
3: ghi

(なお余裕があったら、ファイルが空の時に何も出力しないように工夫しなさ い)。


演習12-7

入力ファイルの空白を全て取り除いたものを出力するプログラムを作りなさい。


演習12-8

入力ファイルに対して、一行が長い場合、 10 文字ずつ折り返すプログラムを 作りなさい。


scanf

C 言語で変数に数値を入力するには scanf を使います。 使い方は printf とほぼ同様ですが、変数の指定では変数名の前に & 記 号を書きます(理由は詳しい本に譲ります)。 例えば変数 i に整数を入力する時は次のようにします。

scanf("%d",&i);

scanf は同時に複数の変数の値を得ることができます。 scanf は代入が成功した変数の数を値として返します(例えば、数字を入力さ せるに文字を入れられたら失敗します)。 また、ファイルの終りを検出すると EOF を返します。

次は入力した値を 2 倍して返すプログラムです。

#include <stdio.h>
main(){
  float x;
  int c;
  while((c=scanf("%f",&x))!=EOF){
    if(c==1){ /* x に値が代入された時だけ */
      printf("\t%f\n",2*x);
    }
  }
}

なお scanf は空白や改行を読み飛ばしますので、複数の数値を入力する時は、 適宜空白や改行で区切ります。 また、プログラムにキーボードから直接値を入力する時は、 Enter キーを押 すまではプログラムに値が渡らないことに注意して下さい。

演習12-9

ファイルの中の数を合計するプログラムを書きなさい。


演習12-10

ファイルの中の数の平均を計算するプログラムを書きなさい。


演習12-11

ファイルの中の数の最大値を出力するプログラムを書きなさい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科