1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.gateway.ftp.exec;
21
22 import org.waarp.common.command.exception.CommandAbstractException;
23 import org.waarp.common.future.WaarpFuture;
24 import org.waarp.common.guid.GUID;
25 import org.waarp.common.logging.WaarpLogger;
26 import org.waarp.common.logging.WaarpLoggerFactory;
27 import org.waarp.common.utility.WaarpStringUtils;
28 import org.waarp.gateway.kernel.session.CommandExecutorInterface;
29 import org.waarp.gateway.kernel.session.HttpAuthInterface;
30
31 import java.util.regex.Pattern;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public abstract class AbstractExecutor {
65
66
67
68 private static final WaarpLogger logger =
69 WaarpLoggerFactory.getLogger(AbstractExecutor.class);
70 protected static final Pattern BLANK = WaarpStringUtils.BLANK;
71
72 protected static final String USER = "#USER#";
73 protected static final String ACCOUNT = "#ACCOUNT#";
74 protected static final String BASEPATH = "#BASEPATH#";
75 protected static final String FILE = "#FILE#";
76 protected static final String COMMAND = "#COMMAND#";
77 protected static final String SPECIALID = "#SPECIALID#";
78 protected static final String S_UUID = "#UUID#";
79
80 protected static final String REFUSED = "REFUSED";
81 protected static final String NONE = "NONE";
82 protected static final String EXECUTE = "EXECUTE";
83 protected static final String JAVAEXECUTE = "JAVAEXECUTE";
84 protected static final String R66PREPARETRANSFER = "R66PREPARETRANSFER";
85
86 protected static final int T_REFUSED = -1;
87 protected static final int T_NONE = 0;
88 protected static final int T_EXECUTE = 1;
89 protected static final int T_R_66_PREPARETRANSFER = 2;
90 protected static final int T_JAVAEXECUTE = 3;
91
92 protected static CommandExecutor commandExecutor;
93
94
95
96
97 public static boolean useDatabase;
98
99
100
101
102 public static boolean useLocalExec;
103
104 public static class CommandExecutor implements CommandExecutorInterface {
105
106
107
108 public final String pretrCMD;
109 public final int pretrType;
110 private boolean pretrRefused;
111
112
113
114 private long pretrDelay;
115
116
117
118 public final String pstorCMD;
119 public final int pstorType;
120 private boolean pstorRefused;
121
122
123
124 private long pstorDelay;
125
126
127
128
129
130
131
132 public CommandExecutor(final String retrieve, final long retrDelay,
133 final String store, final long storDelay) {
134 if (retrieve == null || retrieve.trim().length() == 0) {
135 pretrCMD = commandExecutor.pretrCMD;
136 pretrType = commandExecutor.pretrType;
137 setPretrRefused(commandExecutor.isPretrRefused());
138 } else if (isRefused(retrieve)) {
139 pretrCMD = REFUSED;
140 pretrType = T_REFUSED;
141 setPretrRefused(true);
142 } else {
143 if (isExecute(retrieve)) {
144 pretrCMD = getExecuteCmd(retrieve);
145 pretrType = T_EXECUTE;
146 } else if (isR66PrepareTransfer(retrieve)) {
147 pretrCMD = getR66PrepareTransferCmd(retrieve);
148 pretrType = T_R_66_PREPARETRANSFER;
149 useDatabase = true;
150 } else if (isJavaExecute(retrieve)) {
151 pretrCMD = getJavaExecuteCmd(retrieve);
152 pretrType = T_JAVAEXECUTE;
153 } else {
154
155 pretrCMD = getNone(retrieve);
156 pretrType = T_NONE;
157 }
158 }
159 setPretrDelay(retrDelay);
160 if (store == null || store.trim().length() == 0) {
161 pstorCMD = commandExecutor.pstorCMD;
162 setPstorRefused(commandExecutor.isPstorRefused());
163 pstorType = commandExecutor.pstorType;
164 } else if (isRefused(store)) {
165 pstorCMD = REFUSED;
166 setPstorRefused(true);
167 pstorType = T_REFUSED;
168 } else {
169 if (isExecute(store)) {
170 pstorCMD = getExecuteCmd(store);
171 pstorType = T_EXECUTE;
172 } else if (isR66PrepareTransfer(store)) {
173 pstorCMD = getR66PrepareTransferCmd(store);
174 pstorType = T_R_66_PREPARETRANSFER;
175 useDatabase = true;
176 } else if (isJavaExecute(store)) {
177 pstorCMD = getJavaExecuteCmd(store);
178 pstorType = T_JAVAEXECUTE;
179 } else {
180
181 pstorCMD = getNone(store);
182 pstorType = T_NONE;
183 }
184 }
185 setPstorDelay(storDelay);
186 }
187
188 private static String getNone(final String cmd) {
189 return cmd.substring(NONE.length()).trim();
190 }
191
192 private static String getExecuteCmd(final String cmd) {
193 return cmd.substring(EXECUTE.length()).trim();
194 }
195
196 private static String getJavaExecuteCmd(final String cmd) {
197 return cmd.substring(JAVAEXECUTE.length()).trim();
198 }
199
200 private static String getR66PrepareTransferCmd(final String cmd) {
201 return cmd.substring(R66PREPARETRANSFER.length()).trim();
202 }
203
204 private static boolean isRefused(final String cmd) {
205 return cmd.startsWith(REFUSED);
206 }
207
208 private static boolean isExecute(final String cmd) {
209 return cmd.startsWith(EXECUTE);
210 }
211
212 private static boolean isJavaExecute(final String cmd) {
213 return cmd.startsWith(JAVAEXECUTE);
214 }
215
216 private static boolean isR66PrepareTransfer(final String cmd) {
217 return cmd.startsWith(R66PREPARETRANSFER);
218 }
219
220 @Override
221 public final boolean isValidOperation(final boolean isStore) {
222 if (isStore && isPstorRefused()) {
223 logger.info("STORe like operations REFUSED");
224 return false;
225 } else if (!isStore && isPretrRefused()) {
226 logger.info("RETRieve operations REFUSED");
227 return false;
228 }
229 return true;
230 }
231
232 @Override
233 public final String getRetrType() {
234 switch (pretrType) {
235 case T_REFUSED:
236 return REFUSED;
237 case T_EXECUTE:
238 return EXECUTE;
239 case T_R_66_PREPARETRANSFER:
240 return R66PREPARETRANSFER;
241 case T_JAVAEXECUTE:
242 return JAVAEXECUTE;
243 default:
244 return NONE;
245 }
246 }
247
248 @Override
249 public final String getStorType() {
250 switch (pstorType) {
251 case T_REFUSED:
252 return REFUSED;
253 case T_EXECUTE:
254 return EXECUTE;
255 case T_R_66_PREPARETRANSFER:
256 return R66PREPARETRANSFER;
257 case T_JAVAEXECUTE:
258 return JAVAEXECUTE;
259 default:
260 return NONE;
261 }
262 }
263
264
265
266
267 public final boolean isPretrRefused() {
268 return pretrRefused;
269 }
270
271
272
273
274 public final void setPretrRefused(final boolean pretrRefused) {
275 this.pretrRefused = pretrRefused;
276 }
277
278
279
280
281 public final long getPretrDelay() {
282 return pretrDelay;
283 }
284
285
286
287
288 public final void setPretrDelay(final long pretrDelay) {
289 this.pretrDelay = pretrDelay;
290 }
291
292
293
294
295 public final boolean isPstorRefused() {
296 return pstorRefused;
297 }
298
299
300
301
302 public final void setPstorRefused(final boolean pstorRefused) {
303 this.pstorRefused = pstorRefused;
304 }
305
306
307
308
309 public final long getPstorDelay() {
310 return pstorDelay;
311 }
312
313
314
315
316 public final void setPstorDelay(final long pstorDelay) {
317 this.pstorDelay = pstorDelay;
318 }
319 }
320
321
322
323
324
325
326
327
328
329 public static void initializeExecutor(final String retrieve,
330 final long retrDelay,
331 final String store,
332 final long storDelay) {
333 commandExecutor =
334 new CommandExecutor(retrieve, retrDelay, store, storDelay);
335 if (logger.isInfoEnabled()) {
336 logger.info(
337 "Executor configured as [RETR: " + commandExecutor.getRetrType() +
338 ':' + commandExecutor.pretrCMD + ':' +
339 commandExecutor.getPretrDelay() + ':' +
340 commandExecutor.isPretrRefused() + "] [STOR: " +
341 commandExecutor.getStorType() + ':' + commandExecutor.pstorCMD + ':' +
342 commandExecutor.getPstorDelay() + ':' +
343 commandExecutor.isPstorRefused() + ']');
344 }
345 }
346
347
348
349
350
351
352
353
354 public static boolean isValidOperation(final boolean isStore) {
355 return commandExecutor.isValidOperation(isStore);
356 }
357
358
359
360
361
362
363
364
365
366 public static AbstractExecutor createAbstractExecutor(
367 final HttpAuthInterface auth, final String[] args, final boolean isStore,
368 final WaarpFuture futureCompletion) {
369 if (isStore) {
370 CommandExecutor executor = (CommandExecutor) auth.getCommandExecutor();
371 if (executor == null) {
372 executor = commandExecutor;
373 } else if (executor.pstorType == T_NONE) {
374 final String replaced = getPreparedCommand(executor.pstorCMD, args);
375 return new NoTaskExecutor(replaced, executor.getPstorDelay(),
376 futureCompletion);
377 }
378 if (executor.isPstorRefused()) {
379 logger.error("STORe like operation REFUSED");
380 futureCompletion.cancel();
381 return null;
382 }
383 final String replaced = getPreparedCommand(executor.pstorCMD, args);
384 switch (executor.pstorType) {
385 case T_REFUSED:
386 logger.error("STORe like operation REFUSED");
387 futureCompletion.cancel();
388 return null;
389 case T_EXECUTE:
390 return new ExecuteExecutor(replaced, executor.getPstorDelay(),
391 futureCompletion);
392 case T_JAVAEXECUTE:
393 return new JavaExecutor(replaced, executor.getPstorDelay(),
394 futureCompletion);
395 case T_R_66_PREPARETRANSFER:
396 return new R66PreparedTransferExecutor(replaced,
397 executor.getPstorDelay(),
398 futureCompletion);
399 default:
400 return new NoTaskExecutor(replaced, executor.getPstorDelay(),
401 futureCompletion);
402 }
403 } else {
404 CommandExecutor executor = (CommandExecutor) auth.getCommandExecutor();
405 if (executor == null) {
406 executor = commandExecutor;
407 } else if (executor.pretrType == T_NONE) {
408 final String replaced = getPreparedCommand(executor.pretrCMD, args);
409 return new NoTaskExecutor(replaced, executor.getPretrDelay(),
410 futureCompletion);
411 }
412 if (executor.isPretrRefused()) {
413 logger.error("RETRieve operation REFUSED");
414 futureCompletion.cancel();
415 return null;
416 }
417 final String replaced = getPreparedCommand(executor.pretrCMD, args);
418 switch (executor.pretrType) {
419 case T_REFUSED:
420 logger.error("RETRieve operation REFUSED");
421 futureCompletion.cancel();
422 return null;
423 case T_EXECUTE:
424 return new ExecuteExecutor(replaced, executor.getPretrDelay(),
425 futureCompletion);
426 case T_JAVAEXECUTE:
427 return new JavaExecutor(replaced, executor.getPretrDelay(),
428 futureCompletion);
429 case T_R_66_PREPARETRANSFER:
430 return new R66PreparedTransferExecutor(replaced,
431 executor.getPretrDelay(),
432 futureCompletion);
433 default:
434 return new NoTaskExecutor(replaced, executor.getPretrDelay(),
435 futureCompletion);
436 }
437 }
438 }
439
440
441
442
443
444
445
446
447
448 public static String getPreparedCommand(final String command,
449 final String[] args) {
450 final StringBuilder builder = new StringBuilder(command);
451 logger.debug(
452 "Will replace value in {} with User={}:Acct={}:Base={}:File={}:Cmd={}",
453 command, args[0], args[1], args[2], args[3], args[4]);
454 replaceAll(builder, USER, args[0]);
455 replaceAll(builder, ACCOUNT, args[1]);
456 replaceAll(builder, BASEPATH, args[2]);
457 replaceAll(builder, FILE, args[3]);
458 replaceAll(builder, COMMAND, args[4]);
459 replaceAll(builder, SPECIALID, args[5]);
460 if (builder.indexOf(S_UUID) > 0) {
461 replaceAll(builder, S_UUID, new GUID().toString());
462 }
463 logger.debug("Result: {}", builder);
464 return builder.toString();
465 }
466
467
468
469
470
471
472
473
474
475 public static boolean replace(final StringBuilder builder, final String find,
476 final String replace) {
477 final int start = builder.indexOf(find);
478 if (start == -1) {
479 return false;
480 }
481 final int end = start + find.length();
482 builder.replace(start, end, replace);
483 return true;
484 }
485
486
487
488
489
490
491
492
493
494 public static void replaceAll(final StringBuilder builder, final String find,
495 final String replace) {
496 while (replace(builder, find, replace)) {
497
498 }
499 }
500
501 public static CommandExecutor getCommandExecutor() {
502 return commandExecutor;
503 }
504
505 public abstract void run() throws CommandAbstractException;
506 }