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