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 "../fsops.h"
9 : #include "../handy.h"
10 : #include "../incexc_recv.h"
11 : #include "../incexc_send.h"
12 : #include "../iobuf.h"
13 : #include "../log.h"
14 : #include "../pathcmp.h"
15 : #include "../prepend.h"
16 : #include "autoupgrade.h"
17 : #include "extra_comms.h"
18 :
19 : #include <librsync.h>
20 :
21 419 : static int append_to_feat(char **feat, const char *str)
22 : {
23 419 : char *tmp=NULL;
24 419 : if(!*feat)
25 : {
26 35 : if(!(*feat=strdup_w(str, __func__)))
27 : return -1;
28 35 : return 0;
29 : }
30 384 : if(!(tmp=prepend(*feat, str)))
31 : return -1;
32 384 : free_w(feat);
33 384 : *feat=tmp;
34 384 : return 0;
35 : }
36 :
37 : // It is unfortunate that we are having to figure out the server-initiated
38 : // restore paths here instead of setting it in a struct sdirs.
39 : // But doing the extra_comms needs to come before setting the sdirs, because
40 : // extra_comms sets up a bunch of settings that sdirs need to know.
41 35 : static char *get_restorepath_proto1(struct conf **cconfs)
42 : {
43 35 : char *tmp=NULL;
44 35 : char *restorepath=NULL;
45 35 : if((tmp=prepend_s(get_string(cconfs[OPT_DIRECTORY]),
46 35 : get_string(cconfs[OPT_CNAME]))))
47 35 : restorepath=prepend_s(tmp, "restore");
48 35 : free_w(&tmp);
49 35 : return restorepath;
50 : }
51 :
52 35 : static char *get_restorepath_proto2(struct conf **cconfs)
53 : {
54 35 : char *tmp1=NULL;
55 35 : char *tmp2=NULL;
56 35 : char *restorepath=NULL;
57 35 : if(!(tmp1=prepend_s(get_string(cconfs[OPT_DIRECTORY]),
58 35 : get_string(cconfs[OPT_DEDUP_GROUP]))))
59 : goto error;
60 35 : if(!(tmp2=prepend_s(tmp1, "clients")))
61 : goto error;
62 35 : free_w(&tmp1);
63 35 : if(!(tmp1=prepend_s(tmp2, get_string(cconfs[OPT_CNAME]))))
64 : goto error;
65 35 : if(!(restorepath=prepend_s(tmp1, "restore")))
66 : goto error;
67 : goto end;
68 : error:
69 0 : free_w(&restorepath);
70 : end:
71 35 : free_w(&tmp1);
72 35 : free_w(&tmp2);
73 35 : return restorepath;
74 : }
75 :
76 35 : static int set_restore_path(struct conf **cconfs, char **feat)
77 : {
78 35 : int ret=-1;
79 35 : char *restorepath1=NULL;
80 35 : char *restorepath2=NULL;
81 35 : if(!(restorepath1=get_restorepath_proto1(cconfs))
82 35 : || !(restorepath2=get_restorepath_proto2(cconfs)))
83 : goto end;
84 35 : if(is_reg_lstat(restorepath1)==1
85 4 : && set_string(cconfs[OPT_RESTORE_PATH], restorepath1))
86 : goto end;
87 35 : else if(is_reg_lstat(restorepath2)==1
88 0 : && set_string(cconfs[OPT_RESTORE_PATH], restorepath2))
89 : goto end;
90 35 : if(get_string(cconfs[OPT_RESTORE_PATH])
91 4 : && append_to_feat(feat, "srestore:"))
92 : goto end;
93 : ret=0;
94 : end:
95 35 : free_w(&restorepath1);
96 35 : free_w(&restorepath2);
97 35 : return ret;
98 : }
99 :
100 : struct vers
101 : {
102 : long min;
103 : long cli;
104 : long ser;
105 : long feat_list;
106 : long directory_tree;
107 : long burp2;
108 : long counters_json;
109 : };
110 :
111 35 : static int send_features(struct asfd *asfd, struct conf **cconfs,
112 : struct vers *vers)
113 : {
114 35 : int ret=-1;
115 35 : char *feat=NULL;
116 35 : enum protocol protocol=get_protocol(cconfs);
117 35 : struct strlist *startdir=get_strlist(cconfs[OPT_STARTDIR]);
118 35 : struct strlist *incglob=get_strlist(cconfs[OPT_INCGLOB]);
119 :
120 35 : if(append_to_feat(&feat, "extra_comms_begin ok:")
121 : /* clients can autoupgrade */
122 35 : || append_to_feat(&feat, "autoupgrade:")
123 : /* clients can give server incexc conf so that the
124 : server knows better what to do on resume */
125 35 : || append_to_feat(&feat, "incexc:")
126 : /* clients can give the server an alternative client
127 : to restore from */
128 35 : || append_to_feat(&feat, "orig_client:")
129 : /* clients can tell the server what kind of system they are. */
130 35 : || append_to_feat(&feat, "uname:")
131 35 : || append_to_feat(&feat, "failover:")
132 35 : || append_to_feat(&feat, "vss_restore:")
133 35 : || append_to_feat(&feat, "regex_icase:"))
134 : goto end;
135 :
136 : /* Clients can receive restore initiated from the server. */
137 35 : if(set_restore_path(cconfs, &feat))
138 : goto end;
139 :
140 : /* Clients can receive incexc conf from the server.
141 : Only give it as an option if the server has some starting
142 : directory configured in the clientconfdir. */
143 35 : if((startdir || incglob)
144 0 : && append_to_feat(&feat, "sincexc:"))
145 : goto end;
146 :
147 35 : if(vers->cli>=vers->counters_json)
148 : {
149 : /* Clients can be sent cntrs on resume/verify/restore. */
150 30 : if(append_to_feat(&feat, "counters_json:"))
151 : goto end;
152 : }
153 :
154 : // We support CMD_MESSAGE.
155 35 : if(append_to_feat(&feat, "msg:"))
156 : goto end;
157 :
158 35 : if(protocol==PROTO_AUTO)
159 : {
160 : /* If the server is configured to use either protocol, let the
161 : client know that it can choose. */
162 25 : logp("Server is using protocol=0 (auto)\n");
163 25 : if(append_to_feat(&feat, "csetproto:"))
164 : goto end;
165 : }
166 : else
167 : {
168 10 : char p[32]="";
169 : /* Tell the client what we are going to use. */
170 10 : logp("Server is using protocol=%d\n", (int)protocol);
171 10 : snprintf(p, sizeof(p), "forceproto=%d:", (int)protocol);
172 10 : if(append_to_feat(&feat, p))
173 : goto end;
174 : }
175 :
176 : #ifdef HAVE_BLAKE2
177 : if(append_to_feat(&feat, "rshash=blake2:"))
178 : goto end;
179 : #endif
180 :
181 35 : if(append_to_feat(&feat, "seed:"))
182 : goto end;
183 :
184 : //printf("feat: %s\n", feat);
185 :
186 35 : if(asfd->write_str(asfd, CMD_GEN, feat))
187 : {
188 1 : logp("problem in extra_comms\n");
189 : goto end;
190 : }
191 :
192 : ret=0;
193 : end:
194 35 : free_w(&feat);
195 35 : return ret;
196 : }
197 :
198 2 : static int do_autoupgrade(struct asfd *asfd, struct vers *vers,
199 : struct conf **globalcs)
200 : {
201 2 : int ret=-1;
202 2 : char *os=NULL;
203 2 : struct iobuf *rbuf=asfd->rbuf;
204 2 : const char *autoupgrade_dir=get_string(globalcs[OPT_AUTOUPGRADE_DIR]);
205 :
206 2 : if(!(os=strdup_w(rbuf->buf+strlen("autoupgrade:"), __func__)))
207 : goto end;
208 2 : iobuf_free_content(rbuf);
209 2 : ret=0;
210 2 : if(os && *os)
211 : {
212 : // Sanitise path separators
213 7 : for(char *i=os; *i; ++i)
214 7 : if(*i == '/' || *i == '\\' || *i == ':')
215 0 : *i='-';
216 :
217 1 : ret=autoupgrade_server(asfd, vers->ser,
218 : vers->cli, os, get_cntr(globalcs),
219 : autoupgrade_dir);
220 : }
221 : end:
222 2 : free_w(&os);
223 2 : return ret;
224 : }
225 :
226 0 : static int setup_seed(
227 : struct asfd *asfd,
228 : struct conf **cconfs,
229 : struct iobuf *rbuf,
230 : const char *what,
231 : enum conf_opt opt
232 : ) {
233 0 : int ret=-1;
234 0 : char *tmp=NULL;
235 0 : char *str=NULL;
236 :
237 0 : str=rbuf->buf+strlen(what)+1;
238 0 : strip_trailing_slashes(&str);
239 :
240 0 : if(!is_absolute(str))
241 : {
242 : char msg[128];
243 0 : snprintf(msg, sizeof(msg), "A %s needs to be absolute!", what);
244 0 : log_and_send(asfd, msg);
245 : goto end;
246 : }
247 0 : if(opt==OPT_SEED_SRC && *str!='/')
248 : {
249 0 : printf("here: %s\n", str);
250 : // More windows hacks - add a slash to the beginning of things
251 : // like 'C:'.
252 0 : if(astrcat(&tmp, "/", __func__)
253 0 : || astrcat(&tmp, str, __func__))
254 : goto end;
255 0 : str=tmp;
256 : }
257 0 : if(set_string(cconfs[opt], str))
258 : goto end;
259 0 : ret=0;
260 : end:
261 0 : free_w(&tmp);
262 0 : return ret;
263 : }
264 :
265 34 : static int extra_comms_read(struct async *as,
266 : struct vers *vers, int *srestore,
267 : char **incexc, struct conf **globalcs, struct conf **cconfs)
268 : {
269 34 : int ret=-1;
270 : struct asfd *asfd;
271 : struct iobuf *rbuf;
272 34 : asfd=as->asfd;
273 34 : rbuf=asfd->rbuf;
274 :
275 : while(1)
276 : {
277 54 : iobuf_free_content(rbuf);
278 54 : if(asfd->read(asfd)) goto end;
279 :
280 54 : if(rbuf->cmd!=CMD_GEN)
281 : {
282 1 : iobuf_log_unexpected(rbuf, __func__);
283 : goto end;
284 : }
285 :
286 53 : if(!strcmp(rbuf->buf, "extra_comms_end"))
287 : {
288 24 : if(asfd->write_str(asfd, CMD_GEN, "extra_comms_end ok"))
289 : goto end;
290 : break;
291 : }
292 29 : else if(!strncmp_w(rbuf->buf, "autoupgrade:"))
293 : {
294 2 : if(do_autoupgrade(asfd, vers, globalcs))
295 : goto end;
296 : }
297 27 : else if(!strcmp(rbuf->buf, "srestore ok"))
298 : {
299 4 : char *restore_path=get_string(cconfs[OPT_RESTORE_PATH]);
300 4 : if(!restore_path)
301 : {
302 0 : logp("got srestore ok without a restore_path");
303 : goto end;
304 : }
305 :
306 4 : iobuf_free_content(rbuf);
307 : // Client can accept the restore.
308 : // Load the restore config, then send it.
309 4 : *srestore=1;
310 : // Need to wipe out OPT_INCEXDIR, as it is needed for
311 : // srestore includes. If it is not wiped out, it can
312 : // interfere if cconfs[OPT_RESTORE_PATH] contained no
313 : // includes.
314 4 : set_strlist(cconfs[OPT_INCEXCDIR], NULL);
315 4 : if(conf_parse_incexcs_path(cconfs, restore_path)
316 4 : || incexc_send_server_restore(asfd, cconfs))
317 : goto end;
318 : // Do not unlink it here - wait until
319 : // the client says that it wants to do the
320 : // restore.
321 : // Also need to leave it around if the
322 : // restore is to an alternative client, so
323 : // that the code below that reloads the config
324 : // can read it again.
325 : // NOTE: that appears to be in
326 : // src/server/run_action.c::client_can_restore()
327 : //unlink(get_string(cconfs[OPT_RESTORE_PATH]));
328 : }
329 23 : else if(!strcmp(rbuf->buf, "srestore not ok"))
330 : {
331 1 : const char *restore_path=get_string(
332 : cconfs[OPT_RESTORE_PATH]);
333 : // Client will not accept the restore.
334 1 : if (restore_path)
335 1 : unlink(restore_path);
336 1 : if(set_string(cconfs[OPT_RESTORE_PATH], NULL))
337 : goto end;
338 1 : logp("Client not accepting server initiated restore.\n");
339 : }
340 22 : else if(!strcmp(rbuf->buf, "sincexc ok"))
341 : {
342 : // Client can accept incexc conf from the
343 : // server.
344 1 : iobuf_free_content(rbuf);
345 1 : if(incexc_send_server(asfd, cconfs))
346 : goto end;
347 : }
348 21 : else if(!strcmp(rbuf->buf, "incexc"))
349 : {
350 : // Client is telling server its incexc
351 : // configuration so that it can better decide
352 : // what to do on resume.
353 1 : iobuf_free_content(rbuf);
354 1 : if(incexc_recv_server(asfd, incexc, globalcs))
355 : goto end;
356 1 : if(*incexc)
357 : {
358 1 : char *tmp=NULL;
359 1 : char comp[32]="";
360 1 : snprintf(comp, sizeof(comp),
361 : "compression = %d\n",
362 : get_int(cconfs[OPT_COMPRESSION]));
363 1 : if(!(tmp=prepend(*incexc, comp)))
364 : goto end;
365 1 : free_w(incexc);
366 1 : *incexc=tmp;
367 : }
368 : }
369 20 : else if(!strcmp(rbuf->buf, "counters_json ok"))
370 : {
371 : // Client can accept counters on
372 : // resume/verify/restore.
373 1 : logp("Client supports being sent json counters.\n");
374 1 : set_int(cconfs[OPT_SEND_CLIENT_CNTR], 1);
375 : }
376 19 : else if(!strncmp_w(rbuf->buf, "uname=")
377 2 : && strlen(rbuf->buf)>strlen("uname="))
378 : {
379 2 : char *uname=rbuf->buf+strlen("uname=");
380 2 : if(!strncasecmp("Windows", uname, strlen("Windows")))
381 1 : set_int(cconfs[OPT_CLIENT_IS_WINDOWS], 1);
382 : }
383 17 : else if(!strncmp_w(rbuf->buf, "orig_client=")
384 3 : && strlen(rbuf->buf)>strlen("orig_client="))
385 : {
386 3 : if(conf_switch_to_orig_client(globalcs, cconfs,
387 3 : rbuf->buf+strlen("orig_client=")))
388 : goto end;
389 : // If this started out as a server-initiated
390 : // restore, need to load the restore file
391 : // again.
392 2 : if(*srestore)
393 : {
394 1 : if(conf_parse_incexcs_path(cconfs,
395 1 : get_string(cconfs[OPT_RESTORE_PATH])))
396 : goto end;
397 : }
398 2 : if(asfd->write_str(asfd, CMD_GEN, "orig_client ok"))
399 : goto end;
400 : }
401 14 : else if(!strncmp_w(rbuf->buf, "restore_spool="))
402 : {
403 : // Removed.
404 : }
405 14 : else if(!strncmp_w(rbuf->buf, "protocol="))
406 : {
407 11 : char msg[128]="";
408 : // Client wants to set protocol.
409 : enum protocol protocol;
410 : enum protocol cprotocol;
411 11 : const char *cliproto=NULL;
412 11 : protocol=get_protocol(cconfs);
413 11 : cliproto=rbuf->buf+strlen("protocol=");
414 11 : cprotocol=atoi(cliproto);
415 :
416 11 : if(protocol!=PROTO_AUTO)
417 : {
418 6 : if(protocol==cprotocol)
419 : {
420 2 : logp("Client is forcing protocol=%d\n", (int)protocol);
421 2 : continue;
422 : }
423 4 : snprintf(msg, sizeof(msg), "Client is trying to use protocol=%d but server is set to protocol=%d\n", (int)cprotocol, (int)protocol);
424 4 : log_and_send(asfd, msg);
425 5 : goto end;
426 : }
427 5 : else if(cprotocol==PROTO_1)
428 : {
429 2 : set_protocol(cconfs, cprotocol);
430 2 : set_protocol(globalcs, cprotocol);
431 : }
432 3 : else if(cprotocol==PROTO_2)
433 : {
434 2 : set_protocol(cconfs, cprotocol);
435 2 : set_protocol(globalcs, cprotocol);
436 : }
437 : else
438 : {
439 1 : snprintf(msg, sizeof(msg), "Client is trying to use protocol=%s, which is unknown\n", cliproto);
440 1 : log_and_send(asfd, msg);
441 : goto end;
442 : }
443 4 : logp("Client has set protocol=%d\n",
444 4 : (int)get_protocol(cconfs));
445 : }
446 3 : else if(!strncmp_w(rbuf->buf, "rshash=blake2"))
447 : {
448 : #ifdef HAVE_BLAKE2
449 : set_e_rshash(cconfs[OPT_RSHASH], RSHASH_BLAKE2);
450 : set_e_rshash(globalcs[OPT_RSHASH], RSHASH_BLAKE2);
451 : #else
452 1 : logp("Client is trying to use librsync hash blake2, but server does not support it.\n");
453 : goto end;
454 : #endif
455 : }
456 2 : else if(!strncmp_w(rbuf->buf, "msg"))
457 : {
458 1 : set_int(cconfs[OPT_MESSAGE], 1);
459 1 : set_int(globalcs[OPT_MESSAGE], 1);
460 : }
461 1 : else if(!strncmp_w(rbuf->buf, "backup_failovers_left="))
462 : {
463 : int l;
464 0 : l=atoi(rbuf->buf+strlen("backup_failovers_left="));
465 0 : set_int(cconfs[OPT_BACKUP_FAILOVERS_LEFT], l);
466 0 : set_int(globalcs[OPT_BACKUP_FAILOVERS_LEFT], l);
467 : }
468 1 : else if(!strncmp_w(rbuf->buf, "seed_src="))
469 : {
470 0 : if(setup_seed(asfd, cconfs,
471 : rbuf, "seed_src", OPT_SEED_SRC))
472 : goto end;
473 : }
474 1 : else if(!strncmp_w(rbuf->buf, "seed_dst="))
475 : {
476 0 : if(setup_seed(asfd, cconfs,
477 : rbuf, "seed_dst", OPT_SEED_DST))
478 : goto end;
479 : }
480 1 : else if(!strncmp_w(rbuf->buf, "vss_restore=off"))
481 : {
482 0 : set_int(cconfs[OPT_VSS_RESTORE], VSS_RESTORE_OFF);
483 0 : set_int(globalcs[OPT_VSS_RESTORE], VSS_RESTORE_OFF);
484 : }
485 1 : else if(!strncmp_w(rbuf->buf, "vss_restore=strip"))
486 : {
487 0 : set_int(cconfs[OPT_VSS_RESTORE], VSS_RESTORE_OFF_STRIP);
488 0 : set_int(globalcs[OPT_VSS_RESTORE], VSS_RESTORE_OFF_STRIP);
489 : }
490 1 : else if(!strncmp_w(rbuf->buf, "regex_icase=1"))
491 : {
492 0 : set_int(cconfs[OPT_REGEX_CASE_INSENSITIVE], 1);
493 0 : set_int(globalcs[OPT_REGEX_CASE_INSENSITIVE], 1);
494 : }
495 : else
496 : {
497 1 : iobuf_log_unexpected(rbuf, __func__);
498 : goto end;
499 : }
500 : }
501 :
502 24 : ret=0;
503 : end:
504 34 : iobuf_free_content(rbuf);
505 34 : return ret;
506 : }
507 :
508 39 : static int vers_init(struct vers *vers, struct conf **cconfs)
509 : {
510 39 : memset(vers, 0, sizeof(struct vers));
511 39 : return ((vers->min=version_to_long("1.2.7"))<0
512 39 : || (vers->cli=version_to_long(get_string(cconfs[OPT_PEER_VERSION])))<0
513 39 : || (vers->ser=version_to_long(PACKAGE_VERSION))<0
514 39 : || (vers->feat_list=version_to_long("1.3.0"))<0
515 39 : || (vers->directory_tree=version_to_long("1.3.6"))<0
516 39 : || (vers->burp2=version_to_long("2.0.0"))<0
517 78 : || (vers->counters_json=version_to_long("2.0.46"))<0);
518 : }
519 :
520 22 : static int check_seed(struct asfd *asfd, struct conf **cconfs)
521 : {
522 22 : char msg[128]="";
523 22 : const char *src=get_string(cconfs[OPT_SEED_SRC]);
524 22 : const char *dst=get_string(cconfs[OPT_SEED_DST]);
525 22 : if(!src && !dst)
526 : return 0;
527 0 : if(src && dst)
528 : {
529 0 : logp("Seeding '%s' -> '%s'\n", src, dst);
530 0 : return 0;
531 : }
532 0 : snprintf(msg, sizeof(msg),
533 : "You must specify %s and %s options together, or not at all.",
534 0 : cconfs[OPT_SEED_SRC]->field,
535 0 : cconfs[OPT_SEED_DST]->field);
536 0 : log_and_send(asfd, msg);
537 0 : return -1;
538 : }
539 :
540 39 : int extra_comms(struct async *as,
541 : char **incexc, int *srestore, struct conf **confs, struct conf **cconfs)
542 : {
543 : struct vers vers;
544 : struct asfd *asfd;
545 39 : asfd=as->asfd;
546 : //char *restorepath=NULL;
547 39 : const char *peer_version=NULL;
548 :
549 39 : if(vers_init(&vers, cconfs))
550 : goto error;
551 :
552 39 : if(vers.cli<vers.directory_tree)
553 : {
554 3 : set_int(confs[OPT_DIRECTORY_TREE], 0);
555 3 : set_int(cconfs[OPT_DIRECTORY_TREE], 0);
556 : }
557 :
558 : // Clients before 1.2.7 did not know how to do extra comms, so skip
559 : // this section for them.
560 39 : if(vers.cli<vers.min)
561 : return 0;
562 :
563 37 : if(asfd_read_expect(asfd, CMD_GEN, "extra_comms_begin"))
564 : {
565 1 : logp("problem reading in extra_comms\n");
566 1 : goto error;
567 : }
568 : // Want to tell the clients the extra comms features that are
569 : // supported, so that new clients are more likely to work with old
570 : // servers.
571 36 : if(vers.cli==vers.feat_list)
572 : {
573 : // 1.3.0 did not support the feature list.
574 1 : if(asfd->write_str(asfd, CMD_GEN, "extra_comms_begin ok"))
575 : {
576 1 : logp("problem writing in extra_comms\n");
577 1 : goto error;
578 : }
579 : }
580 : else
581 : {
582 35 : if(send_features(asfd, cconfs, &vers))
583 : goto error;
584 : }
585 :
586 34 : if(extra_comms_read(as, &vers, srestore, incexc, confs, cconfs))
587 : goto error;
588 :
589 24 : peer_version=get_string(cconfs[OPT_PEER_VERSION]);
590 :
591 : // This needs to come after extra_comms_read, as the client might
592 : // have set PROTO_1 or PROTO_2.
593 24 : switch(get_protocol(cconfs))
594 : {
595 : case PROTO_AUTO:
596 : // The protocol has not been specified. Make a choice.
597 14 : if(vers.cli<vers.burp2)
598 : {
599 : // Client is burp-1.x.x, use protocol1.
600 1 : set_protocol(confs, PROTO_1);
601 1 : set_protocol(cconfs, PROTO_1);
602 1 : logp("Client is %s-%s - using protocol=%d\n",
603 : PACKAGE_TARNAME,
604 : peer_version, PROTO_1);
605 : }
606 : else
607 : {
608 : // Client is burp-2.x.x, use protocol2.
609 : // This will probably never be reached because
610 : // the negotiation will take care of it.
611 : /*
612 : set_protocol(confs, PROTO_2);
613 : set_protocol(cconfs, PROTO_2);
614 : logp("Client is %s-%s - using protocol=%d\n",
615 : PACKAGE_TARNAME,
616 : peer_version, PROTO_2);
617 : */
618 : // PROTO_1 is safer for now.
619 13 : set_protocol(confs, PROTO_1);
620 13 : set_protocol(cconfs, PROTO_1);
621 13 : logp("Client is %s-%s - using protocol=%d\n",
622 : PACKAGE_TARNAME,
623 : peer_version, PROTO_1);
624 : }
625 : break;
626 : case PROTO_1:
627 : // It is OK for the client to be burp1 and for the
628 : // server to be forced to protocol1.
629 : break;
630 : case PROTO_2:
631 5 : if(vers.cli>=vers.burp2)
632 : break;
633 2 : logp("protocol=%d is set server side, "
634 : "but client is %s version %s\n",
635 : PROTO_2, PACKAGE_TARNAME, peer_version);
636 2 : goto error;
637 : }
638 :
639 22 : if(get_protocol(cconfs)==PROTO_1)
640 : {
641 19 : if(get_e_rshash(cconfs[OPT_RSHASH])==RSHASH_UNSET)
642 : {
643 19 : set_e_rshash(confs[OPT_RSHASH], RSHASH_MD4);
644 19 : set_e_rshash(cconfs[OPT_RSHASH], RSHASH_MD4);
645 : }
646 : }
647 :
648 22 : if(check_seed(asfd, cconfs))
649 : goto error;
650 :
651 : return 0;
652 : error:
653 : return -1;
654 : }
|