package local.server; import org.zoolu.sip.provider.SipStack; import org.zoolu.tools.Parser; import org.zoolu.tools.Base64; import java.util.Hashtable; import java.util.Enumeration; import java.io.*; /** AuthenticationServiceImpl is a simple implementation of a AuthenticationService. * AuthenticationServiceImpl allows creation and maintainance of a * AAA service for registered users. */ public class AuthenticationServiceImpl implements AuthenticationService { /** AuthenticationService name */ String filename=null; /** Whether the AuthenticationService DB has been changed without saving */ boolean changed=false; /** Users AAA DB. Set of pairs of { (String)user , (UserAuthInfo)binding }. */ Hashtable users; /** Void byte array. */ private static final byte[] NULL_ARRAY=new byte[0]; /** Creates a new AuthenticationService. */ public AuthenticationServiceImpl(String file_name) { filename=file_name; users=new Hashtable(); load(); } // **************** Methods of interface Registry **************** /** Syncronizes the database. * <p> Can be used, for example, to save the current memory image of the DB. */ public void sync() { if (changed) save(); } /** Returns the numbers of users in the database. * @return the numbers of user entries */ public int size() { return users.size(); } /** Returns an enumeration of the users in this database. * @return the list of user names as an Enumeration of String */ public Enumeration getUsers() { return users.keys(); } /** Whether a user is present in the database and can be used as key. * @param user the user name * @return true if the user name is present as key */ public boolean hasUser(String user) { return (users.containsKey(user)); } /** Adds a new user at the database. * @param user the user name * @return this object */ public Repository addUser(String user) { addUser(user,NULL_ARRAY); return this; } /** Removes the user from the database. * @param user the user name * @return this object */ public Repository removeUser(String user) { users.remove(user); changed=true; return this; } /** Removes all users from the database. * @return this object */ public Repository removeAllUsers() { users.clear(); changed=true; return this; } // **************** Methods of interface AuthenticationService **************** /** Adds a new user at the database. * @param user the user name * @param key the user key * @return this object */ public AuthenticationService addUser(String user, byte[] key) { if (hasUser(user)) return this; UserAuthInfo ur=new UserAuthInfo(user,key); users.put(user,ur); changed=true; return this; } /** Sets the user key */ public AuthenticationService setUserKey(String user, byte[] key) { UserAuthInfo ur=getUserAuthInfo(user); if (ur!=null) { ur.setKey(key); changed=true; } return this; } /** Gets the user key */ public byte[] getUserKey(String user) { if (hasUser(user)) return getUserAuthInfo(user).getKey(); else return null; } // ******************************* New methods ******************************* /** Returns the name of the database. */ public String getName() { return filename; } /** Whether the database is changed. */ public boolean isChanged() { return changed; } /** Adds a user record in the database */ private void addUserAuthInfo(UserAuthInfo ur) { if (hasUser(ur.getName())) removeUser(ur.getName()); users.put(ur.getName(),ur); } /** Gets the record of the user */ private UserAuthInfo getUserAuthInfo(String user) { return (UserAuthInfo)users.get(user); } /** Returns an enumeration of the values in this database */ private Enumeration getUserAuthInfos() { return users.elements(); } /** Loads the database */ public void load() { BufferedReader in=null; changed=false; try { in = new BufferedReader(new FileReader(filename)); } catch (FileNotFoundException e) { System.err.println("WARNING: file \""+filename+"\" not found: created new empty DB"); return; } String user=null; byte[] key=NULL_ARRAY; while (true) { String line=null; try { line=in.readLine(); } catch (Exception e) { e.printStackTrace(); System.exit(0); } if (line==null) break; Parser par=new Parser(line); if (line.startsWith("#")) continue; if (line.startsWith("user")) { if (user!=null) addUser(user,key); user=par.goTo('=').skipChar().getString(); key=NULL_ARRAY; continue; } if (line.startsWith("key")) { key=Base64.decode(par.goTo('=').skipChar().getString()); continue; } if (line.startsWith("passwd")) { key=par.goTo('=').skipChar().getString().getBytes(); continue; } } if (user!=null) addUser(user,key); try { in.close(); } catch (Exception e) { e.printStackTrace(); } } /** Saves the database */ public void save() { BufferedWriter out=null; changed=false; try { out=new BufferedWriter(new FileWriter(filename)); out.write(this.toString()); out.close(); } catch (IOException e) { System.err.println("WARNING: error trying to write on file \""+filename+"\""); return; } } /** Gets the String value of this Object. * @return the String value */ public String toString() { String str=""; for (Enumeration e=getUserAuthInfos(); e.hasMoreElements(); ) { UserAuthInfo ur=(UserAuthInfo)e.nextElement(); str+=ur.toString(); //str+="\r\n"; } return str; } } /** User's authentication info. * This class represents a user record of the AAA DB. */ class UserAuthInfo { /** User name */ String name; String getName() { return name; } void setName(String name) { this.name=name; } /** User key */ byte[] key; byte[] getKey() { return key; } void setKey(byte[] key) { this.key=key; } /** Gets the String value of this Object. * @return the String value */ public String toString() { String str=""; str+="user= "+name+"\r\n"; str+="key= "+Base64.encode(key)+"\r\n"; return str; } /** Costructs a new UserAuthInfo for user <i>name</i> * @param name the user name */ UserAuthInfo(String name, byte[] key) { this.name=name; this.key=key; } }