2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 Bacula® is a registered trademark of Kern Sibbald.
19 * Bacula UA authentication. Provides authentication with
22 * Kern Sibbald, June MMI adapted to bat, Jan MMVI
30 * Version at end of Hello
31 * prior to 06Aug13 no version
32 * 1 21Oct13 - added comm line compression
37 /* Commands sent to Director */
38 static char hello[] = "Hello %s calling %d\n";
40 /* Response from Director */
41 static char oldOKhello[] = "1000 OK:";
42 static char newOKhello[] = "1000 OK: %d";
44 /* Forward referenced functions */
47 * Authenticate Director
49 bool DirComm::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons,
50 char *errmsg, int errmsg_len)
52 BSOCK *dir = jcr->dir_bsock;
53 int tls_local_need = BNET_TLS_NONE;
54 int tls_remote_need = BNET_TLS_NONE;
56 bool tls_authenticate;
57 int compatible = true;
58 char bashed_name[MAX_NAME_LENGTH];
60 TLS_CONTEXT *tls_ctx = NULL;
64 * Send my name to the Director then do authentication
67 bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
68 bash_spaces(bashed_name);
69 password = cons->password;
71 if (cons->tls_enable) {
72 if (cons->tls_require) {
73 tls_local_need = BNET_TLS_REQUIRED;
75 tls_local_need = BNET_TLS_OK;
78 tls_authenticate = cons->tls_authenticate;
79 tls_ctx = cons->tls_ctx;
81 bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
82 password = director->password;
84 if (director->tls_enable) {
85 if (director->tls_require) {
86 tls_local_need = BNET_TLS_REQUIRED;
88 tls_local_need = BNET_TLS_OK;
92 tls_authenticate = director->tls_authenticate;
93 tls_ctx = director->tls_ctx;
95 if (tls_authenticate) {
96 tls_local_need = BNET_TLS_REQUIRED;
99 /* Timeout Hello after 15 secs */
100 dir->start_timer(15);
101 dir->fsend(hello, bashed_name, BAT_VERSION);
103 /* respond to Dir challenge */
104 if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
105 /* Now challenge dir */
106 !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
107 bsnprintf(errmsg, errmsg_len, _("Director authorization problem at \"%s:%d\"\n"),
108 dir->host(), dir->port());
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 bsnprintf(errmsg, errmsg_len, _("Authorization problem:"
115 " Remote server at \"%s:%d\" did not advertise required TLS support.\n"),
116 dir->host(), dir->port());
120 /* Verify that we are willing to meet the remote host's requirements */
121 if (tls_remote_need > tls_local_need && tls_local_need != BNET_TLS_OK && tls_remote_need != BNET_TLS_OK) {
122 bsnprintf(errmsg, errmsg_len, _("Authorization problem with Director at \"%s:%d\":"
123 " Remote server requires TLS.\n"),
124 dir->host(), dir->port());
129 /* Is TLS Enabled? */
130 if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) {
131 /* Engage TLS! Full Speed Ahead! */
132 if (!bnet_tls_client(tls_ctx, dir, NULL)) {
133 bsnprintf(errmsg, errmsg_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"),
134 dir->host(), dir->port());
137 if (tls_authenticate) { /* authenticate only? */
138 dir->free_tls(); /* Yes, shutdown tls */
142 Dmsg1(6, ">dird: %s", dir->msg);
143 if (dir->recv() <= 0) {
145 bsnprintf(errmsg, errmsg_len, _("Bad response to Hello command: ERR=%s\n"
146 "The Director at \"%s:%d\" is probably not running.\n"),
147 dir->bstrerror(), dir->host(), dir->port());
152 Dmsg1(10, "<dird: %s", dir->msg);
153 if (strncmp(dir->msg, oldOKhello, sizeof(oldOKhello)-1) != 0) {
154 bsnprintf(errmsg, errmsg_len, _("Director at \"%s:%d\" rejected Hello command\n"),
155 dir->host(), dir->port());
158 /* If Dir version exists, get it */
159 sscanf(dir->msg, newOKhello, &dir_version);
163 bsnprintf(errmsg, errmsg_len, "%s", dir->msg);
169 bsnprintf(errmsg, errmsg_len, _("Authorization problem with Director at \"%s:%d\"\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 dir->host(), dir->port());