]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/cram-md5.c
e9e6cd77dea685721f9d7c93e08bd8c5a64dac47
[bacula/bacula] / bacula / src / lib / cram-md5.c
1 /*
2  *  Challenge Response Authentication Method using MD5 (CRAM-MD5)
3  *
4  * cram-md5 is based on RFC2104.
5  * 
6  * Written for Bacula by Kern E. Sibbald, May MMI.
7  */
8 /*
9    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2 of
14    the License, or (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public
22    License along with this program; if not, write to the Free
23    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24    MA 02111-1307, USA.
25
26  */
27
28 #include "bacula.h"
29
30 int cram_md5_auth(BSOCK *bs, char *password)
31 {
32    struct timeval t1;
33    struct timeval t2;
34    struct timezone tz;
35    int i, ok;
36    char chal[MAXSTRING];
37    char host[MAXSTRING];
38    uint8_t hmac[20];
39
40    gettimeofday(&t1, &tz);
41    for (i=0; i<4; i++)
42       gettimeofday(&t2, &tz);
43    srandom((t1.tv_sec&0xffff) * (t2.tv_usec&0xff));
44    gethostname(host, sizeof(host));
45    sprintf((char *)chal, "<%u.%u@%s>", (uint32_t)random(), (uint32_t)time(NULL), host);
46    if (!bnet_fsend(bs, "auth cram-md5 %s\n", chal)) {
47       return 0;
48    }
49    Dmsg1(99, "%s", bs->msg);
50    if (bnet_wait_data(bs, 120) <= 0 || bnet_recv(bs) <= 0) {
51       sleep(5);
52       return 0;
53    }
54    hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
55    bin_to_base64(host, (char *)hmac, 16);
56    ok = strcmp(bs->msg, host) == 0;
57    if (ok) {
58       Dmsg3(399, "Authenticate %s: wanted %s, got %s\n", 
59             ok ? "OK" : "NOT OK", host, bs->msg);
60    } else {
61       Dmsg3(99, "Authenticate %s: wanted %s, got %s\n", 
62             ok ? "OK" : "NOT OK", host, bs->msg);
63    }
64    if (ok) {
65       bnet_fsend(bs, "1000 OK auth\n");
66    } else {
67       bnet_fsend(bs, "1999 No auth\n");
68       sleep(5);
69    }
70    return ok;
71 }
72
73 int cram_md5_get_auth(BSOCK *bs, char *password)
74 {
75    char chal[MAXSTRING];
76    uint8_t hmac[20];
77
78    if (bnet_recv(bs) <= 0) {
79       sleep(5);
80       return 0;
81    }
82    if (sscanf(bs->msg, "auth cram-md5 %s", chal) != 1) {
83      sleep(5);
84      return 0;
85    }
86    hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
87    bs->msglen = bin_to_base64(bs->msg, (char *)hmac, 16);
88    if (!bnet_send(bs)) {
89       return 0;
90    }
91    Dmsg1(99, "sending resp to challenge: %s\n", bs->msg);
92    if (bnet_wait_data(bs, 120) <= 0 || bnet_recv(bs) <= 0) {
93       sleep(5);
94       return 0;
95    }
96    if (strcmp(bs->msg, "1000 OK auth\n") == 0) {
97       return 1;
98    }
99    sleep(5);
100    return 0;
101 }