]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/console/authenticate.c
kes Change Bacula trademark owner from John Walker to Kern Sibbald
[bacula/bacula] / bacula / src / console / authenticate.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *
30  *   Bacula UA authentication. Provides authentication with
31  *     the Director.
32  *
33  *     Kern Sibbald, June MMI
34  *
35  *    This routine runs as a thread and must be thread reentrant.
36  *
37  *  Basic tasks done here:
38  *
39  */
40
41 #include "bacula.h"
42 #include "console_conf.h"
43 #include "jcr.h"
44
45
46 void senditf(const char *fmt, ...);
47 void sendit(const char *buf);
48
49 /* Commands sent to Director */
50 static char hello[]    = N_("Hello %s calling\n");
51
52 /* Response from Director */
53 static char OKhello[]   = N_("1000 OK:");
54
55 /* Forward referenced functions */
56
57 /*
58  * Authenticate Director
59  */
60 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
61 {
62    BSOCK *dir = jcr->dir_bsock;
63    int tls_local_need = BNET_TLS_NONE;
64    int tls_remote_need = BNET_TLS_NONE;
65    bool tls_needed;
66    bool tls_authenticate;
67    int compatible = true;
68    char bashed_name[MAX_NAME_LENGTH];
69    char *password;
70    TLS_CONTEXT *tls_ctx = NULL;
71
72    /*
73     * Send my name to the Director then do authentication
74     */
75    if (cons) {
76       bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
77       bash_spaces(bashed_name);
78       password = cons->password;
79       /* TLS Requirement */
80       if (cons->tls_enable) {
81          if (cons->tls_require) {
82             tls_local_need = BNET_TLS_REQUIRED;
83          } else {
84             tls_local_need = BNET_TLS_OK;
85          }
86       }
87       if (cons->tls_authenticate) {
88          tls_local_need = BNET_TLS_REQUIRED;
89       }
90       tls_authenticate = cons->tls_authenticate;
91       tls_needed = cons->tls_enable || cons->tls_authenticate;
92       tls_ctx = cons->tls_ctx;
93    } else {
94       bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
95       password = director->password;
96       /* TLS Requirement */
97       if (director->tls_enable) {
98          if (director->tls_require) {
99             tls_local_need = BNET_TLS_REQUIRED;
100          } else {
101             tls_local_need = BNET_TLS_OK;
102          }
103       }
104
105       if (director->tls_authenticate) {
106          tls_local_need = BNET_TLS_REQUIRED;
107       }
108       tls_authenticate = director->tls_authenticate;
109       tls_needed = director->tls_enable || director->tls_authenticate;
110       tls_ctx = director->tls_ctx;
111    }
112
113    
114    /* Timeout Hello after 5 mins */
115    btimer_t *tid = start_bsock_timer(dir, 60 * 5);
116    dir->fsend(hello, bashed_name);
117
118    if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
119        !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
120       goto bail_out;
121    }
122
123    /* Verify that the remote host is willing to meet our TLS requirements */
124    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
125       sendit(_("Authorization problem:"
126              " Remote server did not advertise required TLS support.\n"));
127       goto bail_out;
128    }
129
130    /* Verify that we are willing to meet the remote host's requirements */
131    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
132       sendit(_("Authorization problem:"
133              " Remote server requires TLS.\n"));
134       goto bail_out;
135    }
136
137    /* Is TLS Enabled? */
138    if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
139       /* Engage TLS! Full Speed Ahead! */
140       if (!bnet_tls_client(tls_ctx, dir, NULL)) {
141          sendit(_("TLS negotiation failed\n"));
142          goto bail_out;
143       }
144       if (tls_authenticate) {           /* Authenticate only? */
145          dir->free_tls();               /* yes, shutdown tls */
146       }
147    }
148
149    /*
150     * It's possible that the TLS connection will
151     * be dropped here if an invalid client certificate was presented
152     */
153    Dmsg1(6, ">dird: %s", dir->msg);
154    if (dir->recv() <= 0) {
155       senditf(_("Bad response to Hello command: ERR=%s\n"),
156          dir->bstrerror());
157       goto bail_out;
158    }
159
160    Dmsg1(10, "<dird: %s", dir->msg);
161    if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) {
162       sendit(_("Director rejected Hello command\n"));
163       goto bail_out;
164    } else {
165       sendit(dir->msg);
166    }
167    stop_bsock_timer(tid);
168    return 1;
169
170 bail_out:
171    stop_bsock_timer(tid);
172    sendit( _("Director authorization problem.\n"
173              "Most likely the passwords do not agree.\n"
174              "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
175              "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
176    return 0;
177 }