]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Check for IP SANs when verifying TLS certs
authorMarcus Weinhold - umwerk systems GmbH <marcus.weinhold@umwerk-systems.com>
Sun, 19 Dec 2021 20:32:39 +0000 (21:32 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:04 +0000 (09:03 +0100)
According to RFC5280 [1], a TLS certificate can contain an IP address as
a subject alternative name (SAN). This patch extends the SAN check in
tls.c to consider such cases.

In my case, this is neccessary to get SDCallsClient to work in
conjunction with TLS client authentication. The FDs were rejecting
to connect to the SD, because the SD was reporting its IP address to the
FDs, not its FQDN. Hence I put the SD's IP address as an iPAddress SAN
to the SD's certificate, which is ignored by bacula (without this
patch).

An alternative solution to the problem would be putting the SD's IP as a
dNSName.

This is basically the same problem as described in [2] and should also
fix it, provided the certificates are issued with IP SANs.

References:
[1] https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.6
[2] https://sourceforge.net/p/bacula/mailman/bacula-users/thread/53F6F35B.6040305@informatik.uni-bonn.de/#msg32747985

bacula/src/lib/tls.c

index 84b62fbfe0c0ad17a38c28e79b250f730e612950..fdf280735e51c63f40146b31006f219fa6320fb3 100644 (file)
@@ -587,7 +587,7 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
             val = method->i2v(method, extstr, NULL);
 
             /* dNSName shortname is "DNS" */
-            Dmsg0(250, "Check DNS name\n");
+            Dmsg0(250, "Check DNS name / IP Address\n");
             for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
                nval = sk_CONF_VALUE_value(val, j);
                if (strcmp(nval->name, "DNS") == 0) {
@@ -604,6 +604,12 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
                      goto success;
                   }
                   Dmsg2(250, "No DNS name match. Host=%s cert=%s\n", host, nval->value);
+               } else if (strcmp(nval->name, "IP Address") == 0) {
+                  if (strcasecmp(nval->value, host) == 0) {
+                     auth_success = true;
+                     goto success;
+                  }
+                  Dmsg2(250, "No IP match. Host=%s cert=%s\n", host, nval->value);
                }
             }
          }