]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/console/authenticate.c
Convert to pure GPL v2 license.
[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 John Walker.
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    int compatible = true;
66    char bashed_name[MAX_NAME_LENGTH];
67    char *password;
68    TLS_CONTEXT *tls_ctx = NULL;
69
70    /*
71     * Send my name to the Director then do authentication
72     */
73    if (cons) {
74       bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
75       bash_spaces(bashed_name);
76       password = cons->password;
77       /* TLS Requirement */
78       if (cons->tls_enable) {
79          if (cons->tls_require) {
80             tls_local_need = BNET_TLS_REQUIRED;
81          } else {
82             tls_local_need = BNET_TLS_OK;
83          }
84       }
85
86       tls_ctx = cons->tls_ctx;
87    } else {
88       bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
89       password = director->password;
90       /* TLS Requirement */
91       if (director->tls_enable) {
92          if (director->tls_require) {
93             tls_local_need = BNET_TLS_REQUIRED;
94          } else {
95             tls_local_need = BNET_TLS_OK;
96          }
97       }
98
99       tls_ctx = director->tls_ctx;
100    }
101
102    
103    /* Timeout Hello after 5 mins */
104    btimer_t *tid = start_bsock_timer(dir, 60 * 5);
105    dir->fsend(hello, bashed_name);
106
107    if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
108        !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
109       goto bail_out;
110    }
111
112    /* Verify that the remote host is willing to meet our TLS requirements */
113    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
114       sendit(_("Authorization problem:"
115              " Remote server did not advertise required TLS support.\n"));
116       goto bail_out;
117    }
118
119    /* Verify that we are willing to meet the remote host's requirements */
120    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
121       sendit(_("Authorization problem:"
122              " Remote server requires TLS.\n"));
123       goto bail_out;
124    }
125
126    /* Is TLS Enabled? */
127    if (have_tls) {
128       if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
129          /* Engage TLS! Full Speed Ahead! */
130          if (!bnet_tls_client(tls_ctx, dir, NULL)) {
131             sendit(_("TLS negotiation failed\n"));
132             goto bail_out;
133          }
134       }
135    }
136
137    /*
138     * It's possible that the TLS connection will
139     * be dropped here if an invalid client certificate was presented
140     */
141    Dmsg1(6, ">dird: %s", dir->msg);
142    if (dir->recv() <= 0) {
143       senditf(_("Bad response to Hello command: ERR=%s\n"),
144          dir->bstrerror());
145       goto bail_out;
146    }
147
148    Dmsg1(10, "<dird: %s", dir->msg);
149    if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) {
150       sendit(_("Director rejected Hello command\n"));
151       goto bail_out;
152    } else {
153       sendit(dir->msg);
154    }
155    stop_bsock_timer(tid);
156    return 1;
157
158 bail_out:
159    stop_bsock_timer(tid);
160    sendit( _("Director authorization problem.\n"
161              "Most likely the passwords do not agree.\n"
162              "If you are using TLS, there may have been a certificate validation error during the TLS handshake.\n"
163              "Please see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
164    return 0;
165 }