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(©);
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(©);
136 free_w(&script_path);
137 iobuf_free(&rbuf);
138 return ret;
139 }
140