Line data Source code
1 : #include "../burp.h"
2 : #include "../alloc.h"
3 : #include "../asfd.h"
4 : #include "../async.h"
5 : #include "../cmd.h"
6 : #include "../conf.h"
7 : #include "../conffile.h"
8 : #include "../handy.h"
9 : #include "../iobuf.h"
10 : #include "../log.h"
11 : #include "auth.h"
12 :
13 : #ifndef UTEST
14 : static
15 : #endif
16 8 : int check_passwd(const char *passwd, const char *plain_text)
17 : {
18 : #ifndef HAVE_OPENBSD_OS
19 : #ifdef HAVE_CRYPT
20 8 : const char *encrypted=NULL;
21 8 : if(!plain_text || !passwd || strlen(passwd)<13)
22 : return 0;
23 :
24 5 : encrypted=crypt(plain_text, passwd);
25 5 : return encrypted && !strcmp(encrypted, passwd);
26 : #endif
27 : #endif
28 : logp("Server compiled without crypt support - cannot use passwd option\n");
29 : return -1;
30 : }
31 :
32 11 : static int check_client_and_password(struct conf **globalcs,
33 : const char *password, struct conf **cconfs)
34 : {
35 : const char *cname;
36 : int password_check;
37 : // Cannot load it until here, because we need to have the name of the
38 : // client.
39 11 : if(conf_load_clientconfdir(globalcs, cconfs)) return -1;
40 :
41 9 : cname=get_string(cconfs[OPT_CNAME]);
42 9 : password_check=get_int(cconfs[OPT_PASSWORD_CHECK]);
43 :
44 9 : if(!get_string(cconfs[OPT_SSL_PEER_CN]))
45 : {
46 9 : logp("ssl_peer_cn unset");
47 9 : if(cname)
48 : {
49 9 : logp("Falling back to using '%s'\n", cname);
50 9 : if(set_string(cconfs[OPT_SSL_PEER_CN], cname))
51 : return -1;
52 : }
53 : }
54 :
55 9 : cname=get_string(cconfs[OPT_CNAME]);
56 :
57 9 : if(password_check)
58 : {
59 9 : const char *conf_passwd=get_string(cconfs[OPT_PASSWD]);
60 9 : const char *conf_password=get_string(cconfs[OPT_PASSWORD]);
61 9 : if(!conf_password && !conf_passwd)
62 : {
63 1 : logp("password rejected for client %s\n", cname);
64 1 : return -1;
65 : }
66 : // check against plain text
67 8 : if(conf_password && strcmp(conf_password, password))
68 : {
69 1 : logp("password rejected for client %s\n", cname);
70 1 : return -1;
71 : }
72 : // check against encypted passwd
73 7 : if(conf_passwd && !check_passwd(conf_passwd, password))
74 : {
75 1 : logp("password rejected for client %s\n", cname);
76 1 : return -1;
77 : }
78 : }
79 :
80 6 : if(!get_strlist(cconfs[OPT_KEEP]))
81 : {
82 1 : logp("%s: you cannot set the keep value for a client to 0!\n",
83 : cname);
84 1 : return -1;
85 : }
86 : return 0;
87 : }
88 :
89 6 : void version_warn(struct asfd *asfd,
90 : struct cntr *cntr, struct conf **cconfs)
91 : {
92 6 : const char *cname=get_string(cconfs[OPT_CNAME]);
93 6 : const char *peer_version=get_string(cconfs[OPT_PEER_VERSION]);
94 6 : if(!peer_version || strcmp(peer_version, PACKAGE_VERSION))
95 : {
96 3 : char msg[256]="";
97 :
98 3 : if(!peer_version || !*peer_version)
99 2 : snprintf(msg, sizeof(msg), "Client '%s' has an unknown version. Please upgrade.", cname?cname:"unknown");
100 : else
101 1 : snprintf(msg, sizeof(msg), "Client '%s' version '%s' does not match server version '%s'. An upgrade is recommended.", cname?cname:"unknown", peer_version, PACKAGE_VERSION);
102 3 : logw(asfd, cntr, "%s\n", msg);
103 : }
104 6 : }
105 :
106 15 : int authorise_server(struct asfd *asfd,
107 : struct conf **globalcs, struct conf **cconfs)
108 : {
109 15 : int ret=-1;
110 15 : char *cp=NULL;
111 15 : char *password=NULL;
112 15 : char *cname=NULL;
113 15 : char whoareyou[256]="";
114 15 : struct iobuf *rbuf=asfd->rbuf;
115 15 : const char *peer_version=NULL;
116 15 : if(asfd->read(asfd))
117 : {
118 1 : logp("unable to read initial message\n");
119 1 : goto end;
120 : }
121 14 : if(rbuf->cmd!=CMD_GEN || strncmp_w(rbuf->buf, "hello"))
122 : {
123 1 : iobuf_log_unexpected(rbuf, __func__);
124 1 : goto end;
125 : }
126 : // String may look like...
127 : // "hello"
128 : // "hello:(version)"
129 : // (version) is a version number
130 13 : if((cp=strchr(rbuf->buf, ':')))
131 : {
132 12 : cp++;
133 12 : if(cp && set_string(cconfs[OPT_PEER_VERSION], cp))
134 : goto end;
135 : }
136 13 : iobuf_free_content(rbuf);
137 :
138 : snprintf(whoareyou, sizeof(whoareyou), "whoareyou");
139 13 : peer_version=get_string(cconfs[OPT_PEER_VERSION]);
140 13 : if(peer_version)
141 : {
142 12 : long min_ver=0;
143 12 : long cli_ver=0;
144 12 : if((min_ver=version_to_long("1.3.2"))<0
145 12 : || (cli_ver=version_to_long(peer_version))<0)
146 : return -1;
147 : // Stick the server version on the end of the whoareyou string.
148 : // if the client version is recent enough.
149 12 : if(min_ver<=cli_ver)
150 : snprintf(whoareyou, sizeof(whoareyou),
151 : "whoareyou:%s", PACKAGE_VERSION);
152 : }
153 :
154 13 : if(asfd->write_str(asfd, CMD_GEN, whoareyou)
155 12 : || asfd->read(asfd))
156 : {
157 1 : logp("unable to get client name\n");
158 1 : goto end;
159 : }
160 :
161 12 : if(!(cname=strdup_w(rbuf->buf, __func__)))
162 : goto end;
163 12 : if(!get_int(globalcs[OPT_CNAME_FQDN]))
164 1 : strip_fqdn(&cname);
165 12 : if(get_int(globalcs[OPT_CNAME_LOWERCASE]))
166 3 : strlwr(cname);
167 :
168 12 : if(set_string(cconfs[OPT_CNAME], cname))
169 : goto end;
170 12 : iobuf_free_content(rbuf);
171 :
172 12 : if(asfd->write_str(asfd, CMD_GEN, "okpassword")
173 11 : || asfd->read(asfd))
174 : {
175 1 : logp("unable to get password for client %s\n",
176 : get_string(cconfs[OPT_CNAME]));
177 1 : goto end;
178 : }
179 11 : password=rbuf->buf;
180 11 : iobuf_init(rbuf);
181 :
182 11 : if(check_client_and_password(globalcs, password, cconfs))
183 : goto end;
184 :
185 5 : if(get_int(cconfs[OPT_VERSION_WARN]))
186 5 : version_warn(asfd, get_cntr(globalcs), cconfs);
187 :
188 5 : logp("auth ok for: %s%s\n", get_string(cconfs[OPT_CNAME]),
189 5 : get_int(cconfs[OPT_PASSWORD_CHECK])?
190 : "":" (no password needed)");
191 :
192 5 : if(asfd->write_str(asfd, CMD_GEN, "ok"))
193 : goto end;
194 :
195 5 : ret=0;
196 : end:
197 15 : iobuf_free_content(rbuf);
198 15 : free_w(&password);
199 15 : free_w(&cname);
200 15 : return ret;
201 : }
|