1 /*
2  *
3  *   Bacula authentication. Provides authentication with
4  *     File and Storage daemons.
5  *
6  *     Nicolas Boichat, August MMIV
7  *
8  *    This routine runs as a thread and must be thread reentrant.
9  *
10  *  Basic tasks done here:
11  *
12  */
13 /*
14    Bacula® - The Network Backup Solution
15 
16    Copyright (C) 2004-2014 Free Software Foundation Europe e.V.
17 
18    The main author of Bacula is Kern Sibbald, with contributions from
19    many others, a complete list can be found in the file AUTHORS.
20    This program is Free Software; you can redistribute it and/or
21    modify it under the terms of version three of the GNU Affero General Public
22    License as published by the Free Software Foundation plus additions
23    that are listed in the file LICENSE.
24 
25    This program is distributed in the hope that it will be useful, but
26    WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28    General Public License for more details.
29 
30    You should have received a copy of the GNU Affero General Public License
31    along with this program; if not, write to the Free Software
32    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33    02110-1301, USA.
34 
35    Bacula® is a registered trademark of John Walker.
36    The licensor of Bacula is the Free Software Foundation Europe
37    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
38    Switzerland, email:ftf@fsfeurope.org.
39 */
40 
41 #include "bacula.h"
42 #include "check_bacula.h"
43 
44 void senditf(const char *fmt, ...);
45 void sendit(const char *buf);
46 
47 /* Commands sent to Director */
48 static char DIRhello[]    = "Hello %s calling\n";
49 
50 /* Response from Director */
51 static char DIROKhello[]   = "1000 OK:";
52 
53 /* Commands sent to Storage daemon */
54 static char SDhello[]     = "Hello SD: Bacula Director %s calling\n";
55 
56 /* Commands sent to  File daemon */
57 static char FDhello[]     = "Hello Director %s calling\n";
58 
59 /* Response from SD */
60 static char SDOKhello[]  = "3000 OK Hello";
61 /* Response from FD */
62 static char FDOKhello[] = "2000 OK Hello";
63 
64 /* Forward referenced functions */
65 
66 /*
67  * Authenticate Director
68  */
authenticate_director(BSOCK * dir,char * dirname,char * password)69 int authenticate_director(BSOCK *dir, char *dirname, char *password)
70 {
71    int tls_local_need = BNET_TLS_NONE;
72    int tls_remote_need = BNET_TLS_NONE;
73    int compatible = true;
74    char bashed_name[MAX_NAME_LENGTH];
75 
76    bstrncpy(bashed_name, dirname, sizeof(bashed_name));
77    bash_spaces(bashed_name);
78 
79    /* Timeout Hello after 5 mins */
80    btimer_t *tid = start_bsock_timer(dir, 60 * 5);
81    dir->fsend(DIRhello, bashed_name);
82 
83    if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
84        !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
85       stop_bsock_timer(tid);
86       return 0;
87    }
88 
89    Dmsg1(6, ">dird: %s", dir->msg);
90    if (dir->recv() <= 0) {
91       stop_bsock_timer(tid);
92       return 0;
93    }
94    Dmsg1(10, "<dird: %s", dir->msg);
95    stop_bsock_timer(tid);
96    if (strncmp(dir->msg, DIROKhello, sizeof(DIROKhello)-1) != 0) {
97       return 0;
98    }
99    return 1;
100 }
101 
102 /*
103  * Authenticate Storage daemon connection
104  */
authenticate_storage_daemon(BSOCK * sd,char * sdname,char * password)105 int authenticate_storage_daemon(BSOCK *sd, char *sdname, char* password)
106 {
107    char dirname[MAX_NAME_LENGTH];
108    int tls_local_need = BNET_TLS_NONE;
109    int tls_remote_need = BNET_TLS_NONE;
110    int compatible = true;
111 
112    /*
113     * Send my name to the Storage daemon then do authentication
114     */
115    bstrncpy(dirname, sdname, sizeof(dirname));
116    bash_spaces(dirname);
117    /* Timeout Hello after 5 mins */
118    btimer_t *tid = start_bsock_timer(sd, 60 * 5);
119    if (!sd->fsend(SDhello, dirname)) {
120       stop_bsock_timer(tid);
121       return 0;
122    }
123    if (!cram_md5_respond(sd, password, &tls_remote_need, &compatible) ||
124        !cram_md5_challenge(sd, password, tls_local_need, compatible)) {
125       stop_bsock_timer(tid);
126       return 0;
127    }
128    Dmsg1(116, ">stored: %s", sd->msg);
129    if (sd->recv() <= 0) {
130       stop_bsock_timer(tid);
131       return 0;
132    }
133    Dmsg1(110, "<stored: %s", sd->msg);
134    stop_bsock_timer(tid);
135    if (strncmp(sd->msg, SDOKhello, strlen(SDOKhello)) != 0) {
136       return 0;
137    }
138    return 1;
139 }
140 
141 /*
142  * Authenticate File daemon connection
143  */
authenticate_file_daemon(BSOCK * fd,char * fdname,char * password)144 int authenticate_file_daemon(BSOCK *fd, char *fdname, char *password)
145 {
146    char dirname[MAX_NAME_LENGTH];
147    int tls_local_need = BNET_TLS_NONE;
148    int tls_remote_need = BNET_TLS_NONE;
149    int compatible = true;
150 
151    /*
152     * Send my name to the File daemon then do authentication
153     */
154    bstrncpy(dirname, fdname, sizeof(dirname));
155    bash_spaces(dirname);
156    /* Timeout Hello after 5 mins */
157    btimer_t *tid = start_bsock_timer(fd, 60 * 5);
158    if (!fd->fsend(FDhello, dirname)) {
159       stop_bsock_timer(tid);
160       return 0;
161    }
162    if (!cram_md5_respond(fd, password, &tls_remote_need, &compatible) ||
163        !cram_md5_challenge(fd, password, tls_local_need, compatible)) {
164       stop_bsock_timer(tid);
165       return 0;
166    }
167    Dmsg1(116, ">filed: %s", fd->msg);
168    if (fd->recv() <= 0) {
169       stop_bsock_timer(tid);
170       return 0;
171    }
172    Dmsg1(110, "<stored: %s", fd->msg);
173    stop_bsock_timer(tid);
174    if ((strncmp(fd->msg, FDOKhello, strlen(FDOKhello)) != 0)) {
175       return 0;
176    }
177    return 1;
178 }
179