implement tests (and looser constraints on) peer names for peers who are clients
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 14 Nov 2010 08:07:44 +0000 (03:07 -0500)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 14 Nov 2010 08:08:30 +0000 (03:08 -0500)
Changelog
Crypt/Monkeysphere/MSVA.pm
tests/basic

index df1a6e79ded5fc34d958305f88a572a5260e307f..82c10489ddeb211e30870b834d282c417055a106 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -11,11 +11,14 @@ msva-perl (0.6~pre) upstream;
   * fixed double-prompting on sites that have more than one User ID
     (closes MS #2567)
   * report server implementation name and version with every query (closes
-    MS # 2564)
+    MS #2564)
   * support x509pem, opensshpubkey, and rfc4716 PKC formats in addition to
     x509der (addresses MS #2566)
+  * add new peer type categorization (closes MS #2568) -- peers of type
+    client can have much more flexible names than regular hostnames we
+    look for for servers.
 
- -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Fri, 29 Oct 2010 03:48:50 -0400
+ -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Sun, 14 Nov 2010 03:04:13 -0500
 
 msva-perl (0.5) upstream;
 
index 507bafe5a6b52fb56ce6156a1b016e3f5a3ec321..792008637f11c7564f58e5b2e3ea4079c0ace554 100755 (executable)
     $data->{peer} = { name => $data->{peer} }
       if (ref($data->{peer}) ne 'HASH');
 
-    if ($data->{peer}->{name} =~ /^($RE{net}{domain})$/) {
-       $data->{peer}->{name} = $1;
-    } else {
-       msvalog('error', "invalid peer name string: %s\n", $data->{peer}->{name});
-       $ret->{message} = sprintf("Invalid peer name string: %s", $data->{peer}->{name});
-       return $status,$ret;
-    }
     if (defined($data->{peer}->{type})) {
       if ($data->{peer}->{type} =~ /^(client|server|peer)$/) {
         $data->{peer}->{type} = $1;
       }
     }
 
-    msvalog('verbose', "peer: %s\n", $data->{peer}->{name});
-
-    # generate uid string
     my $prefix = $data->{context}.'://';
     if (defined $data->{peer}->{type} &&
         $data->{peer}->{type} eq 'client' &&
         # exclude them:
         $data->{context} !~ /^(ike|smtp)$/) {
       $prefix = '';
+      # clients can have any one-line User ID without NULL characters
+      # and leading or trailing whitespace
+      if ($data->{peer}->{name} =~ /^([^[:space:]][^\n\0]*[^[:space:]]|[^\0[:space:]])$/) {
+        $data->{peer}->{name} = $1;
+      } else {
+        msvalog('error', "invalid client peer name string: %s\n", $data->{peer}->{name});
+        $ret->{message} = sprintf("Invalid client peer name string: %s", $data->{peer}->{name});
+        return $status, $ret;
+      }
+    } elsif ($data->{peer}->{name} =~ /^($RE{net}{domain})$/) {
+      $data->{peer}->{name} = $1;
+    } else {
+      msvalog('error', "invalid peer name string: %s\n", $data->{peer}->{name});
+      $ret->{message} = sprintf("Invalid peer name string: %s", $data->{peer}->{name});
+      return $status,$ret;
     }
+
+    msvalog('verbose', "peer: %s\n", $data->{peer}->{name});
+
+    # generate uid string
     my $uid = $prefix.$data->{peer}->{name};
     msvalog('verbose', "user ID: %s\n", $uid);
 
index 8605b132ad0228ece111b9b804ff621f79f2624c..525aa6d19581dc6f289b7b14dff1c94dbb131e71 100755 (executable)
@@ -60,10 +60,23 @@ for name in x y z ; do
     ssh-keygen -e -P '' -f "${WORKDIR}/sec/${name}.key" > "${WORKDIR}/pkc/${name}.rfc4716"
 done
 
+# make 2 client certs (A and B) with self-signed certs
+for name in a b ; do 
+    openssl req -x509 -subj "/eMail=${name}@example.net/CN=${name}/" -nodes -sha256 -newkey rsa:1024 -keyout "${WORKDIR}/sec/${name}.key" -outform DER -out "${WORKDIR}/pkc/${name}.x509der"
+    chmod 0400  "${WORKDIR}/sec/${name}.key"
+    openssl x509 -inform DER -outform PEM < "${WORKDIR}/pkc/${name}.x509der" > "${WORKDIR}/pkc/${name}.x509pem"
+    ssh-keygen -y -P '' -f "${WORKDIR}/sec/${name}.key" > "${WORKDIR}/pkc/${name}.opensshpubkey"
+    ssh-keygen -e -P '' -f "${WORKDIR}/sec/${name}.key" > "${WORKDIR}/pkc/${name}.rfc4716"
+done
+
 # translate X and Y's keys into OpenPGP cert
 for name in x y; do
     PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "https://${name}.example.net" < "${WORKDIR}/sec/${name}.key" | gpg --import
 done
+# and the same for the clients A and B
+for name in a b; do
+    PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "${name} <${name}@example.net>" < "${WORKDIR}/sec/${name}.key" | gpg --import
+done
 
 runtests() {
     # X should not validate as X or Y or Z:
@@ -72,9 +85,16 @@ runtests() {
             ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "${name}.example.net" "${ctype}" < "${WORKDIR}/pkc/x.${ctype}"
         done
     done
+    # A shouldn't validate as A or B:
+    for name in a b; do
+        for ctype in $CERTTYPES; do
+            ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "${name} <${name}@example.net>" "${ctype}" client < "${WORKDIR}/pkc/a.${ctype}"
+        done
+    done
     
-    # certify X's OpenPGP cert with CA
+    # certify X and A's OpenPGP cert with CA
     gpg --batch --yes --sign-key https://x.example.net
+    gpg --batch --yes --sign-key a@example.net
 
     echo "Testing bad data:"
     # it should fail if we pass it the wrong kind of data:
@@ -85,11 +105,14 @@ runtests() {
     for ctype in $CERTTYPES; do 
     # X should now validate as X
         "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https x.example.net "${ctype}" < "${WORKDIR}/pkc/x.${ctype}"
+        "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https 'a <a@example.net>' "${ctype}" client < "${WORKDIR}/pkc/a.${ctype}"
         
     # but X should not validate as Y or Z:
         for name in x y z; do
             ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "${name}.example.net" "${ctype}" < "${WORKDIR}/pkc/x.${ctype}"
         done
+        # and A shouldn't validate as B:
+        ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "b <b@example.net>" "${ctype}" client < "${WORKDIR}/pkc/a.${ctype}"
 
     # neither Y nor Z should validate as any of them:
         for src in y z; do
@@ -97,6 +120,8 @@ runtests() {
                 ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "${targ}.example.net" "${ctype}" < "${WORKDIR}/pkc/${src}.${ctype}"
             done
         done
+        # B should also still not validate as itself:
+        ! "${srcdir}"/test-msva msva-perl "${srcdir}"/test-msva msva-query-agent https "b <b@example.net>" "${ctype}" client < "${WORKDIR}/pkc/b.${ctype}"
     done
 }