Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

114
LINES

< > BotCompany Repo | #1032110 // Screenshot Service (use with #1032109)

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 1113K of libraries. Click here for Pure Java version (10741L/56K).

1  
!7
2  
3  
sclass IPInfo {
4  
  S ip;
5  
  Timestamp firstSeen, lastSeen, blockUntil;
6  
  long passwordFails, passwordSuccesses;
7  
  Timestamp lastPasswordSuccess, lastPasswordFail;
8  
  long blockedRequests;
9  
  Bool allowed;
10  
  
11  
  bool isEvil() { ret blockUntil != null; }
12  
}
13  
14  
static MapSO _renameClasses = litmap("SalterService" := "ScreenshotService");
15  
16  
cm ScreenshotService > DynPrintLogAndEnabled {
17  
  !include early #1029545 // API for Eleu
18  
  
19  
  switchable S password = aGlobalID();
20  
  switchable int badPWBlockSeconds = 30;
21  
22  
  Map<S, IPInfo> ipsSeen = syncLinkedHashMap();
23  
  
24  
  start {  // to show warnings early
25  
    canServe();
26  
    printIPsSeen();
27  
  }
28  
  
29  
  void printIPsSeen aka printStats() {
30  
    var list = cloneValues(ipsSeen);
31  
    print(n2(list, "IP") + " seen." + stringIf(empty(list), " I am a virgin."));
32  
    for (IPInfo info : list)
33  
      print("Known client IP: " + info.ip
34  
        + appendBracketed_comma(
35  
          info.isEvil() ? "evil" : "good",
36  
          info.passwordFails == 0 ? ""
37  
            : n2(info.passwordSuccesses, "normal request") + ", last: "
38  
              + info.lastPasswordSuccess,
39  
          info.passwordFails == 0 ? ""
40  
            : n2(info.passwordFails, "password failures") + ", last: " + info.lastPasswordFail,
41  
          n2UnlessZero(info.blockedRequests, "blocked requests")));
42  
  }
43  
  
44  
  O html(IWebRequest req) ctex {
45  
    if (!canServe()) ret "Can't serve";
46  
47  
    S ip = req.clientIP();
48  
    IPInfo ipInfo = getOrCreate(ipsSeen, ip, () -> {
49  
      print("New client IP!! " + ip);
50  
      new IPInfo info;
51  
      info.ip = ip;
52  
      info.lastSeen = new Timestamp;
53  
      if (info.firstSeen == null) info.firstSeen = info.lastSeen;
54  
      change();
55  
      ret info;
56  
    });
57  
    
58  
    // Don't allow brute-force password checking
59  
    
60  
    if (ipInfo.blockUntil != null && cmp(ipInfo.blockUntil, new Timestamp) > 0) {
61  
      print("Request from blocked IP: " + ip);
62  
      ipInfo.blockedRequests++;
63  
      change();
64  
      ret print("Not allowed (evil IP)");
65  
    }
66  
67  
    S uri = req.uri();
68  
    print("Serving to IP " + ip + ": " + uri);
69  
    
70  
    if (isFalse(ipInfo.allowed))
71  
      ret print("Not allowed (bad IP)");
72  
      
73  
    S suppliedPW = req.get("password");
74  
    if (empty(suppliedPW)) ret "Need password";
75  
    
76  
    if (!eq(password, suppliedPW)) {
77  
      ++ipInfo.passwordFails;
78  
      ipInfo.lastPasswordFail = new Timestamp;
79  
      change();
80  
      print("Password FAIL from " + ip + " OK");
81  
      if ((ipInfo.passwordFails % 10) == 0) {
82  
        infoMessage(n2(ipInfo.passwordFails) + " password fails from " + ip + "!!!!");
83  
        print("Blocking " + ip + " for " + badPWBlockSeconds + " seconds");
84  
        ipInfo.blockUntil = new Timestamp(nowPlusSeconds(badPWBlockSeconds));
85  
        change();
86  
      }
87  
      ret "Bad PW";
88  
    }
89  
    
90  
    ++ipInfo.passwordSuccesses;
91  
    ipInfo.lastPasswordSuccess = new Timestamp;
92  
    change();
93  
    print("Password from " + ip + " OK");
94  
95  
    ret subBot_serveJPEG(shootScreen2());
96  
  }
97  
  
98  
  bool canServe() {
99  
    if (!enabled) ret false with print("Disabled");
100  
    if (l(password) < 4) ret false with warn("Not starting - password too short!!");
101  
    true;
102  
  }
103  
  
104  
  void forgetIPsSeen() {
105  
    ipsSeen.clear();
106  
    change();
107  
    print("Mandatory memory wipe done.");
108  
    printIPsSeen();
109  
  }
110  
  
111  
  enhanceFrame {
112  
    addInternalFrameTitleMenuItem(f/JInternalFrame, "Print Stats", rThreadEnter printStats);
113  
  }
114  
}

Author comment

Began life as a copy of #1031702

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx

No comments. add comment

Snippet ID: #1032110
Snippet name: Screenshot Service (use with #1032109)
Eternal ID of this version: #1032110/28
Text MD5: 87219990f2a03b647b03f581e581a2b5
Transpilation MD5: cff253e7030ac4056c9905ea00cd7403
Author: stefan
Category: javax
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-08-14 02:26:41
Source code size: 3457 bytes / 114 lines
Pitched / IR pitched: No / No
Views / Downloads: 225 / 1739
Version history: 27 change(s)
Referenced in: [show references]