1 #include "../burp.h"
2 #include "../asfd.h"
3 #include "../async.h"
4 #include "../cmd.h"
5 #include "../fsops.h"
6 #include "../iobuf.h"
7 #include "../handy.h"
8 #include "../log.h"
9 #include "../prepend.h"
10 #include "../run_script.h"
11 #include "cvss.h"
12 #include "autoupgrade.h"
13 
receive_file(struct asfd * asfd,const char * autoupgrade_dir,const char * file,struct cntr * cntr)14 static int receive_file(struct asfd *asfd, const char *autoupgrade_dir,
15 	const char *file, struct cntr *cntr)
16 {
17 	int ret=0;
18 	char *incoming=NULL;
19 	if(!(incoming=prepend_s(autoupgrade_dir, file))) return -1;
20 	ret=receive_a_file(asfd, incoming, cntr);
21 	free_w(&incoming);
22 	return ret;
23 }
24 
autoupgrade_func(struct asfd * asfd,struct conf ** confs,void * param)25 static enum asl_ret autoupgrade_func(struct asfd *asfd,
26 	__attribute__ ((unused)) struct conf **confs,
27 	__attribute__ ((unused)) void *param)
28 {
29 	if(!strcmp(asfd->rbuf->buf, "do not autoupgrade"))
30 		return ASL_END_OK;
31 	if(strcmp(asfd->rbuf->buf, "autoupgrade ok"))
32 	{
33 		iobuf_log_unexpected(asfd->rbuf, __func__);
34 		return ASL_END_ERROR;
35 	}
36 	return ASL_END_OK_RETURN_1;
37 }
38 
autoupgrade_client(struct async * as,struct conf ** confs)39 int autoupgrade_client(struct async *as, struct conf **confs)
40 {
41 	int a=0;
42 	int ret=-1;
43 	char *cp=NULL;
44 	char *copy=NULL;
45 	char *script_path=NULL;
46 	char script_name[32]="";
47 	char package_name[32]="";
48 	char write_str[256]="";
49 	const char *args[2];
50 	struct iobuf *rbuf=NULL;
51 	struct asfd *asfd;
52 	char *autoupgrade_dir=get_string(confs[OPT_AUTOUPGRADE_DIR]);
53 	const char *autoupgrade_os=get_string(confs[OPT_AUTOUPGRADE_OS]);
54 	struct cntr *cntr=get_cntr(confs);
55 	asfd=as->asfd;
56 
57 	if(!autoupgrade_dir)
58 	{
59 		logp("autoupgrade_dir not set!\n");
60 		goto end;
61 	}
62 	if(!autoupgrade_os)
63 	{
64 		logp("autoupgrade_os not set!\n");
65 		goto end;
66 	}
67 	if(!(copy=strdup_w(autoupgrade_dir, __func__)))
68 		goto end;
69 
70 	strip_trailing_slashes(&copy);
71 	if((cp=strchr(copy, '/'))) *cp='\0';
72 	if(mkpath(&autoupgrade_dir, copy))
73 		goto end;
74 
75 	// Let the server know we are ready.
76 	snprintf(write_str, sizeof(write_str),
77 		"autoupgrade:%s", autoupgrade_os);
78 	if(asfd->write_str(asfd, CMD_GEN, write_str))
79 		goto end;
80 
81 	if(!(a=asfd->simple_loop(asfd,
82 		confs, NULL, __func__, autoupgrade_func)))
83 	{
84 		ret=0; // No autoupgrade.
85 		goto end;
86 	}
87 	else if(a<0) // Error.
88 		goto end;
89 
90 #ifdef HAVE_WIN32
91 	win32_enable_backup_privileges();
92 	snprintf(script_name, sizeof(script_name), "script.bat");
93 	snprintf(package_name, sizeof(package_name), "package.exe");
94 #else
95 	snprintf(script_name, sizeof(script_name), "script");
96 	snprintf(package_name, sizeof(package_name), "package");
97 #endif
98 
99 	if(receive_file(asfd, autoupgrade_dir, script_name, cntr))
100 	{
101 		logp("Problem receiving %s/%s\n",
102 			autoupgrade_dir, script_name);
103 		goto end;
104 	}
105 	if(receive_file(asfd, autoupgrade_dir, package_name, cntr))
106 	{
107 		logp("Problem receiving %s/%s\n",
108 			autoupgrade_dir, package_name);
109 		goto end;
110 	}
111 
112 	if(!(script_path=prepend_s(autoupgrade_dir, script_name)))
113 		goto end;
114 
115 	chmod(script_path, 0755);
116 
117 	/* Run the script here. */
118 	a=0;
119 	args[a++]=script_path;
120 	args[a++]=NULL;
121 	run_script(asfd, args, NULL, confs,
122 		0 /* do not wait */, 1 /* use logp */, 1 /* log_remote */);
123 	/* To get round Windows problems to do with installing over files
124 	   that the current process is running from, I am forking the child,
125 	   then immediately exiting the parent process. */
126 
127 	printf("\n");
128 	logp("The server tried to upgrade your client.\n");
129 	logp("You will need to try your command again.\n");
130 	asfd_flush_asio(asfd);
131 	asfd_free(&as->asfd);
132 
133 	exit(0);
134 end:
135 	free_w(&copy);
136 	free_w(&script_path);
137 	iobuf_free(&rbuf);
138 	return ret;
139 }
140