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