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