001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.business.utils;
020:
021: import java.io.FileInputStream;
022: import java.io.FileOutputStream;
023: import java.sql.Connection;
024: import java.sql.DriverManager;
025: import java.sql.PreparedStatement;
026: import java.sql.ResultSet;
027: import java.util.Enumeration;
028: import java.util.Properties;
029: import org.apache.roller.util.Utilities;
030:
031: /**
032: * Roller password utility: don't run this unless you know what you are doing!</br >
033: *
034: * <p>Configuration:<br />
035: *
036: * Program looks in current directory for db.properties file with database
037: * connection properties driverClassName and connectionUrl.
038: *
039: * Program expects JDBC driver jar to be on classpath.</p>
040: *
041: * <p>Usage:<br />
042: *
043: * java -cp ./WEB-INF/lib/rollerbeans.jar;./jdbc.jar org.apache.roller.business.utils.PasswordUtility<br />
044: *
045: * <br />Options:<br />
046: *
047: * -save <file-name>: Save username/passwords in property file<br />
048: * -encrypt : turn on encryption and encrypt passwords<br />
049: * -restore <file-name> : turn off encryption and restore passwords from file<br />
050: * -reset <username> <password>: reset users password<br />
051: * -grant_admin <username><br />
052: * -revoke_admin <username></p>
053: */
054: public class PasswordUtility {
055: public static void main(String[] args) throws Exception {
056: Properties props = new Properties();
057: props.load(new FileInputStream("rollerdb.properties"));
058:
059: String algorithm = props.getProperty("algorithm");
060:
061: Connection con = ConsistencyCheck.createConnection(props, "");
062:
063: if (args.length == 2 && args[0].equals("-save")) {
064: savePasswords(con, args[1]);
065: } else if (args.length == 1 && args[0].equals("-encrypt")) {
066: encryptionOn(con, algorithm);
067: } else if (args.length == 2 && args[0].equals("-restore")) {
068: encryptionOff(con, args[1]);
069: } else if (args.length == 3 && args[0].equals("-reset")) {
070: resetPassword(con, args[1], args[2], algorithm);
071: } else if (args.length == 2 && args[0].equals("-grant_admin")) {
072: grantAdmin(con, args[1]);
073: } else if (args.length == 2 && args[0].equals("-revoke_admin")) {
074: revokeAdmin(con, args[1]);
075: } else {
076: System.out.println("");
077: System.out
078: .println("USAGE: save passwords to a properties file");
079: System.out.println(" rollerpw -save <file-name>");
080: System.out.println("");
081: System.out
082: .println("USAGE: turn ON password encryption and encrypt existing passwords");
083: System.out.println(" rollerpw -encrypt");
084: System.out.println("");
085: System.out
086: .println("USAGE: turn OFF password encryption and restore saved passwords");
087: System.out.println(" rollerpw -restore <file-name>");
088: System.out.println("");
089: System.out.println("USAGE: reset a user password");
090: System.out
091: .println(" rollerpw -password <username> <new-password>");
092: System.out.println("");
093: System.out.println("USAGE: grant admin rights to user");
094: System.out.println(" rollerpw -grant_admin <username>");
095: System.out.println("");
096: System.out.println("USAGE: revoke admin right from user");
097: System.out.println(" rollerpw -revoke_admin <username>");
098: System.out.println("");
099: }
100: }
101:
102: /**
103: * Saves usernames and passwords to properties file, passwords keyed by usernames
104: */
105: private static void savePasswords(Connection con, String fileName)
106: throws Exception {
107: Properties newprops = new Properties();
108: PreparedStatement userquery = con
109: .prepareStatement("select username,passphrase from rolleruser");
110: ResultSet users = userquery.executeQuery();
111: while (users.next()) {
112: String username = users.getString(1);
113: String passphrase = users.getString(2);
114: newprops.put(username, passphrase);
115: }
116: FileOutputStream fos = new FileOutputStream(fileName);
117: newprops.save(fos, "Generated by Roller Password Utility");
118: fos.close();
119: }
120:
121: /**
122: * Encrypt all passwords in rolleruser and turn ON encryption flag in rollerconfig
123: */
124: private static void encryptionOn(Connection con, String algorithm)
125: throws Exception {
126: PreparedStatement userQuery = con
127: .prepareStatement("select username,passphrase from rolleruser");
128: PreparedStatement userUpdate = con
129: .prepareStatement("update rolleruser set passphrase=? where username=?");
130: PreparedStatement configUpdate = con
131: .prepareStatement("update rollerconfig set encryptpasswords=?");
132:
133: Properties props = new Properties();
134: ResultSet users = userQuery.executeQuery();
135: while (users.next()) {
136: String username = users.getString(1);
137: String passphrase = users.getString(2);
138: props.put(username, passphrase);
139: }
140: Enumeration usernames = props.keys();
141: while (usernames.hasMoreElements()) {
142: String username = (String) usernames.nextElement();
143: String passphrase = (String) props.get(username);
144: userUpdate.clearParameters();
145: userUpdate.setString(1, Utilities.encodePassword(
146: passphrase, algorithm));
147: userUpdate.setString(2, username);
148: userUpdate.executeUpdate();
149: System.out.println("Encrypted password for user: "
150: + username);
151: }
152:
153: configUpdate.setBoolean(1, true);
154: configUpdate.executeUpdate();
155: }
156:
157: /**
158: * Restore passwords in rolleruser and turn OFF encryption flag in rollerconfig
159: */
160: private static void encryptionOff(Connection con, String fileName)
161: throws Exception {
162: PreparedStatement userUpdate = con
163: .prepareStatement("update rolleruser set passphrase=? where username=?");
164: PreparedStatement configUpdate = con
165: .prepareStatement("update rollerconfig set encryptpasswords=?");
166:
167: Properties props = new Properties();
168: props.load(new FileInputStream(fileName));
169: Enumeration usernames = props.keys();
170: while (usernames.hasMoreElements()) {
171: String username = (String) usernames.nextElement();
172: String password = (String) props.get(username);
173: userUpdate.clearParameters();
174: userUpdate.setString(1, password);
175: userUpdate.setString(2, username);
176: userUpdate.executeUpdate();
177: }
178:
179: configUpdate.setBoolean(1, false);
180: configUpdate.executeUpdate();
181: }
182:
183: /**
184: * Reset user's password to specified value using specified algorythm (if needed)
185: */
186: private static void resetPassword(Connection con, String username,
187: String password, String algorithm) throws Exception {
188: PreparedStatement encryptionQuery = con
189: .prepareStatement("select encryptpasswords from rollerconfig");
190: PreparedStatement userUpdate = con
191: .prepareStatement("update rolleruser set passphrase=? where username=?");
192:
193: ResultSet rs = encryptionQuery.executeQuery();
194: rs.next();
195: boolean encryption = rs.getBoolean(1);
196:
197: String newpassword = encryption ? Utilities.encodePassword(
198: password, algorithm) : password;
199: userUpdate.setString(1, newpassword);
200: userUpdate.setString(2, username);
201: userUpdate.executeUpdate();
202: }
203:
204: /**
205: * Grant admin role to user by adding admin role for user to userrole table
206: */
207: private static void grantAdmin(Connection con, String userName)
208: throws Exception {
209: // Find userid of specified user
210: String userid = null;
211: PreparedStatement userQuery = con
212: .prepareStatement("select id from rolleruser where username=?");
213: userQuery.setString(1, userName);
214: ResultSet userRS = userQuery.executeQuery();
215: if (!userRS.next()) {
216: System.err.println("ERROR: username not found in database");
217: return;
218: } else {
219: userid = userRS.getString(1);
220: }
221:
222: // Is user already an admin?
223: PreparedStatement roleQuery = con
224: .prepareStatement("select username from userrole where username=? and rolename='admin'");
225: roleQuery.setString(1, userName);
226: ResultSet roleRS = roleQuery.executeQuery();
227: if (!roleRS.next()) // then no, user is not admin
228: {
229: // Add admin role for user
230: PreparedStatement adminInsert = con
231: .prepareStatement("insert into userrole (id,rolename,username,userid) values (?,?,?,?)");
232: adminInsert.setString(1, userName);
233: adminInsert.setString(2, "admin");
234: adminInsert.setString(3, userName);
235: adminInsert.setString(4, userid);
236: adminInsert.executeUpdate();
237: System.out.println("User granted admin role");
238: } else {
239: System.out.println("User was already an admin");
240: }
241: }
242:
243: /**
244: * Revoke admin role from user by removing admin role from userrole table
245: */
246: private static void revokeAdmin(Connection con, String userName)
247: throws Exception {
248: // Find userid of specified user
249: String userid = null;
250: PreparedStatement userQuery = con
251: .prepareStatement("select id from rolleruser where username=?");
252: userQuery.setString(1, userName);
253: ResultSet userRS = userQuery.executeQuery();
254: if (!userRS.next()) {
255: System.err.println("ERROR: username not found in database");
256: return;
257: } else {
258: userid = userRS.getString(1);
259: }
260:
261: // Delete user's admin entries from userrole table
262: PreparedStatement roleDelete = con
263: .prepareStatement("delete from userrole where userid=? and rolename='admin'");
264: roleDelete.setString(1, userid);
265: roleDelete.executeUpdate();
266: }
267: }
|