What: The ability for the director to validate a Client (FD) CN against
        an arbitrary set of patterns (cf. TLS Allowed CN options for
        clients), rather than the hostname.

Why: DNS is not secure. Also, computers may move to new networks, and
        local policy may tie hostnames to a physical location. For
        example, in UPenn's school of Engineering, hostnames are of the
        form building-room.seas.upenn.edu. When someone changes offices,
        their hostname changes.

Notes: The following patch (written for 2.0.2, but also applies cleanly
to 2.0.3) implements this feature. If "TLS Allowed CN" clauses are
provided in the Client{} stanza, then pattern matching is used in place
of hostname matching against the Certificate's CN. As an example, we
have certificates which (a) use a local CA, and (b) have a CN of the
form "client_123". A client's stanza in the director's config file may
read like this:

Client {
  Name = "client_123"
  Address = fqdn.example.com
  FDPort = 9102
  Catalog = MyCatalog
  Password = "** some password here **"
  File Retention = 30 days
  Job Retention = 60 days
  AutoPrune = yes
  TLS Require = yes
  TLS CA Certificate File = /usr/local/etc/bacula.d/ca.crt
  TLS Certificate = /usr/local/etc/bacula.d/client.crt
  TLS Key = /usr/local/etc/bacula.d/client.key
  TLS Allowed CN = "client_123"
}

... note that you would not want to use this feature with public CAs,
since there would be no guarantee that another certificate with that CN
had not been issued.

Additionally, UPenn/SEAS is planning for the future. Our client machines
are increasingly mobile (laptops instead of desktops). We're migrating
to Bacula from a home-grown backup system which had plans for mobile
backups. The client "phones home" to the director, which updates its IP
address for that client, and then backs it up at its new location.
Adding a TLS Allowed CN option for the director to validate clients
allows this sort of flexible certificate validation for future Bacula
features (whether or not this will be one of them is not my focus here).

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Jorj Bauer                                  |       [EMAIL PROTECTED]
IT Director                                 |         3330 Walnut St.
School of Engineering and Applied Science   |    Levine Building, Room 160
University of Pennsylvania                  |     Philadelphia, PA 19104
http://www.jorj.org/                        | O: 215/898-0575 F: 215/898-1195
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


diff --recursive -u bacula-2.0.2/src/console/authenticate.c 
bacula-2.0.2.patched/src/console/authenticate.c
--- bacula-2.0.2/src/console/authenticate.c     2006-11-21 15:14:46.000000000 
-0500
+++ bacula-2.0.2.patched/src/console/authenticate.c     2007-02-16 
15:06:23.000000000 -0500
@@ -127,7 +127,7 @@
    if (have_tls) {
       if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
          /* Engage TLS! Full Speed Ahead! */
-         if (!bnet_tls_client(tls_ctx, dir)) {
+         if (!bnet_tls_client(tls_ctx, dir, NULL)) {
             sendit(_("TLS negotiation failed\n"));
             goto bail_out;
          }
diff --recursive -u bacula-2.0.2/src/dird/authenticate.c 
bacula-2.0.2.patched/src/dird/authenticate.c
--- bacula-2.0.2/src/dird/authenticate.c        2006-11-21 08:20:08.000000000 
-0500
+++ bacula-2.0.2.patched/src/dird/authenticate.c        2007-02-16 
15:12:13.000000000 -0500
@@ -131,7 +131,7 @@
    /* Is TLS Enabled? */
    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
-      if (!bnet_tls_client(store->tls_ctx, sd)) {
+      if (!bnet_tls_client(store->tls_ctx, sd, NULL)) {
          stop_bsock_timer(tid);
          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with SD on 
\"%s:%d\"\n"),
             sd->host, sd->port);
@@ -235,7 +235,8 @@
    /* Is TLS Enabled? */
    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
-      if (!bnet_tls_client(client->tls_ctx, fd)) {
+      if (!bnet_tls_client(client->tls_ctx, fd, client->tls_allowed_cns)) {
+
          stop_bsock_timer(tid);
          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed with FD on 
\"%s:%d\".\n"),
               fd->host, fd->port);
diff --recursive -u bacula-2.0.2/src/dird/dird_conf.c 
bacula-2.0.2.patched/src/dird/dird_conf.c
--- bacula-2.0.2/src/dird/dird_conf.c   2006-12-22 10:40:15.000000000 -0500
+++ bacula-2.0.2.patched/src/dird/dird_conf.c   2007-02-16 21:44:51.000000000 
-0500
@@ -189,6 +189,7 @@
    {"tlscacertificatedir",  store_dir,       ITEM(res_client.tls_ca_certdir), 
0, 0, 0},
    {"tlscertificate",       store_dir,       ITEM(res_client.tls_certfile), 0, 
0, 0},
    {"tlskey",               store_dir,       ITEM(res_client.tls_keyfile), 0, 
0, 0},
+   {"tlsallowedcn",         store_alist_str, ITEM(res_client.tls_allowed_cns), 
0, 0, 0},
    {NULL, NULL, {0}, 0, 0, 0}
 };
 
@@ -1039,6 +1040,9 @@
       if (res->res_client.tls_keyfile) {
          free(res->res_client.tls_keyfile);
       }
+      if (res->res_client.tls_allowed_cns) {
+         delete res->res_client.tls_allowed_cns;
+      }
       break;
    case R_STORAGE:
       if (res->res_store.address) {
@@ -1301,6 +1305,7 @@
             Emsg1(M_ERROR_TERM, 0, _("Cannot find Client resource %s\n"), 
res_all.res_client.hdr.name);
          }
          res->res_client.catalog = res_all.res_client.catalog;
+         res->res_client.tls_allowed_cns = res_all.res_client.tls_allowed_cns;
          break;
       case R_SCHEDULE:
          /*
diff --recursive -u bacula-2.0.2/src/dird/dird_conf.h 
bacula-2.0.2.patched/src/dird/dird_conf.h
--- bacula-2.0.2/src/dird/dird_conf.h   2007-01-11 11:38:34.000000000 -0500
+++ bacula-2.0.2.patched/src/dird/dird_conf.h   2007-02-16 15:15:40.000000000 
-0500
@@ -254,6 +254,7 @@
    char *tls_ca_certdir;              /* TLS CA Certificate Directory */
    char *tls_certfile;                /* TLS Client Certificate File */
    char *tls_keyfile;                 /* TLS Client Key File */
+   alist *tls_allowed_cns;            /* TLS Allowed Clients */
    TLS_CONTEXT *tls_ctx;              /* Shared TLS Context */
    bool tls_enable;                   /* Enable TLS */
    bool tls_require;                  /* Require TLS */
diff --recursive -u bacula-2.0.2/src/filed/authenticate.c 
bacula-2.0.2.patched/src/filed/authenticate.c
--- bacula-2.0.2/src/filed/authenticate.c       2006-12-17 07:42:56.000000000 
-0500
+++ bacula-2.0.2.patched/src/filed/authenticate.c       2007-02-16 
15:08:36.000000000 -0500
@@ -263,7 +263,7 @@
 
    if (have_tls && tls_local_need >= BNET_TLS_OK && tls_remote_need >= 
BNET_TLS_OK) {
       /* Engage TLS! Full Speed Ahead! */
-      if (!bnet_tls_client(me->tls_ctx, sd)) {
+      if (!bnet_tls_client(me->tls_ctx, sd, NULL)) {
          Jmsg(jcr, M_FATAL, 0, _("TLS negotiation failed.\n"));
          auth_success = false;
          goto auth_fatal;
diff --recursive -u bacula-2.0.2/src/lib/bnet.c 
bacula-2.0.2.patched/src/lib/bnet.c
--- bacula-2.0.2/src/lib/bnet.c 2006-11-21 11:13:57.000000000 -0500
+++ bacula-2.0.2.patched/src/lib/bnet.c 2007-02-16 16:17:11.000000000 -0500
@@ -493,7 +493,7 @@
  * Returns: true  on success
  *          false on failure
  */
-bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
+bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
 {
    TLS_CONNECTION *tls;
 
@@ -510,7 +510,14 @@
       goto err;
    }
 
-   if (!tls_postconnect_verify_host(tls, bsock->host)) {
+   if (verify_list) {
+      if (!tls_postconnect_verify_cn(tls, verify_list)) {
+         Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS certificate verification failed."
+                                         " Peer certificate did not match a 
required commonName\n"),
+                                         bsock->host);
+         goto err;
+      }
+   } else if (!tls_postconnect_verify_host(tls, bsock->host)) {
       Qmsg1(bsock->jcr, M_FATAL, 0, _("TLS host certificate verification 
failed. Host %s did not match presented certificate\n"), bsock->host);
       goto err;
    }
@@ -527,7 +534,7 @@
    Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enabled but not configured.\n"));
    return false;
 }
-bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock)
+bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list, int 
verify_hostname)
 {
    Jmsg(bsock->jcr, M_ABORT, 0, _("TLS enable but not configured.\n"));
    return false;
diff --recursive -u bacula-2.0.2/src/lib/protos.h 
bacula-2.0.2.patched/src/lib/protos.h
--- bacula-2.0.2/src/lib/protos.h       2006-12-03 04:00:00.000000000 -0500
+++ bacula-2.0.2.patched/src/lib/protos.h       2007-02-16 15:07:10.000000000 
-0500
@@ -85,7 +85,8 @@
 bool       bnet_sig              (BSOCK *bs, int sig);
 bool       bnet_tls_server       (TLS_CONTEXT *ctx, BSOCK *bsock,
                                   alist *verify_list);
-bool       bnet_tls_client       (TLS_CONTEXT *ctx, BSOCK *bsock);
+bool       bnet_tls_client       (TLS_CONTEXT *ctx, BSOCK *bsock,
+                                 alist *verify_list);
 BSOCK *    bnet_connect          (JCR *jcr, int retry_interval,
                int max_retry_time, const char *name, char *host, char *service,
                int port, int verbose);
diff --recursive -u bacula-2.0.2/src/wx-console/authenticate.c 
bacula-2.0.2.patched/src/wx-console/authenticate.c
--- bacula-2.0.2/src/wx-console/authenticate.c  2006-11-22 09:26:39.000000000 
-0500
+++ bacula-2.0.2.patched/src/wx-console/authenticate.c  2007-02-16 
15:09:36.000000000 -0500
@@ -138,7 +138,7 @@
    if (have_tls) {
       if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
          /* Engage TLS! Full Speed Ahead! */
-         if (!bnet_tls_client(tls_ctx, dir)) {
+         if (!bnet_tls_client(tls_ctx, dir, NULL)) {
             csprint(_("TLS negotiation failed\n"));
             goto bail_out;
          }

Attachment: pgpWUXK5YVZgw.pgp
Description: PGP signature

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Bacula-users mailing list
Bacula-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-users

Reply via email to