Collection syntax change because of Sonar
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / taf / dos / DenialOfServiceTaf.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.cadi.taf.dos;
23
24 import java.io.BufferedReader;
25 import java.io.File;
26 import java.io.FileOutputStream;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.io.PrintStream;
30 import java.util.ArrayList;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.List;
34 import java.util.Map;
35
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38
39 import org.onap.aaf.cadi.Access;
40 import org.onap.aaf.cadi.CachedPrincipal;
41 import org.onap.aaf.cadi.CadiException;
42 import org.onap.aaf.cadi.CachedPrincipal.Resp;
43 import org.onap.aaf.cadi.Taf.LifeForm;
44 import org.onap.aaf.cadi.config.Config;
45 import org.onap.aaf.cadi.taf.HttpTaf;
46 import org.onap.aaf.cadi.taf.PuntTafResp;
47 import org.onap.aaf.cadi.taf.TafResp;
48 import org.onap.aaf.cadi.taf.TafResp.RESP;
49
50 public class DenialOfServiceTaf implements HttpTaf {
51         private static Map<String, Counter> deniedIP=null, deniedID=null;
52         private Access access;
53         private final TafResp puntNotDenied;
54         private static File dosIP, dosID;
55         
56         /**
57          * 
58          * @param hostname
59          * @param prod
60          * @throws CadiException
61          */
62         public DenialOfServiceTaf(Access access) throws CadiException {
63                 puntNotDenied = new PuntTafResp("DenialOfServiceTaf", "This Transaction is not denied");
64                 this.access = access;
65                 if(dosIP==null || dosID == null) {
66                         String dirStr;
67                         if((dirStr = access.getProperty(Config.AAF_DATA_DIR, null))!=null) {
68                                 dosIP = new File(dirStr+"/dosIP");
69                                 readIP();
70                                 dosID = new File(dirStr+"/dosID");
71                                 readID();
72                         }
73                 }
74         }
75
76         @Override
77         public TafResp validate(LifeForm reading, HttpServletRequest req, final HttpServletResponse resp) {
78                 // Performance, when not needed
79                 if(deniedIP != null) {
80                         String ip;
81                         Counter c = deniedIP.get(ip=req.getRemoteAddr());
82                         if(c!=null) {
83                                 c.inc();
84                                 return respDenyIP(access,ip);
85                         }
86                 }
87                 
88                 // Note:  Can't process Principal, because this is the first TAF, and no Principal is created.
89                 // Other TAFs use "isDenied()" on this Object to validate.
90                 return puntNotDenied;
91         }
92
93         @Override
94         public Resp revalidate(CachedPrincipal prin, Object state) {
95                 // We always return NOT MINE, because DOS Taf does not ever validate
96                 return Resp.NOT_MINE;
97         }
98
99         /*
100          *  for use in Other TAFs, before they attempt backend validation of 
101          */
102         public static Counter isDeniedID(String identity) {
103                 if(deniedID!=null) {
104                         return deniedID.get(identity);
105                 }
106                 return null;
107         }
108         
109         /**
110          *  
111          */
112         public static Counter isDeniedIP(String ipvX) {
113                 if(deniedIP!=null) {
114                         return deniedIP.get(ipvX);
115                 }
116                 return null;
117         }
118
119         /**
120          * Return of "True" means IP has been added.
121          * Return of "False" means IP already added.
122          * 
123          * @param ip
124          * @return
125          */
126         public static synchronized boolean denyIP(String ip) {
127                 boolean rv = false;
128                 if(deniedIP==null) {
129                         deniedIP = new HashMap<>();
130                         deniedIP.put(ip, new Counter(ip)); // Noted duplicated for minimum time spent
131                         rv= true;
132                 } else if(deniedIP.get(ip)==null) {
133                         deniedIP.put(ip, new Counter(ip));
134                         rv = true;
135                 }
136                 if(rv) {
137                         writeIP();
138                 }
139                 return rv;
140         }
141         
142         private static void writeIP() {
143                 if(dosIP!=null && deniedIP!=null) {
144                         if(deniedIP.isEmpty()) {
145                                 if(dosIP.exists()) {
146                                         dosIP.delete();
147                                 }
148                         } else {
149                                 PrintStream fos;
150                                 try {
151                                         fos = new PrintStream(new FileOutputStream(dosIP,false));
152                                         try {
153                                                 for(String ip: deniedIP.keySet()) {
154                                                         fos.println(ip);
155                                                 }
156                                         } finally {
157                                                 fos.close();
158                                         }
159                                 } catch (IOException e) {
160                                         e.printStackTrace(System.err);
161                                 }
162                         }
163                 }
164         }
165         
166         private static void readIP() {
167                 if(dosIP!=null && dosIP.exists()) {
168                         BufferedReader br;
169                         try {
170                                 br = new BufferedReader(new FileReader(dosIP));
171                                 try {
172                                         if(deniedIP==null) {
173                                                 deniedIP=new HashMap<>();
174                                         }
175
176                                         String line;
177                                         while((line=br.readLine())!=null) {
178                                                 deniedIP.put(line, new Counter(line));
179                                         }
180                                 } finally {
181                                         br.close();
182                                 }
183                         } catch (IOException e) {
184                                 e.printStackTrace(System.err);
185                         }
186                 }
187         }
188
189
190         /**
191          * Return of "True" means IP has was removed.
192          * Return of "False" means IP wasn't being denied.
193          * 
194          * @param ip
195          * @return
196          */
197         public static synchronized boolean removeDenyIP(String ip) {
198                 if(deniedIP!=null && deniedIP.remove(ip)!=null) {
199                         writeIP();
200                         if(deniedIP.isEmpty()) {
201                                 deniedIP=null;
202                         }
203                         return true;
204                 }
205                 return false;
206         }
207
208         /**
209          * Return of "True" means ID has been added.
210          * Return of "False" means ID already added.
211          * 
212          * @param ip
213          * @return
214          */
215         public static synchronized boolean denyID(String id) {
216                 boolean rv = false;
217                 if(deniedID==null) {
218                         deniedID = new HashMap<>();
219                         deniedID.put(id, new Counter(id)); // Noted duplicated for minimum time spent
220                         rv = true;
221                 } else if(deniedID.get(id)==null) {
222                         deniedID.put(id, new Counter(id));
223                         rv = true;
224                 }
225                 if(rv) {
226                         writeID();
227                 }
228                 return rv;
229
230         }
231
232         private static void writeID() {
233                 if(dosID!=null && deniedID!=null) {
234                         if(deniedID.isEmpty()) {
235                                 if(dosID.exists()) {
236                                         dosID.delete();
237                                 }
238                         } else {
239                                 PrintStream fos;
240                                 try {
241                                         fos = new PrintStream(new FileOutputStream(dosID,false));
242                                         try {
243                                                 for(String ip: deniedID.keySet()) {
244                                                         fos.println(ip);
245                                                 }
246                                         } finally {
247                                                 fos.close();
248                                         }
249                                 } catch (IOException e) {
250                                         e.printStackTrace(System.err);
251                                 }
252                         }
253                 }
254         }
255
256         private static void readID() {
257                 if(dosID!=null && dosID.exists()) {
258                         BufferedReader br;
259                         try {
260                                 br = new BufferedReader(new FileReader(dosID));
261                                 try {
262                                         if(deniedID==null) {
263                                                 deniedID=new HashMap<>();
264                                         }
265                                         
266                                         String line;
267                                         while((line=br.readLine())!=null) {
268                                                 deniedID.put(line, new Counter(line));
269                                         }
270                                 } finally {
271                                         br.close();
272                                 }
273                         } catch (IOException e) {
274                                 e.printStackTrace(System.err);
275                         }
276                 }
277         }
278
279         /**
280          * Return of "True" means ID has was removed.
281          * Return of "False" means ID wasn't being denied.
282          * 
283          * @param ip
284          * @return
285          */
286         public static synchronized boolean removeDenyID(String id) {
287                 if(deniedID!=null && deniedID.remove(id)!=null) { 
288                         writeID();
289                         if(deniedID.isEmpty()) {
290                                 deniedID=null;
291                         }
292
293                         return true;
294                 }
295                 return false;
296         }
297         
298         public List<String> report() {
299                 int initSize = 0;
300                 if(deniedIP!=null)initSize+=deniedIP.size();
301                 if(deniedID!=null)initSize+=deniedID.size();
302                 ArrayList<String> al = new ArrayList<>(initSize);
303                 if(deniedID!=null) {
304                         for(Counter c : deniedID.values()) {
305                                 al.add(c.toString());
306                         }
307                 }
308                 if(deniedIP!=null) {
309                         for(Counter c : deniedIP.values()) {
310                                 al.add(c.toString());
311                         }
312                 }
313                 return al;
314         }
315         
316         public static class Counter {
317                 private final String name; 
318                 private int count = 0;
319                 private Date first;
320                 private long last; // note, we use "last" as long, to avoid popping useless dates on Heap.
321                 
322                 public Counter(String name) {
323                         this.name = name;
324                         first = null;
325                         last = 0L;
326                         count = 0;
327                 }
328                 
329                 public String getName() {
330                         return name;
331                 }
332                 
333                 public int getCount() {
334                         return count;
335                 }
336
337                 public long getLast() {
338                         return last;
339                 }
340                 
341                 /*
342                  * Only allow Denial of ServiceTaf to increment
343                  */
344                 private synchronized void inc() {
345                         ++count;
346                         last = System.currentTimeMillis();
347                         if(first==null) {
348                                 first = new Date(last);
349                         }
350                 }
351                 
352                 public String toString() {
353                         if(count==0) 
354                                 return name + " is on the denied list, but has not attempted Access"; 
355                         else 
356                                 return 
357                                         name +
358                                         " has been denied " +
359                                         count +
360                                         " times since " +
361                                         first +
362                                         ".  Last denial was " +
363                                         new Date(last);
364                 }
365         }
366
367         public static TafResp respDenyID(Access access, String identity) {
368                 return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, identity + " is on the Identity Denial list");
369         }
370         
371         public static TafResp respDenyIP(Access access, String ip) {
372                 return new DenialOfServiceTafResp(access, RESP.NO_FURTHER_PROCESSING, ip + " is on the IP Denial list");
373         }
374
375 }