aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-05-08 17:36:16 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-05-08 18:39:16 +0300
commit0bda1e43269af186e0b61280410e4630d67c5fcb (patch)
tree1c135053161351bc3ca61f2d85c7b4733f3f8386
parent0be7b61b12b6cefa91e01065046975e71245b8ea (diff)
Add support for certificate name subdomain wildcard
-rw-r--r--bpkg/auth.cxx85
-rwxr-xr-xtests/auth/cert9
-rw-r--r--tests/auth/self-any-cert.pem30
-rw-r--r--tests/auth/self-any-openssl.cnf22
-rw-r--r--tests/auth/self-cert.pem30
-rw-r--r--tests/auth/self-openssl.cnf22
-rw-r--r--tests/auth/subdomain-cert.pem30
-rw-r--r--tests/auth/subdomain-openssl.cnf22
-rw-r--r--tests/rep-auth.test152
9 files changed, 392 insertions, 10 deletions
diff --git a/bpkg/auth.cxx b/bpkg/auth.cxx
index b60e998..ddbb284 100644
--- a/bpkg/auth.cxx
+++ b/bpkg/auth.cxx
@@ -653,18 +653,83 @@ namespace bpkg
f = *conf / certs_dir / path (cert.fingerprint + ".pem");
}
- const string& c (cert.name);
- const string& r (rl.canonical_name ());
- const size_t cn (c.size ());
- const size_t rn (r.size ());
+ // Make sure that the repository canonical name hostname matches the
+ // certificate hostname (that can contain a subdomain wildcard), and its
+ // optional /prefix/path (will call it just path down the road) part is a
+ // subpath of the certificate name path.
+ //
+ // Split a name into the host and path parts.
+ //
+ auto split = [] (const string& name) -> pair<string, path>
+ {
+ size_t p (name.find ('/'));
+ return make_pair (name.substr (0, p),
+ p != string::npos ? path (name.substr (p)) : path ());
+ };
- // Make sure the names are either equal or the certificate name is a
- // prefix (at /-boundary) of the repository name.
+ pair<string, path> c (split (cert.name));
+ pair<string, path> r (split (rl.canonical_name ()));
+
+ // Match host names.
+ //
+ // The certificate hostname, that contains a subdomain wildcards, can have
+ // one of the following forms:
+ //
+ // *.example.com - matches any single-level subdomain of example.com
+ // **.example.com - matches any subdomain of example.com
+ // *example.com - matches example.com and any its single-level subdomain
+ // **example.com - matches example.com and any its subdomain
//
- if (!(r.compare (0, cn, c) == 0 &&
- (rn == cn || (rn > cn && r[cn] == '/'))))
- fail << "certificate name mismatch for repository " << r <<
- info << "certificate name is " << c;
+ bool match (false);
+ {
+ string& ch (c.first);
+ const string& rh (r.first);
+
+ if (ch[0] == '*') // Subdomain wildcard.
+ {
+ size_t p (1);
+
+ bool any (ch[p] == '*');
+ if (any)
+ ++p;
+
+ bool self (ch[p] != '.');
+ if (!self)
+ ++p;
+
+ ch = ch.substr (p); // Strip wildcard prefix.
+
+ const size_t cn (ch.size ());
+ const size_t rn (rh.size ());
+
+ // If hostnames are equal, then the repository hostname matches the
+ // certificate hostname if self-matching is allowed. Otherwise, it
+ // matches being a subdomain of the first level, or any level if
+ // allowed.
+ //
+ if (rh == ch)
+ match = self;
+ else if (rn > cn && rh.compare (p = rn - cn, cn, ch) == 0 &&
+ rh[p - 1] == '.')
+ match = any || rh.find ('.') == p - 1;
+ }
+ else
+ // If the certificate hostname doesn't contain a subdomain wildcard,
+ // then the repository hostname must match it exactly.
+ //
+ match = rh == ch;
+ }
+
+ // Match the repository canonical name path part (must be a subpath of the
+ // certificate name path).
+ //
+ if (match)
+ match = r.second.sub (c.second);
+
+ if (!match)
+ fail << "certificate name mismatch for repository "
+ << rl.canonical_name () <<
+ info << "certificate name is " << cert.name;
try
{
diff --git a/tests/auth/cert b/tests/auth/cert
index 41b3b9c..5cb1237 100755
--- a/tests/auth/cert
+++ b/tests/auth/cert
@@ -16,6 +16,15 @@ openssl req -x509 -new -key key.pem -days 1825 -config mismatch-openssl.cnf > \
openssl req -x509 -new -key key.pem -days 1825 -config noemail-openssl.cnf > \
noemail-cert.pem
+openssl req -x509 -new -key key.pem -days 1825 \
+ -config subdomain-openssl.cnf > subdomain-cert.pem
+
+openssl req -x509 -new -key key.pem -days 1825 -config self-openssl.cnf > \
+ self-cert.pem
+
+openssl req -x509 -new -key key.pem -days 1825 -config self-any-openssl.cnf > \
+ self-any-cert.pem
+
# Normally, you have no reason to regenerate expired-cert.pem, as need to keep
# it expired for the testing purposes. But if you do, copy expired-cert.pem
# content to the certificate value of the following manifest files:
diff --git a/tests/auth/self-any-cert.pem b/tests/auth/self-any-cert.pem
new file mode 100644
index 0000000..88553c0
--- /dev/null
+++ b/tests/auth/self-any-cert.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFMzCCAxugAwIBAgIJAL6WhYgIDFucMA0GCSqGSIb3DQEBCwUAMDUxFzAVBgNV
+BAoMDkNvZGUgU3ludGhlc2lzMRowGAYDVQQDDBFuYW1lOioqYnVpbGQyLm9yZzAe
+Fw0xNzA1MDgxNDA4NTlaFw0yMjA1MDcxNDA4NTlaMDUxFzAVBgNVBAoMDkNvZGUg
+U3ludGhlc2lzMRowGAYDVQQDDBFuYW1lOioqYnVpbGQyLm9yZzCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBANq78SXuzFzCMoFU1RnzEeAfzE0UUYGynS3F
+2lG7viH3coxjLt+BrFBudVs4XDTpjXS19hRxIohEgD71W1jhDvmUC9yCMW13PCII
+jRKTTz0efEhTcMHdhOgvKZsje0IV7svoKVXcG7DfUVl51wWPQPSbUrfsQbsXg7Pz
+5HaDx+Dt2i9hwdE1M0z4R2dtwQkszFyCKiX8RF9oPXirTz5ETLC3f19JUapLrY5l
+5ZylzQifLhPMlHLlrT0n7KkohH7waX3KyeLa0M2IIl3zaeAsuN+ErFVecAdlJIvX
+00cth2OO/Gxy09sIKlagi2q7ZDik2sMvG8dAv7gNZsXp+FOj/XXCiOI9f6D5ospJ
+dK9B5UCABjmGc8W5Odv6ZLey5Ui76luI7ciITOKfAoEkbyMiNHiRxLdM7aAeizdc
+wHU4bm6JlmiJk8UyyV85f33mvCSfuo7D+DQYiK650/xwRdTFBIqi38IwME62gT7a
+h/AOmiPshj7FjwIU7ZWHskyr9qpExQOEKJXoLZJo1rf6MRc8AsJyz6zdfQhT1BTz
+hogNfru4xjVM6fSrjRUF34msuWcz/HKo9W350Aw2y5F59kziP+m7G6uBYrqmElv/
+13Vamg2ZZ1b38KMz5Ss3SkfcDErOzz/D+0hRlOaCIeWts1G2zWcQvBnn+zGA+sTI
+u0xAFOCRAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggr
+BgEFBQcDAzAaBgNVHREEEzARgQ9pbmZvQGJ1aWxkMi5vcmcwDQYJKoZIhvcNAQEL
+BQADggIBAMkex3gIuU2G1kDg57PG2H188pDU0lRQzkC3KTy8o0n5gwH5ZPAN6hYb
+BauJj92sRYLwGP57TWPqgVwFQWYQSXQTP5mu8RbIfW6nxK88mwcHj0nne8fdO14Y
+FJms52uvuq+delypw0+pnsUUgt3MkVf+9hVhJlxxpEAH9rhJ4roSdNdvuB0JnjgE
+eKUX+9Vyptch4krlUrTrFm6aSBEm8NzI1OAsTmOLtrB59xkLTKej14YNUq09kyVA
+JsueKlXSHtHO3CxisoFWHfczonSbIJpOUJn3DDZDZ4UPft2dD+oyW3zMrDoXczKm
+DI+CTSvSqWVpwiUTHsO2IO+XI50HHZCCoMF0or3Gg0zyq9+Dj9yX7VAUeqxV2jIw
+ZvCm//k/zveCmJZrhW4doKNy0AudnSRwzufcFLVI0H6ID/q/Udb5g5J1eYXrLJRo
+V3pfY/HhtTZ3wYT2uTd+++NHSmoXud/w3hPHnHQ4zuw+6Qpb0QhyBSODNarMzxBX
+aT1KHZcF6OW/90932nesY+4IIzYHzVrWfBnR23GaXRPhfnnYneCVB5SsUhY5kEGa
+NjQDXtwFGNxiFd60nFtU7PFUVLSNx6MRy09+8XyUu4mg2smCZyDoSzKFTICaU0Gq
+vQ5Nhvg8bdSTkBJyOKPD8SNyxWs3Bdk9XyZnpCKssz1KnUk9y+VA
+-----END CERTIFICATE-----
diff --git a/tests/auth/self-any-openssl.cnf b/tests/auth/self-any-openssl.cnf
new file mode 100644
index 0000000..c0d72eb
--- /dev/null
+++ b/tests/auth/self-any-openssl.cnf
@@ -0,0 +1,22 @@
+repository = **build2.org
+company = Code Synthesis
+email = info@build2.org
+
+
+[ req ]
+
+distinguished_name = req_distinguished_name
+x509_extensions = v3_req
+prompt = no
+utf8 = yes
+
+[ req_distinguished_name ]
+
+O = $company
+CN = name:$repository
+
+[ v3_req ]
+
+keyUsage = critical,digitalSignature
+extendedKeyUsage = critical,codeSigning
+subjectAltName = email:$email
diff --git a/tests/auth/self-cert.pem b/tests/auth/self-cert.pem
new file mode 100644
index 0000000..1553a2a
--- /dev/null
+++ b/tests/auth/self-cert.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFMTCCAxmgAwIBAgIJAJlKDlkC6IwmMA0GCSqGSIb3DQEBCwUAMDQxFzAVBgNV
+BAoMDkNvZGUgU3ludGhlc2lzMRkwFwYDVQQDDBBuYW1lOipidWlsZDIub3JnMB4X
+DTE3MDUwODE0MDg1OVoXDTIyMDUwNzE0MDg1OVowNDEXMBUGA1UECgwOQ29kZSBT
+eW50aGVzaXMxGTAXBgNVBAMMEG5hbWU6KmJ1aWxkMi5vcmcwggIiMA0GCSqGSIb3
+DQEBAQUAA4ICDwAwggIKAoICAQDau/El7sxcwjKBVNUZ8xHgH8xNFFGBsp0txdpR
+u74h93KMYy7fgaxQbnVbOFw06Y10tfYUcSKIRIA+9VtY4Q75lAvcgjFtdzwiCI0S
+k089HnxIU3DB3YToLymbI3tCFe7L6ClV3Buw31FZedcFj0D0m1K37EG7F4Oz8+R2
+g8fg7dovYcHRNTNM+EdnbcEJLMxcgiol/ERfaD14q08+REywt39fSVGqS62OZeWc
+pc0Iny4TzJRy5a09J+ypKIR+8Gl9ysni2tDNiCJd82ngLLjfhKxVXnAHZSSL19NH
+LYdjjvxsctPbCCpWoItqu2Q4pNrDLxvHQL+4DWbF6fhTo/11wojiPX+g+aLKSXSv
+QeVAgAY5hnPFuTnb+mS3suVIu+pbiO3IiEzinwKBJG8jIjR4kcS3TO2gHos3XMB1
+OG5uiZZoiZPFMslfOX995rwkn7qOw/g0GIiuudP8cEXUxQSKot/CMDBOtoE+2ofw
+Dpoj7IY+xY8CFO2Vh7JMq/aqRMUDhCiV6C2SaNa3+jEXPALCcs+s3X0IU9QU84aI
+DX67uMY1TOn0q40VBd+JrLlnM/xyqPVt+dAMNsuRefZM4j/puxurgWK6phJb/9d1
+WpoNmWdW9/CjM+UrN0pH3AxKzs8/w/tIUZTmgiHlrbNRts1nELwZ5/sxgPrEyLtM
+QBTgkQIDAQABo0YwRDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYB
+BQUHAwMwGgYDVR0RBBMwEYEPaW5mb0BidWlsZDIub3JnMA0GCSqGSIb3DQEBCwUA
+A4ICAQBhhZHfxie6sB6GO00NGBj+8Jcbg4CltB1hq2dFA3Ytx2VSFFl4bkq1jSff
+fciWh+GoVNmGIYnDok3Sdj+G5x6r53hn3zRZuZDK5CzAZ5fmagn/hgJpYhrbqCxz
+hXkuKJkxCQTLTiZOWRvdNZRu8cApNgVnlUKPcqiv7QEgAkGPqR+ZinmXzbYPDpmV
+PjP6r6jtpGMsFyIoO4N3iFgDneiV8MJHLyjSNoNddu9ylPcR9vwfmtOxMnlnr8lY
+za1AbJtkYsNJKuIZd5dvB47E1D8d4a7ZL5vIhmt9C9d+9gE80H4PZfXQJ+jPPGCl
+SUqbEFiZerRUgybfLtUppgFXtP855uXTKMR9GOeWCOEKWEklLVOmFmHO09OvpzTf
+MQSCnwV4d/rDYbIWA5w5FzlS4hB9q/SkY6JFPGu6lLfKvkMcCjIncIANDG2vtafg
+tDBTVF49GZmbCR6fSr+Rs/5TliTaRgj7GmZ8V75uIX/fSUFCklSrE1yT6WrrOsf2
+Jq4JpodZ6l+r+u993YJnp3o16r3nwpg6jVeWxI93x7JsdXxI9IRRelVoeQL44BWF
+zywo2GPwQfFTdFSOrKB7TrEgR0T+z0dKAJoI0S1lqxTxBleNSVmtBiicglxjFnqZ
+GvD6iu0+Z2aFqvfyquMjUWMfiRxioZ3altX+mj4hDjWvY6trQg==
+-----END CERTIFICATE-----
diff --git a/tests/auth/self-openssl.cnf b/tests/auth/self-openssl.cnf
new file mode 100644
index 0000000..a4a8fa8
--- /dev/null
+++ b/tests/auth/self-openssl.cnf
@@ -0,0 +1,22 @@
+repository = *build2.org
+company = Code Synthesis
+email = info@build2.org
+
+
+[ req ]
+
+distinguished_name = req_distinguished_name
+x509_extensions = v3_req
+prompt = no
+utf8 = yes
+
+[ req_distinguished_name ]
+
+O = $company
+CN = name:$repository
+
+[ v3_req ]
+
+keyUsage = critical,digitalSignature
+extendedKeyUsage = critical,codeSigning
+subjectAltName = email:$email
diff --git a/tests/auth/subdomain-cert.pem b/tests/auth/subdomain-cert.pem
new file mode 100644
index 0000000..40f7e90
--- /dev/null
+++ b/tests/auth/subdomain-cert.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFMzCCAxugAwIBAgIJAPEWdjQimVTMMA0GCSqGSIb3DQEBCwUAMDUxFzAVBgNV
+BAoMDkNvZGUgU3ludGhlc2lzMRowGAYDVQQDDBFuYW1lOiouYnVpbGQyLm9yZzAe
+Fw0xNzA1MDgxNDA4NTlaFw0yMjA1MDcxNDA4NTlaMDUxFzAVBgNVBAoMDkNvZGUg
+U3ludGhlc2lzMRowGAYDVQQDDBFuYW1lOiouYnVpbGQyLm9yZzCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBANq78SXuzFzCMoFU1RnzEeAfzE0UUYGynS3F
+2lG7viH3coxjLt+BrFBudVs4XDTpjXS19hRxIohEgD71W1jhDvmUC9yCMW13PCII
+jRKTTz0efEhTcMHdhOgvKZsje0IV7svoKVXcG7DfUVl51wWPQPSbUrfsQbsXg7Pz
+5HaDx+Dt2i9hwdE1M0z4R2dtwQkszFyCKiX8RF9oPXirTz5ETLC3f19JUapLrY5l
+5ZylzQifLhPMlHLlrT0n7KkohH7waX3KyeLa0M2IIl3zaeAsuN+ErFVecAdlJIvX
+00cth2OO/Gxy09sIKlagi2q7ZDik2sMvG8dAv7gNZsXp+FOj/XXCiOI9f6D5ospJ
+dK9B5UCABjmGc8W5Odv6ZLey5Ui76luI7ciITOKfAoEkbyMiNHiRxLdM7aAeizdc
+wHU4bm6JlmiJk8UyyV85f33mvCSfuo7D+DQYiK650/xwRdTFBIqi38IwME62gT7a
+h/AOmiPshj7FjwIU7ZWHskyr9qpExQOEKJXoLZJo1rf6MRc8AsJyz6zdfQhT1BTz
+hogNfru4xjVM6fSrjRUF34msuWcz/HKo9W350Aw2y5F59kziP+m7G6uBYrqmElv/
+13Vamg2ZZ1b38KMz5Ss3SkfcDErOzz/D+0hRlOaCIeWts1G2zWcQvBnn+zGA+sTI
+u0xAFOCRAgMBAAGjRjBEMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggr
+BgEFBQcDAzAaBgNVHREEEzARgQ9pbmZvQGJ1aWxkMi5vcmcwDQYJKoZIhvcNAQEL
+BQADggIBANBDUE7sch9rO99MOAjEoPCU9gVZcndaAcNbghfCbNpIyPPUq7R5+Jy/
+70kYkHV0JanFFUlB+O99TsLWCkNBcRSQ9sQHqqddyEdI+LN5GUwlXq/uCwF/AcDA
+fZjhnLhes3vDHXO5lLfN6K4pvQ+viF5V4qL1KIo4gYKO1dyuoBsGt+JqUJXS9QS3
+xWLEq4IF7iPZiFYJ+fnXL7J8cuNvflkf3EeOlpMPxo356hOYp0ND6/z8P9lQWAXs
+0NQWzW4hlL5Cm+YroX/su8+on2INvP3Nx9GW3nMFRuCYXmq6rYGSw6zGZbgv57JD
+vA5F3D1XkTe85rytJjsJaKjJAC+xHQl9yzkjyBMzJBLwio75i/4hlkrpKtet649n
+PrkEB3LU43LczZXXUKmAWsV8XOEssHdCSZQD+/oyzW6FcW2dHcNeXBxKn/we2/2E
+Ss0vuys0uQGPlfT0TlHSuvIoXNIPAqzAefA0h9R2sisazkTYoeu04wWAA/Crobv5
+/NssbZ04/sMY4eTrwP/IZOvgmrS+dZSaEr9kVTUu/TQLmRDTgUtwxS39C0eri4QY
+/1M0qGY4Wxji+MPDFGSgmsLj3vrmX3nlsan4fG466TCnIo4yVhYc2c9rmTqZ9u42
+CLoIN099hOYbfUueMBwtiLd7+544cGo1n2z+AnGePmHfoQYxDOqw
+-----END CERTIFICATE-----
diff --git a/tests/auth/subdomain-openssl.cnf b/tests/auth/subdomain-openssl.cnf
new file mode 100644
index 0000000..1c4f91c
--- /dev/null
+++ b/tests/auth/subdomain-openssl.cnf
@@ -0,0 +1,22 @@
+repository = *.build2.org
+company = Code Synthesis
+email = info@build2.org
+
+
+[ req ]
+
+distinguished_name = req_distinguished_name
+x509_extensions = v3_req
+prompt = no
+utf8 = yes
+
+[ req_distinguished_name ]
+
+O = $company
+CN = name:$repository
+
+[ v3_req ]
+
+keyUsage = critical,digitalSignature
+extendedKeyUsage = critical,codeSigning
+subjectAltName = email:$email
diff --git a/tests/rep-auth.test b/tests/rep-auth.test
index b2331aa..12815f9 100644
--- a/tests/rep-auth.test
+++ b/tests/rep-auth.test
@@ -43,6 +43,44 @@
cat <<<$cert_manifest >+$out/signed/repositories
$rc --key $key $out/signed &$out/signed/packages &$out/signed/signature
+ # Create the 'self-match' repository. Note that its certificate name is
+ # the '*build2.org' wildcard (matches build2.org and any single-level
+ # subdomain).
+ #
+ cp -r $src/unsigned $out/self-match
+
+ echo 'certificate: \' >+$out/self-match/repositories
+ cat <<<$src_base/auth/self-cert.pem >+$out/self-match/repositories
+ echo '\' >+$out/self-match/repositories
+
+ $rc --key $key $out/self-match &$out/self-match/packages \
+ &$out/self-match/signature
+
+ # Create the 'self-any-match' repository. Note that its certificate name is
+ # the '**build2.org' wildcard (matches build2.org and any subdomain).
+ #
+ cp -r $src/unsigned $out/self-any-match
+
+ echo 'certificate: \' >+$out/self-any-match/repositories
+ cat <<<$src_base/auth/self-any-cert.pem >+$out/self-any-match/repositories
+ echo '\' >+$out/self-any-match/repositories
+
+ $rc --key $key $out/self-any-match &$out/self-any-match/packages \
+ &$out/self-any-match/signature
+
+ # Create the 'subdomain-match' repository. Note that its certificate name is
+ # the '*.build2.org' wildcard (matches any single-level subdomain of
+ # build2.org).
+ #
+ cp -r $src/unsigned $out/subdomain-match
+
+ echo 'certificate: \' >+$out/subdomain-match/repositories
+ cat <<<$src_base/auth/subdomain-cert.pem >+$out/subdomain-match/repositories
+ echo '\' >+$out/subdomain-match/repositories
+
+ $rc --key $key $out/subdomain-match &$out/subdomain-match/packages \
+ &$out/subdomain-match/signature
+
# Create the 'name-mismatch' repository. Note that its certificate name
# mismatches the repository location.
#
@@ -278,6 +316,120 @@ sc = " " # Space character to append to here-document line when required.
$rep_info >'name:build2.org'
}
}
+
+ : subdomain-wildcard
+ :
+ {
+ rep_info += --auth all --trust-yes --cert-name
+
+ : self
+ :
+ {
+ : exact
+ :
+ $rep_info $rep/self-match >'name:*build2.org'
+
+ : subdomain
+ :
+ if ($remote != true)
+ {
+ : first-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/self-match $r;
+
+ $rep_info $r/self-match >'name:*build2.org'
+ }
+
+ : second-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/b.a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/self-match $r;
+
+ $rep_info $r/self-match 2>>EOE != 0
+ error: certificate name mismatch for repository b.a.build2.org/self-match
+ info: certificate name is *build2.org
+ EOE
+ }
+ }
+ }
+
+ : self-any
+ :
+ {
+ : exact
+ :
+ $rep_info $rep/self-any-match >'name:**build2.org'
+
+ : subdomain
+ :
+ if ($remote != true)
+ {
+ : first-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/self-any-match $r;
+
+ $rep_info $r/self-any-match >'name:**build2.org'
+ }
+
+ : second-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/b.a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/self-any-match $r;
+
+ $rep_info $r/self-any-match >'name:**build2.org'
+ }
+ }
+ }
+
+ : subdomain
+ :
+ {
+ : exact
+ :
+ $rep_info $rep/subdomain-match 2>>EOE != 0
+ error: certificate name mismatch for repository build2.org/rep-auth/subdomain-match
+ info: certificate name is *.build2.org
+ EOE
+
+ : subdomain
+ :
+ if ($remote != true)
+ {
+ : first-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/subdomain-match $r;
+
+ $rep_info $r/subdomain-match >'name:*.build2.org'
+ }
+
+ : second-level
+ :
+ {
+ r = $canonicalize([dir_path] $~/pkg/1/b.a.build2.org/);
+ mkdir -p $r;
+ cp -r $rep/subdomain-match $r;
+
+ $rep_info $r/subdomain-match 2>>EOE != 0
+ error: certificate name mismatch for repository b.a.build2.org/subdomain-match
+ info: certificate name is *.build2.org
+ EOE
+ }
+ }
+ }
+ }
}
: unsigned