package com.objectgen.phpbb.util; import java.io.UnsupportedEncodingException; import java.security.GeneralSecurityException; import java.security.MessageDigest; /** * Port of phpBB3 password handling to Java. * See phpBB3/includes/functions.php * * @author lars */ public class PHPBB3Password { private static final int PHP_VERSION = 4; private String itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; public String phpbb_hash(String password) { String random_state = unique_id(); String random = ""; int count = 6; if (random.length() < count) { random = ""; for (int i = 0; i < count; i += 16) { random_state = md5(unique_id() + random_state); random += pack(md5(random_state)); } random = random.substring(0, count); } String hash = _hash_crypt_private(password, _hash_gensalt_private(random, itoa64)); if (hash.length() == 34) return hash; return md5(password); } private String unique_id() { return unique_id("c"); } // global $config; // private boolean dss_seeded = false; private String unique_id(String extra) { // String val = $config['rand_seed'] . microtime(); // val = md5(val); // $config['rand_seed'] = md5($config['rand_seed'] . $val . $extra); // // if ($dss_seeded !== true && ($config['rand_seed_last_update'] < // time() - rand(1,10))) // { // $config['rand_seed_last_update']=time(); // dss_seeded = true; // } // // return substr($val, 4, 16); // TODO Generate something random here. return "1234567890abcdef"; } private String _hash_gensalt_private(String input, String itoa64) { return _hash_gensalt_private(input, itoa64, 6); } private String _hash_gensalt_private(String input, String itoa64, int iteration_count_log2) { if (iteration_count_log2 < 4 || iteration_count_log2 > 31) { iteration_count_log2 = 8; } String output = "$H$"; output += itoa64.charAt(Math.min(iteration_count_log2 + ((PHP_VERSION >= 5) ? 5 : 3), 30)); output += _hash_encode64(input, 6); return output; } /** * Encode hash */ private String _hash_encode64(String input, int count) { String output = ""; int i = 0; do { int value = input.charAt(i++); output += itoa64.charAt(value & 0x3f); if (i < count) value |= input.charAt(i) << 8; output += itoa64.charAt((value >> 6) & 0x3f); if (i++ >= count) break; if (i < count) value |= input.charAt(i) << 16; output += itoa64.charAt((value >> 12) & 0x3f); if (i++ >= count) break; output += itoa64.charAt((value >> 18) & 0x3f); } while (i < count); return output; } String _hash_crypt_private(String password, String setting) { String output = "*"; // Check for correct hash if (!setting.substring(0, 3).equals("$H$")) return output; int count_log2 = itoa64.indexOf(setting.charAt(3)); if (count_log2 < 7 || count_log2 > 30) return output; int count = 1 << count_log2; String salt = setting.substring(4, 12); if (salt.length() != 8) return output; String m1 = md5(salt + password); String hash = pack(m1); do { hash = pack(md5(hash + password)); } while (--count > 0); output = setting.substring(0, 12); output += _hash_encode64(hash, 16); return output; } public boolean phpbb_check_hash(String password, String hash) { if (hash.length() == 34) return _hash_crypt_private(password, hash).equals(hash); else return md5(password).equals(hash); } public static String md5(String data) { try { byte[] bytes = data.getBytes("ISO-8859-1"); MessageDigest md5er = MessageDigest.getInstance("MD5"); byte[] hash = md5er.digest(bytes); return bytes2hex(hash); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } static int hexToInt(char ch) { if(ch >= '0' && ch <= '9') return ch - '0'; ch = Character.toUpperCase(ch); if(ch >= 'A' && ch <= 'F') return ch - 'A' + 0xA; throw new IllegalArgumentException("Not a hex character: " + ch); } private static String bytes2hex(byte[] bytes) { StringBuffer r = new StringBuffer(32); for (int i = 0; i < bytes.length; i++) { String x = Integer.toHexString(bytes[i] & 0xff); if (x.length() < 2) r.append("0"); r.append(x); } return r.toString(); } static String pack(String hex) { StringBuffer buf = new StringBuffer(); for(int i = 0; i < hex.length(); i += 2) { char c1 = hex.charAt(i); char c2 = hex.charAt(i+1); char packed = (char) (hexToInt(c1) * 16 + hexToInt(c2)); buf.append(packed); } return buf.toString(); } }
public class LoginClient { public static final String LOGGED_IN = "loggedIn"; public static final String ERROR = "error"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; private LoginServiceAsync loginService; private PropertySupport propertySupport = new PropertySupport("LoginClient"); private HashMap values = new HashMap(); public LoginClient(LoginServiceAsync loginService) { this.loginService = loginService; } public String toString() { return "LoginClient"; } private Object getValue(String name) { AutomaticPropertyListener.registerListener(propertySupport, name); return values.get(name); } private void setValue(String name, Object value) { Object oldValue = values.get(name); values.put(name, value); propertySupport.firePropertyChange(name, oldValue, value); } public String getError() { return (String) getValue(ERROR); } public void setError(String error) { setValue(ERROR, error); } public String getUsername() { return (String) getValue(USERNAME); } public void setUsername(String username) { setValue(USERNAME, username); } public String getPassword() { return (String) getValue(PASSWORD); } public void setPassword(String password) { setValue(PASSWORD, password); } public UserDTO getLoggedInUser() { return (UserDTO) getValue(LOGGED_IN); } public void setLoggedInUser(UserDTO user) { setValue(LOGGED_IN, user); } public void login() { setValue(ERROR, null); String username = (String) values.get(USERNAME); String password = (String) values.get(PASSWORD); loginService.login(username, password, new AsyncCallback() { public void onSuccess(Object result) { UserDTO user = (UserDTO) result; setLoggedInUser(user); if(user == null) setValue(ERROR, "Incorrect login"); } public void onFailure(Throwable e) { e.printStackTrace(); setValue(ERROR, e.getMessage()); } }); } }
public class UsersPanel extends Grid { private UserClient userClient; private FlexTable userList; private Label groupLabel; private ListBox groupList; private Label usernameLabel; private TextBox usernameField; private Label emailLabel; private TextBox emailField; private Label passwordLabel; private TextBox passwordField; private Button createUserButton; public UsersPanel() { super(1, 2); userList = new FlexTable(); ScrollPanel userListScrollPanel = new ScrollPanel(); userListScrollPanel.add(userList); userListScrollPanel.setHeight("300px"); Grid createUserForm = new Grid(5, 2); groupLabel = new Label("Group"); groupList = new ListBox(); usernameLabel = new Label("Username"); usernameField = new TextBox(); emailLabel = new Label("Email"); emailField = new TextBox(); passwordLabel = new Label("Password"); passwordField = new TextBox(); createUserButton = new Button(); createUserButton.setText("Create New User"); createUserForm.setWidget(0, 0, groupLabel); createUserForm.setWidget(0, 1, groupList); createUserForm.setWidget(1, 0, usernameLabel); createUserForm.setWidget(1, 1, usernameField); createUserForm.setWidget(2, 0, emailLabel); createUserForm.setWidget(2, 1, emailField); createUserForm.setWidget(3, 0, passwordLabel); createUserForm.setWidget(3, 1, passwordField); createUserForm.setWidget(4, 1, createUserButton); setWidget(0, 0, userListScrollPanel); setWidget(0, 1, createUserForm); } public void setUserClient(UserClient userClient) { this.userClient = userClient; start(); } private void start() { new AutomaticPropertyListener("UsersPanel.listUsers") { public void evaluate() { List users = userClient.getAllUsers(); setUsers(users); } }.start(); new AutomaticPropertyListener("UsersPanel.listGroups") { public void evaluate() { List groups = userClient.getAllGroups(); setGroups(groups); } }.start(); new AutomaticPropertyListener("UsersPanel.groupname") { public void evaluate() { String groupname = ListBoxValue.getInstance(groupList).getValue(); userClient.setGroupName(groupname); } }.start(); new AutomaticPropertyListener("UsersPanel.username") { public void evaluate() { String username = TextValue.getInstance(usernameField).getText(); userClient.setUsername(username); } }.start(); new AutomaticPropertyListener("UsersPanel.email") { public void evaluate() { String email = TextValue.getInstance(emailField).getText(); userClient.setEmail(email); } }.start(); new AutomaticPropertyListener("UsersPanel.password") { public void evaluate() { String password = TextValue.getInstance(passwordField).getText(); userClient.setPassword(password); } }.start(); new AutomaticPropertyListener("UsersPanel.createEnabled") { public void evaluate() { boolean createEnabled = userClient.isCreateEnabled(); createUserButton.setEnabled(createEnabled); } }.start(); createUserButton.addClickListener(new ClickListener() { public void onClick(Widget sender) { userClient.create(); } }); } private void setGroups(List groups) { groupList.clear(); if(groups != null) { for(Iterator i = groups.iterator(); i.hasNext(); ) { GroupDTO group = (GroupDTO) i.next(); groupList.addItem(group.getGroupName()); } } int index = groupList.getSelectedIndex(); String groupname = (index >= 0 ? groupList.getValue(index) : null); userClient.setGroupName(groupname); } private void setUsers(List users) { userList.clear(); Label username = new Label("Username"); userList.setWidget(0, 0, username); Label email = new Label("Email"); userList.setWidget(0, 1, email); int row = 1; if(users != null) { for(Iterator i = users.iterator(); i.hasNext(); ) { UserDTO user = (UserDTO) i.next(); userList.setText(row, 0, user.getUsername()); userList.setText(row, 1, user.getEmail()); row++; } } } }
public class UserClient { public static final String ALL_USERS = "allUsers"; public static final String ALL_GROUPS = "allGroups"; public static final String ERROR = "error"; public static final String GROUPNAME = "groupName"; public static final String USERNAME = "username"; public static final String EMAIL = "email"; public static final String PASSWORD = "password"; public static final String CREATE_ENABLED = "createEnabled"; private UserServiceAsync userService; private PropertySupport propertySupport = new PropertySupport("UserClient"); private HashMap values = new HashMap(); public UserClient(UserServiceAsync userService) { this.userService = userService; } public String toString() { return "UserClient"; } private Object getValue(String name) { AutomaticPropertyListener.registerListener(propertySupport, name); return values.get(name); } private void setValue(String name, Object value) { Object oldValue = values.get(name); values.put(name, value); propertySupport.firePropertyChange(name, oldValue, value); } public String getError() { return (String) getValue(ERROR); } public void setError(String error) { setValue(ERROR, error); } public String getGroupName() { return (String) getValue(GROUPNAME); } public void setGroupName(String groupName) { setValue(GROUPNAME, groupName); } public String getUsername() { return (String) getValue(USERNAME); } public void setUsername(String username) { setValue(USERNAME, username); } public String getEmail() { return (String) getValue(EMAIL); } public void setEmail(String password) { setValue(EMAIL, password); } public String getPassword() { return (String) getValue(PASSWORD); } public void setPassword(String password) { setValue(PASSWORD, password); } public List getAllUsers() { List allUsers = (List) getValue(ALL_USERS); if(allUsers == null) listUsers(); return allUsers; } public void setAllUsers(List list) { setValue(ALL_USERS, list); } private void listUsers() { userService.listUsers(new AsyncCallback() { public void onSuccess(Object result) { List allUsers = (List) result; setAllUsers(allUsers); } public void onFailure(Throwable e) { e.printStackTrace(); setValue(ERROR, e.getMessage()); } }); } public void create() { setValue(ERROR, null); userService.create(getGroupName(), getUsername(), getEmail(), getPassword(), new AsyncCallback() { public void onSuccess(Object result) { UserDTO user = (UserDTO) result; List allUsers = getAllUsers(); if(allUsers == null) allUsers = new ArrayList(); allUsers.add(user); setAllUsers(allUsers); } public void onFailure(Throwable e) { e.printStackTrace(); setValue(ERROR, e.getMessage()); } }); } public List getAllGroups() { List allGroups = (List) getValue(ALL_GROUPS); if(allGroups == null) listGroups(); return allGroups; } public void setAllGroups(List list) { setValue(ALL_GROUPS, list); } private void listGroups() { userService.listGroups(new AsyncCallback() { public void onSuccess(Object result) { List allGroups = (List) result; setAllGroups(allGroups); } public void onFailure(Throwable e) { e.printStackTrace(); setValue(ERROR, e.getMessage()); } }); } public boolean isCreateEnabled() { return isSet(getGroupName()) && isSet(getUsername()) && isSet(getEmail()) && isSet(getPassword()); } private boolean isSet(String s) { return s != null && !"".equals(s); } }
public class LoginServiceImpl extends RemoteServiceServlet implements LoginService { private transient HibernateHelper persistenceHelper = HibernateHelper.getInstance(); private MapperIF mapper = new DozerBeanMapper(); private UserDAO userDAO = new UserDAO(); public LoginServiceImpl() { } public UserDTO login(final String username, final String password) { javax.persistence.EntityManager entityManager = persistenceHelper.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin(); try { User user = userDAO.login("ADMINISTRATORS", username, password); UserDTO dto = (user != null ? (UserDTO) mapper.map(user, UserDTO.class) : null); tx.commit(); return dto; } catch(RuntimeException e) { e.printStackTrace(); tx.rollback(); throw e; } } }
public class UserServiceImpl extends RemoteServiceServlet implements UserService { private transient HibernateHelper persistenceHelper = HibernateHelper.getInstance(); private MapperIF mapper = new DozerBeanMapper(); private UserDAO userDAO = new UserDAO(); private PHPBB3Password passwordUtil = new PHPBB3Password(); public UserServiceImpl() { } public UserDTO create(String groupName, String username, String email, String password) { javax.persistence.EntityManager entityManager = persistenceHelper.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin(); try { Group group = userDAO.findGroupByName(groupName); if(group == null) throw new IllegalArgumentException("No such group: " + groupName); String encryptedPassword = passwordUtil.phpbb_hash(password); User user = new User(); user.setUsername(username); user.setUsernameClean(username); user.setEmail(email); user.setPassword(encryptedPassword); user.setGroup(group); group.addUser(user); int userId = userDAO.create(user); user.setId(userId); tx.commit(); return (UserDTO) mapper.map(user, UserDTO.class); } catch(RuntimeException e) { e.printStackTrace(); tx.rollback(); throw e; } } public List<UserDTO> listUsers() { javax.persistence.EntityManager entityManager = persistenceHelper.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin(); try { List<User> list = userDAO.list(); List<UserDTO> dtoList = new ArrayList<UserDTO>(); for(User user : list) { UserDTO dto = (UserDTO) mapper.map(user, UserDTO.class); dtoList.add(dto); } tx.commit(); return dtoList; } catch(RuntimeException e) { e.printStackTrace(); tx.rollback(); throw e; } } public List<GroupDTO> listGroups() { javax.persistence.EntityManager entityManager = persistenceHelper.getEntityManager(); EntityTransaction tx = entityManager.getTransaction(); tx.begin(); try { List<Group> list = userDAO.listGroups(); List<GroupDTO> dtoList = new ArrayList<GroupDTO>(); for(Group g : list) { GroupDTO dto = (GroupDTO) mapper.map(g, GroupDTO.class); dtoList.add(dto); } tx.commit(); return dtoList; } catch(RuntimeException e) { e.printStackTrace(); tx.rollback(); throw e; } } }
Copyright © 2011 Object Generation AB