Line data Source code
1 : #include "burp.h"
2 : #include "alloc.h"
3 : #include "cmd.h"
4 : #include "iobuf.h"
5 : #include "log.h"
6 : #include "msg.h"
7 : #include "pathcmp.h"
8 :
9 378 : struct iobuf *iobuf_alloc(void)
10 : {
11 : struct iobuf *iobuf;
12 378 : if(!(iobuf=(struct iobuf *)calloc_w(1, sizeof(struct iobuf), __func__)))
13 : return NULL;
14 378 : iobuf_init(iobuf);
15 378 : return iobuf;
16 : }
17 :
18 364660 : void iobuf_set(struct iobuf *iobuf, enum cmd cmd, char *buf, size_t len)
19 : {
20 3082357 : iobuf->cmd=cmd;
21 3082357 : iobuf->buf=buf;
22 3082357 : iobuf->len=len;
23 364660 : }
24 :
25 549681 : void iobuf_init(struct iobuf *iobuf)
26 : {
27 2296438 : iobuf_set(iobuf, CMD_ERROR, NULL, 0);
28 549681 : }
29 :
30 1746002 : void iobuf_free_content(struct iobuf *iobuf)
31 : {
32 1746002 : if(!iobuf) return;
33 1746379 : free_w(&iobuf->buf);
34 : iobuf_init(iobuf);
35 : }
36 :
37 387 : void iobuf_free(struct iobuf **iobuf)
38 : {
39 387 : if(!iobuf || !*iobuf) return;
40 756 : iobuf_free_content(*iobuf);
41 378 : free_v((void **)iobuf);
42 : }
43 :
44 12 : void iobuf_log_unexpected(struct iobuf *iobuf, const char *func)
45 : {
46 12 : logp("unexpected command in %s(): %s\n",
47 : func, iobuf_to_printable(iobuf));
48 12 : }
49 :
50 17208 : void iobuf_copy(struct iobuf *dst, struct iobuf *src)
51 : {
52 611482 : iobuf_set(dst, src->cmd, src->buf, src->len);
53 17208 : }
54 :
55 288533 : void iobuf_move(struct iobuf *dst, struct iobuf *src)
56 : {
57 288533 : iobuf_copy(dst, src);
58 288533 : src->buf=NULL;
59 288533 : }
60 :
61 115518 : void iobuf_from_str(struct iobuf *iobuf, enum cmd cmd, char *str)
62 : {
63 231036 : iobuf_set(iobuf, cmd, str, strlen(str));
64 115518 : }
65 :
66 382107 : int iobuf_send_msg_fzp(struct iobuf *iobuf, struct fzp *fzp)
67 : {
68 382107 : return send_msg_fzp(fzp, iobuf->cmd, iobuf->buf, iobuf->len);
69 : }
70 :
71 150824 : int iobuf_pathcmp(struct iobuf *a, struct iobuf *b)
72 : {
73 : int r;
74 150824 : if((r=pathcmp(a->buf, b->buf))) return r;
75 144431 : if(a->cmd==CMD_METADATA || a->cmd==CMD_ENC_METADATA)
76 : {
77 51 : if(b->cmd==CMD_METADATA || b->cmd==CMD_ENC_METADATA) return 0;
78 9 : else return 1;
79 : }
80 144380 : else if(a->cmd==CMD_VSS || a->cmd==CMD_ENC_VSS)
81 : {
82 40 : if(b->cmd==CMD_VSS || b->cmd==CMD_ENC_VSS) return 0;
83 0 : else return -1;
84 : }
85 144340 : else if(a->cmd==CMD_VSS_T || a->cmd==CMD_ENC_VSS_T)
86 : {
87 8 : if(b->cmd==CMD_VSS_T || b->cmd==CMD_ENC_VSS_T) return 0;
88 0 : else return 1;
89 : }
90 : else
91 : {
92 144332 : if(b->cmd==CMD_METADATA || b->cmd==CMD_ENC_METADATA) return -1;
93 144324 : else if(b->cmd==CMD_VSS || b->cmd==CMD_ENC_VSS) return 1;
94 144324 : else if(b->cmd==CMD_VSS_T || b->cmd==CMD_ENC_VSS_T) return -1;
95 144324 : else return 0;
96 : }
97 : }
98 :
99 261246 : int iobuf_is_filedata(struct iobuf *iobuf)
100 : {
101 261246 : return cmd_is_filedata(iobuf->cmd);
102 : }
103 :
104 10832 : int iobuf_is_vssdata(struct iobuf *iobuf)
105 : {
106 10832 : return cmd_is_vssdata(iobuf->cmd);
107 : }
108 :
109 110 : int iobuf_is_link(struct iobuf *iobuf)
110 : {
111 110 : return cmd_is_link(iobuf->cmd);
112 : }
113 :
114 85249 : int iobuf_is_encrypted(struct iobuf *iobuf)
115 : {
116 85249 : return cmd_is_encrypted(iobuf->cmd);
117 : }
118 :
119 117 : int iobuf_is_metadata(struct iobuf *iobuf)
120 : {
121 117 : return cmd_is_metadata(iobuf->cmd);
122 : }
123 :
124 0 : int iobuf_is_estimatable(struct iobuf *iobuf)
125 : {
126 0 : return cmd_is_estimatable(iobuf->cmd);
127 : }
128 :
129 368396 : static int do_iobuf_fill_from_fzp(struct iobuf *iobuf, struct fzp *fzp,
130 : int extra_bytes)
131 : {
132 : unsigned int s;
133 368396 : char lead[6]="";
134 : char command;
135 : int r;
136 :
137 368396 : r=fzp_read_ensure(fzp, lead, sizeof(lead)-1, __func__);
138 368396 : lead[5]='\0';
139 368396 : switch(r)
140 : {
141 : case 0: break; // OK.
142 : case 1: return 1; // Finished OK.
143 : default:
144 : {
145 14 : logp("Error reading lead in %s\n", __func__);
146 14 : return -1; // Error.
147 : }
148 : }
149 367830 : if((sscanf(lead, "%c%04X", &command, &s))!=2)
150 : {
151 0 : logp("sscanf failed reading manifest: %s\n", lead);
152 0 : return -1;
153 : }
154 367830 : iobuf->cmd=(enum cmd)command;
155 367830 : iobuf->len=(size_t)s;
156 367830 : if(!(iobuf->buf=(char *)malloc_w(
157 367830 : iobuf->len+extra_bytes+1, __func__)))
158 : return -1;
159 367830 : switch(fzp_read_ensure(fzp,
160 367830 : iobuf->buf, iobuf->len+extra_bytes, __func__))
161 : {
162 : case 0: break; // OK.
163 : case 1: return 1; // Finished OK.
164 : default:
165 45 : logp("Error attempting to read after %s in %s (%c:%u)\n", lead, __func__, iobuf->cmd, s);
166 45 : return -1;
167 : }
168 367785 : iobuf->buf[iobuf->len]='\0';
169 367785 : return 0;
170 : }
171 :
172 368080 : int iobuf_fill_from_fzp(struct iobuf *iobuf, struct fzp *fzp)
173 : {
174 368080 : return do_iobuf_fill_from_fzp(iobuf, fzp, 1 /*newline*/);
175 : }
176 :
177 316 : int iobuf_fill_from_fzp_data(struct iobuf *iobuf, struct fzp *fzp)
178 : {
179 316 : return do_iobuf_fill_from_fzp(iobuf, fzp, 0 /*no newline*/);
180 : }
181 :
182 80 : static int is_printable(struct iobuf *iobuf)
183 : {
184 : size_t l;
185 903 : for(l=0; l<iobuf->len; l++)
186 903 : if(!isprint(iobuf->buf[l]) && iobuf->buf[l]!='\n')
187 : return 0;
188 : return 1;
189 : }
190 :
191 80 : const char *iobuf_to_printable(struct iobuf *iobuf)
192 : {
193 : static char str[256]="";
194 80 : if(is_printable(iobuf))
195 160 : snprintf(str, sizeof(str),
196 80 : "%c:%04X:%s", iobuf->cmd, (int)iobuf->len, iobuf->buf);
197 : else
198 0 : snprintf(str, sizeof(str),
199 0 : "%c:%04X:(binary data)", iobuf->cmd, (int)iobuf->len);
200 80 : return str;
201 : }
202 :
203 69122 : int iobuf_relative_path_attack(struct iobuf *iobuf)
204 : {
205 69122 : if(!has_dot_component(iobuf->buf))
206 : return 0;
207 0 : iobuf_log_unexpected(iobuf, __func__);
208 0 : return 1;
209 : }
210 :
|