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