]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/authenticate.c
Update the Microsoft Visual Studio build to match the MinGW32 build.
[bacula/bacula] / bacula / src / wx-console / authenticate.c
1 /*
2  *
3  *   Bacula UA authentication. Provides authentication with
4  *     the Director.
5  *
6  *     Kern Sibbald, June MMI
7  *
8  *    This routine runs as a thread and must be thread reentrant.
9  *
10  *  Basic tasks done here:
11  *
12  */
13 /*
14    Copyright (C) 2001-2005 Kern Sibbald
15
16    This program is free software; you can redistribute it and/or
17    modify it under the terms of the GNU General Public License
18    version 2 as amended with additional clauses defined in the
19    file LICENSE in the main source directory.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
24    the file LICENSE for additional details.
25
26  */
27
28 /* _("...") macro returns a wxChar*, so if we need a char*, we need to convert it with:
29  * wxString(_("...")).mb_str(*wxConvCurrent) */
30
31 #undef _DEBUG
32
33 #include "bacula.h"
34 #include "console_conf.h"
35 #include "jcr.h"
36
37 #include <wx/intl.h>
38
39 #include "csprint.h"
40
41 void senditf(char *fmt, ...);
42 void sendit(char *buf);
43
44 /* Commands sent to Director */
45 static char hello[]    = "Hello %s calling\n";
46
47 /* Response from Director */
48 static char OKhello[]   = "1000 OK:";
49
50 /* Forward referenced functions */
51
52 /*
53  * Authenticate Director
54  */
55 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
56 {
57    BSOCK *dir = jcr->dir_bsock;
58    int tls_local_need = BNET_TLS_NONE;
59    int tls_remote_need = BNET_TLS_NONE;
60    int compatible = true;
61    char bashed_name[MAX_NAME_LENGTH];
62    char *password;
63    TLS_CONTEXT *tls_ctx = NULL;
64
65    /*
66     * Send my name to the Director then do authentication
67     */
68    if (cons) {
69       bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
70       bash_spaces(bashed_name);
71       password = cons->password;
72       /* TLS Requirement */
73       if (cons->tls_enable) {
74          if (cons->tls_require) {
75             tls_local_need = BNET_TLS_REQUIRED;
76          } else {
77             tls_local_need = BNET_TLS_OK;
78          }
79       }
80
81       tls_ctx = cons->tls_ctx;
82    } else {
83       bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
84       password = director->password;
85       /* TLS Requirement */
86       if (director->tls_enable) {
87          if (director->tls_require) {
88             tls_local_need = BNET_TLS_REQUIRED;
89          } else {
90             tls_local_need = BNET_TLS_OK;
91          }
92       }
93
94       tls_ctx = director->tls_ctx;
95    }
96
97
98    /* Timeout Hello after 5 mins */
99    btimer_t *tid = start_bsock_timer(dir, 60 * 5);
100    bnet_fsend(dir, hello, bashed_name);
101
102    if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
103        !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
104       goto bail_out;
105    }
106
107    /* Verify that the remote host is willing to meet our TLS requirements */
108    if (tls_remote_need < tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
109       csprint(_("Authorization problem: Remote server did not advertise required TLS support.\n"));
110       goto bail_out;
111    }
112
113    /* Verify that we are willing to meet the remote host's requirements */
114    if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
115       csprint(_("Authorization problem: Remote server requires TLS.\n"));
116       goto bail_out;
117    }
118
119    /* Is TLS Enabled? */
120    if (have_tls) {
121       if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
122          /* Engage TLS! Full Speed Ahead! */
123          if (!bnet_tls_client(tls_ctx, dir)) {
124             csprint(_("TLS negotiation failed\n"));
125             goto bail_out;
126          }
127       }
128    }
129
130    Dmsg1(6, ">dird: %s", dir->msg);
131    if (bnet_recv(dir) <= 0) {
132       csprint(_("Bad response to Hello command: ERR="), CS_DATA);
133       csprint(bnet_strerror(dir), CS_DATA);
134       csprint("\n", CS_DATA);
135       goto bail_out;
136    }
137    Dmsg1(10, "<dird: %s", dir->msg);
138    if (strncmp(dir->msg, OKhello, sizeof(OKhello)-1) != 0) {
139       csprint(_("Director rejected Hello command\n"), CS_DATA);
140       goto bail_out;
141    } else {
142       csprint(dir->msg, CS_DATA);
143    }
144    stop_bsock_timer(tid);
145    return 1;
146
147 bail_out:
148    stop_bsock_timer(tid);
149    csprint( _("Director authorization problem.\nMost likely the passwords do not agree.\nIf you are using TLS, there may have been a certificate validation error during the TLS handshake.\nPlease see http://www.bacula.org/rel-manual/faq.html#AuthorizationErrors for help.\n"));
150    return 0;
151
152 }