View Javadoc
1   package com.jsql.util;
2   
3   import com.jsql.model.InjectionModel;
4   import org.apache.commons.lang3.StringUtils;
5   import org.apache.logging.log4j.LogManager;
6   import org.apache.logging.log4j.Logger;
7   
8   import java.io.File;
9   import java.net.Authenticator;
10  import java.net.PasswordAuthentication;
11  import java.util.prefs.Preferences;
12  
13  /**
14   * Manage authentication protocols Basic, Digest, NTLM and Kerberos.
15   * Java class Authenticator processes Basic, Digest and NTLM, library spnego
16   * processes kerberos.
17   */
18  public class AuthenticationUtil {
19      
20      private static final Logger LOGGER = LogManager.getRootLogger();
21      
22      /**
23       * True if standard authentication Basic, Digest, NTLM is activated.
24       */
25      private boolean isAuthentication = false;
26  
27      /**
28       * Login for standard authentication.
29       */
30      private String usernameAuthentication;
31  
32      /**
33       * Pass for standard authentication.
34       */
35      private String passwordAuthentication;
36      
37      /**
38       * True if kerberos authentication is activated.
39       */
40      private boolean isKerberos = false;
41  
42      /**
43       * Path to the kerberos file login.
44       */
45      private String pathKerberosLogin;
46  
47      /**
48       * Path to the kerberos file krb5.
49       */
50      private String pathKerberosKrb5;
51  
52      /**
53       * Get new authentication settings from the view, update the utility class,
54       * persist settings to the JVM and apply changes to the system.
55       * @param isAuthentication true if non-kerberos authentication is activated
56       * @param usernameAuthentication login for standard authentication
57       * @param passwordAuthentication pass for standard authentication
58       * @param isKerberos true if krb authentication is activated
59       * @param kerberosKrb5Conf path to the file krb5
60       * @param kerberosLoginConf path to the file login
61       */
62      public boolean set(
63          boolean isAuthentication,
64          String usernameAuthentication,
65          String passwordAuthentication,
66          boolean isKerberos,
67          String kerberosKrb5Conf,
68          String kerberosLoginConf
69      ) {
70          boolean isRestartRequired = this.initKerberos(isKerberos, kerberosKrb5Conf, kerberosLoginConf);
71          this.initSimpleAuthorization(isAuthentication, usernameAuthentication, passwordAuthentication);
72          this.setAuthentication();
73          return isRestartRequired;
74      }
75  
76      public void initSimpleAuthorization(boolean isAuthentication, String usernameAuthentication, String passwordAuthentication) {
77          var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
78          preferences.putBoolean("isAuthentication", isAuthentication);
79          preferences.put("usernameAuthentication", usernameAuthentication);
80          preferences.put("passwordAuthentication", passwordAuthentication);
81          // Define proxy settings
82          this.isAuthentication = isAuthentication;
83          this.usernameAuthentication = usernameAuthentication;
84          this.passwordAuthentication = passwordAuthentication;
85      }
86  
87      private boolean initKerberos(boolean isKerberos, String kerberosKrb5Conf, String kerberosLoginConf) {
88          // Persist to JVM
89          var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
90          
91          this.isKerberos = isKerberos;
92          this.pathKerberosKrb5 = kerberosKrb5Conf;
93          this.pathKerberosLogin = kerberosLoginConf;
94          
95          // Check if krb file has changed
96          boolean isRestartRequired = this.isKerberos
97              && !new File(this.pathKerberosKrb5).exists()
98              && !kerberosKrb5Conf.equals(this.pathKerberosKrb5);
99          
100         preferences.putBoolean("enableKerberos", this.isKerberos);
101         preferences.put("kerberosKrb5Conf", this.pathKerberosKrb5);
102         preferences.put("kerberosLoginConf", this.pathKerberosLogin);
103         
104         // Check krb integrity
105         if (this.isKerberos) {
106             // Fix #23877: NoClassDefFoundError on java/nio/file/Paths
107             if (!new File(this.pathKerberosKrb5).exists()) {
108                 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Krb5 file not found: {}", this.pathKerberosKrb5);
109             }
110             if (!new File(this.pathKerberosLogin).exists()) {
111                 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Login file not found: {}", this.pathKerberosLogin);
112             }
113         }
114         return isRestartRequired;
115     }
116     
117     /**
118      * Initialize the utility class with preferences from the JVM
119      * and apply environment settings.
120      */
121     public void setKerberosCifs() {
122         // Use Preferences API to persist proxy configuration
123         var preferences = Preferences.userRoot().node(InjectionModel.class.getName());
124 
125         // Default proxy disabled
126         this.isAuthentication = preferences.getBoolean("isAuthentication", false);
127 
128         // Default TOR config
129         this.usernameAuthentication = preferences.get("usernameAuthentication", StringUtils.EMPTY);
130         this.passwordAuthentication = preferences.get("passwordAuthentication", StringUtils.EMPTY);
131         
132         this.isKerberos = preferences.getBoolean("enableKerberos", false);
133         this.pathKerberosKrb5 = preferences.get("kerberosKrb5Conf", StringUtils.EMPTY);
134         this.pathKerberosLogin = preferences.get("kerberosLoginConf", StringUtils.EMPTY);
135         
136         this.setAuthentication();
137     }
138     
139     /**
140      * Apply kerberos authentication to the JVM.
141      */
142     public void setAuthentication() {
143         Authenticator.setDefault(null);
144         if (this.isAuthentication) {
145             Authenticator.setDefault(new Authenticator() {
146                 @Override
147                 protected PasswordAuthentication getPasswordAuthentication() {
148                     return new PasswordAuthentication (
149                         AuthenticationUtil.this.usernameAuthentication,
150                         AuthenticationUtil.this.passwordAuthentication.toCharArray()
151                     );
152                 }
153             });
154         } else {
155             Authenticator.setDefault(null);
156         }
157         if (this.isKerberos) {
158             System.setProperty("java.security.krb5.conf", this.pathKerberosKrb5);
159             System.setProperty("java.security.auth.login.config", this.pathKerberosLogin);
160             System.setProperty("spnego.krb5.conf", this.pathKerberosKrb5);
161             System.setProperty("spnego.login.conf", this.pathKerberosLogin);
162         } else {
163             System.setProperty("java.security.krb5.conf", StringUtils.EMPTY);
164             System.setProperty("java.security.auth.login.config", StringUtils.EMPTY);
165             System.setProperty("spnego.krb5.conf", StringUtils.EMPTY);
166             System.setProperty("spnego.login.conf", StringUtils.EMPTY);
167         }
168     }
169     
170     
171     // Getters and setters
172 
173     public boolean isAuthentEnabled() {
174         return this.isAuthentication;
175     }
176 
177     public String getPathKerberosLogin() {
178         return this.pathKerberosLogin;
179     }
180 
181     public String getPathKerberosKrb5() {
182         return this.pathKerberosKrb5;
183     }
184 
185     public boolean isKerberos() {
186         return this.isKerberos;
187     }
188 
189     public String getUsernameAuthentication() {
190         return this.usernameAuthentication;
191     }
192 
193     public String getPasswordAuthentication() {
194         return this.passwordAuthentication;
195     }
196     
197     
198     // Builder
199     
200     public AuthenticationUtil withAuthenticationEnabled() {
201         this.isAuthentication = true;
202         return this;
203     }
204     
205     public AuthenticationUtil withUsernameAuthentication(String usernameAuthentication) {
206         this.usernameAuthentication = usernameAuthentication;
207         return this;
208     }
209     
210     public AuthenticationUtil withPasswordAuthentication(String passwordAuthentication) {
211         this.passwordAuthentication = passwordAuthentication;
212         return this;
213     }
214 }