No. 17/1519 Index Prev Next
Return-Path: minz@super.win.ne.jp
Return-Path: minz@super.win.ne.jp
Received: from nirai.ie.u-ryukyu.ac.jp (nirai-1.ie.u-ryukyu.ac.jp [133.13.48.1] (may be forged)) by rananim.ie.u-ryukyu.ac.jp (8.8.8/3.5Wpl5-98022819) with ESMTP id QAA28316 for ; Tue, 12 Jan 1999 16:59:50 +0900 (GMT+0900)
Received: from super.win.or.jp (super.win.or.jp [202.26.1.170])
	by nirai.ie.u-ryukyu.ac.jp (8.8.8/3.6W-98061617) with ESMTP id QAA16840
	for ; Tue, 12 Jan 1999 16:49:01 +0900 (JST)
Received: (from minz@localhost)
	by super.win.or.jp (8.8.8/8.8.8-SUPER) id QAA19762;
	Tue, 12 Jan 1999 16:52:47 +0900 (JST)
Message-Id: < 199901120752.QAA19762@super.win.ne.jp> 
From: Yasushi Shinjo 
To: committee@fj-news.org
Subject: [committee:15] PGP key for fj.* 
Date: Tue, 12 Jan 1999 16:55:33 +0900
Reply-To: committee@fj-news.org
Precedence: list
Sender: committee-owner@fj-news.org
Errors-To: committee-owner@fj-news.org

新城です。こんにちは。

> From: Yasuhisa Kuzuha 
>  Date: Tue, 12 Jan 1999 12:04:42 +0900
>  葛葉です
>  旧アドレス: PGP使用 新城・塚本さんのさんの旧パッケージ使用
>        From: fj-committee@...   
>              user: fj.news.announce
>  
>  新アドレス: PGP使用 新パッケージ使用(update版)
>        From: committee@fj-news.org 
>              user: fj.news.announce
>  ということでいいのでしょうか? 新パッケージは、各自でもupdateで
>  きるでしょうが、旧パッケージを持ってらっしゃらないかたもおられ
>  ますし、念のため新城さんにお願いした方がいいでしょうね。

3箇所の修正で大丈夫でした。末尾に全部付けます。

chaos[signcontrol.fj-2.0] 177% diff signcontrol.fj-nara signcontrol.fj-org
30,31c30,31
<  $force{'From'} = 'fj-committee@cow.nara.sharp.co.jp (Fj Newsgroups Management Committee)';
<  #$force{'Sender'} = 'fj-committee@cow.nara.sharp.co.jp';
---
>  $force{'From'} = 'committee@fj-news.org (Fj Newsgroups Management Committee)';
>  #$force{'Sender'} = 'committee@fj-news.org';
38c38
<  $id_host = 'cow.nara.sharp.co.jp';
---
>  $id_host = 'fj-news.org';
chaos[signcontrol.fj-2.0] 178% 

しばらくは、2つのアドレスで出すことになります。それで、2つ
のスクリプトを使うというので、いかがでしょうか。
	signcontrol.fj-nara	以前のもの
	signcontrol.fj-org	新しいアドレスのもの
使い方は、こうなります。

% signcontrol.fj-nara  newgroup.nara.pgp
% pgpverify-1.10 <  newgroup.nara.pgp
% inews -h newgroup.nara.pgp
% signcontrol.fj-org  newgroup.org.pgp
% pgpverify-1.10 <  newgroup.org.pgp
% inews -h newgroup.org.pgp

ここで、コントロール・メッセージの雛型 newgroup.ngname は、
1つで大丈夫です。

>  2ヶ所からControl が届いたとして、(fj.news.admを読んでいる
>  国内サイトはいいとして)「どちらが本物だ」という混乱はないで
>  しょうか? PGP signが本物なら、それで問題はないのでしょうか?

どちらも本物なので、中身が同じなら大丈夫でしょう。INN の設定
で電子メールのアドレスの所を「*」にしてしまうと、From: は見
ないでPGP の署名だけを見るようになりますが、普通の管理者は、
新しい方に修正するか、念のために2つのアドレスを登録するので
しょう。

>  fj.news.adm以外に、どこかにちゃんと連絡するか、announceする
>  かしないといけないのでしょうか? このあたり、私はあまりわかり
>  ませんので、どなたか教えて下さい。

INN 2.2 のリリースには、ぎりぎり間に合ったということでしょうか。
あと、説明の WWW ページも作り直しました。英文などのチェック
もよろしくお願いします。

http://www.hlla.is.tsukuba.ac.jp/~yas/fj/

OK となると、次の場所にコピーします。

http://www.is.tsukuba.ac.jp/~yas/fj/

コピー前の文書で http://www.is.tsukuba.ac.jp/ となっているも
のは、http://www.hlla.is.tsukuba.ac.jp/ と読み替えて下さい。

				新城
signcontrol.fj-org:
----------------------------------------------------------------------
#!/usr/local/bin/perl -w
# written April 1996, tale@isc.org (David C Lawrence)
# Version 1.3
#
# Changes from 1.2.3 to 1.3:
#  -- skip minor pgp signature headers like " charset:"  after " version:"  header
#     and until the empty line that starts the base64 signature block

# CONFIGURATION

# pgp variables.
# STORING YOUR PASS PHRASE IN A FILE IS A POTENTIAL SECURITY HOLE.
# make sure you know what you're doing if you do it.
# if you don't use pgppassfile, you can only use this script interactively.
$pgpsigner = " fj.news.announce" ;
#$pgppassfile = '';      # file with pass phrase for $pgpsigner
$pgp = " pgp" ;
$pgpheader = " X-PGP-Sig" ;

# this program is strict about always wanting to be consistent about
# what headers appear in the control messages.  the defaults for the
# @... arrays are reasonable, but you should edit the force values.

# these headers are acceptable in input,  but they will be overwritten
# with these values.  no sanity checking is done on what you put here.
# also, Subject: is forced to be the Control header prepending by " cmsg" .
# also, Newsgroups: is forced to be just the group being added/removed.
#                   (but is taken as-is for checkgroups)
$force{'Path'} = 'bounce-back';
$force{'From'} = 'committee@fj-news.org (Fj Newsgroups Management Committee)';
#$force{'Sender'} = 'committee@fj-news.org';
$force{'X-Info'}='ftp://ftp.isc.org/pub/pgpcontrol/README.html'
               . " \n\t" 
               . 'ftp://ftp.isc.org/pub/pgpcontrol/README';

# host for message-id; this could be determined automatically based on where
# it is run, but consistency is the goal here
$id_host = 'fj-news.org';

# how can a standards-compliant date header be generated?
# this gets substituted into a perl backtick expression,
# so be careful with the quoting.
# -0000 is hardcoded here as GMT/UTC zone because in some installations 
# the %Z flag does not work.
$get_date = " /bin/date -u '+%a, %d %h %Y %T -0000'" ;
$get_date_mid = " /bin/date -u '+%Y%m%d'" ;

# this expression works with SunOS 4's date; note that a formatted date string 
# is not used because it doesn't support four digit years
# $get_date = '/bin/date -u | /bin/awk \'{print $1 " ," , $3, $2, $6, $4, $5}\'';

# headers to sign.  Sender is included because non-PGP authentication uses it.
@signheaders = ('Subject', 'Control', 'Message-ID', 'Date', 'From', 'Sender');

# headers to remove from real headers of final message.
# If it is a signed header, it is signed with an empty value.
# set to () if you do not want any headers removed.
@ignoreheaders = ('Sender');
#@ignoreheaders = ();

# headers that will appear in final message, and their order of appearance.
# all _must_ be set, either in input or via $force{''} = value, above.
# (exceptions: Date, Lines, Message-ID are computed by the program)
# several are required by the news article format standard; if you remove
# these, your article will not propagate:
#   Path, From, Newsgroups, Subject, Message-ID, Date
# if you take out these, your control message is not very useful:
#   Control, Approved
# any headers here will not be removed even if in @ignoreheaders.
# any headers present but not in @orderheaders or @ignoreheaders is an error.
@orderheaders =
  ('Path', 'From', 'Newsgroups', 'Subject', 'Control', 'Approved',
   'Message-ID', 'Date', 'Lines', 'X-Info', $pgpheader);

# this program tries to help you out by not letting you sign erroneous names,
# especially ones that are so erroneous they run afoul of naming standards.
#
# set to match only hierarchies you will use it on
# include no '|' for a single hierarchy (eg, " $hierarchies = 'uk';" ).

$hierarchies = 'fj';

# the draft news article format standard says:
#   " subsequent components SHOULD begin with a letter" 
# where " SHOULD"  means:
#   means that the item is a strong recommendation: there may be
#   valid reasons to ignore it  in  unusual  circumstances,  but
#   this  should  be  done  only after careful study of the full
#   implications and a firm conclusion  that  it  is  necessary,
#   because  there are serious disadvantages to doing so. 
# as opposed to " MUST"  which means:
#   means that the item is an absolute requirement of the specification
# MUST is preferred, but might not be acceptable if you have legacy
# newsgroups that have name components that begin with a letter, like
# news.announce.newgrups does with comp.sys.3b1 and 17 other groups.

$start_component_with_letter = 'MUST';

## END CONFIGURATION

$0 =~ s#^.*/##;

die "Usage: $0  0;

& setgrouppat;

$die = '';

& readhead;
& readbody;

die $die if $die;

& signit;

exit 0;

sub
setgrouppat

{
  my ($hierarchy, $plain_component, $no_component);
  my ($must_start_letter, $should_start_letter);
  my ($eval);

  # newsgroup name checks based on RFC 1036bis (not including encodings) rules:
  #  " component MUST contain at least one letter" 
  #  " [component] MUST not contain uppercase letters" 
  #  " [component] MUST begin with a letter or digit" 
  #  " [component] MUST not be longer than 14 characters" 
  #  " sequences 'all' and 'ctl' MUST not be used as components" 
  #  " first component MUST begin with a letter" 
  # and enforcing " subsequent components SHOULD begin with a letter"  as MUST
  # and enforcing at least a 2nd level group (can't use to newgroup " general" )
  #
  # DO NOT COPY THIS PATTERN BLINDLY TO OTHER APPLICATIONS!
  #   It has special construction based on the pattern it is finally used in.

  $plain_component = '[a-z][-+_a-z\d]{0,13}';
  $no_component = '(.*\.)?(all|ctl)(\.|$)';
  $must_start_letter = '(\.' . $plain_component . ')+';
  $should_start_letter = '(\.(?=\d*[a-z])[a-z\d]+[-+_a-z\d]{0,13})+';

  $grouppat = " (?!$no_component)($hierarchies)" ;
  if ($start_component_with_letter eq 'SHOULD') {
    $grouppat .= $should_start_letter;
  } elsif ($start_component_with_letter eq 'MUST') {
    $grouppat .= $must_start_letter;
  } else {
    die " $0: unknown value configured for \$start_component_with_letter\n" ;
  }

  foreach $hierarchy (split(/\|/, $hierarchies)) {
    die " $0: hierarchy name $hierarchy not standards-compliant\n" 
      if $hierarchy !~ /^$plain_component$/o;
  }

  $eval = " \$_ = 'test'; /$grouppat/;" ;
  eval $eval;
  die " $0: bad regexp for matching group names:\n $@"  if $@;
}

sub
readhead

{
  my($head, $label, $value);
  local($_, $/);

  $/ = " " ;
  $head = ;              # get the whole news header
  $die .= " $0: continuation lines in headers not allowed\n" 
    if $head =~ s/\n[ \t]+/ /g; # rejoin continued lines

  for (split(/\n/, $head)) {
    if (/^(\S+): (.*)/) {
      $label = $1;
      $value = $2;

      $die .= " $0: duplicate header $label\n"  if $header{$label};

      $header{$label} = $value;
      $header{$label} =~ s/^\s+//;
      $header{$label} =~ s/\s+$//;
    } elsif (/^$/) {
      ;                           # the empty line separator(s)
    } else {
      $die .= " $0: non-header line:\n  $_\n" ;
    }
  }

#  $header{'Message-ID'} = '";
  $header{'Date'} = `$get_date`;
  chop($header{'Date'}) if $header{'Date'};

  for (@ignoreheaders) {
    $die .= " ignored header $_ also has forced value set\n"  if $force{$_};
    $header{$_} = '';
  }

  for (@orderheaders) {
    $header{$_} = $force{$_} if defined($force{$_});
    next if /^(Lines|\Q$pgpheader\E)$/; # these are set later
    $die .= " $0: missing $_ header\n"  unless $header{$_};
  }

  if ($header{'Control'}) {
    if ($header{'Control'} =~ /^(new)group (\S+)( moderated)?$/o ||
        $header{'Control'} =~ /^(rm)group (\S+)()$/o ||
        $header{'Control'} =~ /^(check)groups()()$/o) {
      ($action, $group, $moderated) = ($1, $2, $3);
      $die .= " $0: group name $group is not standards-compliant\n" 
        if $group !~ /^$grouppat$/ & &  $action eq 'new';
      $die .= " $0: no group to rmgroup on Control: line\n" 
        if ! $group & &  $action eq 'rm';
      $header{'Subject'} = " cmsg $header{'Control'}" ;
      $header{'Newsgroups'} = $group unless $action eq 'check';
    } else {
      $die .= " $0: bad Control format: $header{'Control'}\n" ;
    }
  } else {
    $die .= " $0: can't verify message content; missing Control header\n" ;
  }
  $date_mid = `$get_date_mid` ;
  chop($date_mid);
  if ($header{'Control'} =~ /^(newgroup) (\S+)/o ||
      $header{'Control'} =~ /^(rmgroup) (\S+)/o )
  {
      $mid = $1 .  " ."  . $2 . " ."  . $date_mid ;
  }
  if ( $header{'Control'} =~ /^(checkgroups)/o) {
      $mid = " checkgroups.fj."  . $date_mid ;
  }
  $header{'Message-ID'} = '";
}

sub
readbody

{
  local($_, $/);
  local($status, $ngline, $fixline, $used, $desc, $mods);

  undef $/;
  $body = $_ = ;
  $header{'Lines'} = $body =~ tr/\n/\n/;

  return unless $group;

  # the following tests are based on the structure of a news.announce.newgroups
  # newgroup message; even if you comment out the " first line"  test, please
  # leave the newsgroups line and moderators checks
  if ($action eq 'new') {
    $status = $moderated ? 'a\smoderated' : 'an\sunmoderated';
#    $die .= " $0: nonstandard first line in body\n" 
#      if ! /^\Q$group\E\sis\s$status\snewsgroup\b/;

    $ngline =
      (/^For your newsgroups file:\n\Q$group\E[ \t]+(.+)\n(\n|\Z(?!\n))/mi)[0];
    if ($ngline) {
      $_ = $group;
      $desc = $1;
      $fixline = $_;
      $fixline .= "\t" x ((length) >  23 ? 1 : (4 - ((length) + 1) / 8));
      $used = (length) <  24 ? 24 : (length) + (8 - (length) % 8);
      $used--;
      $desc =~ s/ \(Moderated\)//i;
      $desc =~ s/\s+$//;
      $desc =~ s/\w$/$& ./;
      $die .= "$0: $_ description too long\n" if $used + length($desc) >  80;
      $fixline .= $desc;
      $fixline .= ' (Moderated)' if $moderated;
      $body =~ s/^(For your newsgroups file:\n)(.+)/$1$fixline/i;
    } else {
      $die .= " $0: newsgroup line not formatted correctly\n" ;
    }
    if ($moderated) {
      $die .= " $0: Group submission address not formatted correctly\n" 
        if $body !~ /\nGroup submission address:   ?\S+@\S+\.\S+\n/m;
      $mods = " ( |\n[ \t]+)\\([^)]+\\)\n\n" ;
      $die .= " $0: Moderator contact address not formatted correctly\n" 
        if $body !~ /\nModerator contact address:  ?\S+@\S+\.\S+$mods/m;
    }
  }
  # rmgroups have freeform bodies

  # checkgroups have structured bodies, but I have not coded this for lack
  # of time.  i probably should do it.
}

sub
signit

{
  my($tmp, $head, $header, $signheaders, $pgpflags, $pgpbegin, $pgpend);
  local(*FH);

  $tmp = " /tmp/sign-$$" ;
  $signheaders = join(" ," , @signheaders);

  $head = " X-Signed-Headers: $signheaders\n" ;
  foreach $header (@signheaders) {
    $head .= " $header: $header{$header}\n" ;
  }
  open(FH, ">  $tmp") || die "$0: open $tmp: !$\n";
  print FH $head;
  print FH " \n" ;
  print FH $body;
  close(FH) || warn " $0: close TMP: $!\n" ;
  die " $0: data to sign corrupted in $tmp\n" 
    if -s $tmp != length($head) + length($body) + 1;

  if ($pgppassfile & &  -f $pgppassfile) {
    $ENV{'PGPPASS'} = `cat "$pgppassfile" 2> /dev/null`;
    chomp $ENV{'PGPPASS'} if $ENV{'PGPPASS'};
    # if PGPPASS is not now set and non-null, it will be prompted for by pgp
  }

  # -f = write to stdout
  # -a = ciphertext file in ASCII radix-64 format
  # -s = sign the plaintext file
  # -t = plaintext file contains ASCII text, not binary, and
  #      should be converted to recipient's local text line conventions
  # -u = userid to use to sign
  # +verbose=0 = only print errors on stderr
  open(FH, "$pgp -fast -u $pgpsigner +verbose=0 /dev/null |") ||
    die " $0: open pipe from pgp: $!\n" ;
  
  $pgpbegin = " -----BEGIN PGP SIGNATURE-----" ;
  $/ = " $pgpbegin\n" ;
  $_ = ;                         # read to signature, discard
  die " $0: $pgpbegin not found\n"  unless /\Q$pgpbegin\E$/;

  # make sure the temp file goes away even if we die now
  unlink($tmp) || warn " $0: unlink $tmp: $!\n" ;

  # finish getting the signature
  $/ = " \n" ;
  $_ = ;
  die " $0: didn't find PGP Version line where expected\n" 
    unless /^Version: (\S+)$/;
  $header{$pgpheader} = " $1 $signheaders" ;

  do {                # skip other pgp headers like " charset:"  until empty line
    $_ = ;        # ... is charset significant to this application?
  } while ! /^$/;

  while () {
    chomp;
    $pgpend = '-----END PGP SIGNATURE-----';
    last if /^\Q$pgpend\E$/;
    $header{$pgpheader} .= " \n\t$_" ;
  }
  $_ = ;
  die " $0: unexpected data following $pgpend\n"  unless eof(FH);
  close(FH) || warn " $0: close pipe from pgp returned status $?\n" ;

  $head = '';
  foreach $header (@orderheaders) {
    $head .= " $header: $header{$header}\n" ;
    delete $header{$header};
  }

  for (@ignoreheaders) {
    delete $header{$_} if defined $header{$_};
  }
  foreach $header (keys %header) {
    die " $0: unexpected header $header left in header array\n" ;
  }

  print STDOUT $head;
  print STDOUT " \n" ;
  print STDOUT $body;
}

exit 0;

# Our lawyer told me to include the following.  The upshot of it is
# that you can use the software for free as much as you like.

# Copyright (c) 1996 UUNET Technologies, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by UUNET Technologies, Inc.
# 4. The name of UUNET Technologies (" UUNET" ) may not be used to endorse or
#    promote products derived from this software without specific prior
#    written permission.
#
# THIS SOFTWARE IS PROVIDED BY UUNET ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL UUNET BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.

Next
Continue