Source for javax.security.auth.kerberos.KerberosPrincipal

   1: /* KerberosPrincipal.java -- a kerberos principal
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.security.auth.kerberos;
  40: 
  41: import gnu.classpath.NotImplementedException;
  42: import gnu.classpath.SystemProperties;
  43: 
  44: import java.io.Serializable;
  45: import java.security.Principal;
  46: 
  47: /**
  48:  * This represents a Kerberos principal.  See the Kerberos
  49:  * authentication RFC for more information:
  50:  * <a href="http://www.ietf.org/rfc/rfc1510.txt">RFC 1510</a>.
  51:  *
  52:  * @since 1.4
  53:  */
  54: public final class KerberosPrincipal
  55:     implements Serializable, Principal
  56: {
  57:   // Uncomment when serialization is correct.
  58:   // private static final long serialVersionUID = -7374788026156829911L;
  59: 
  60:   /**
  61:    * Constant from the RFC: "Just the name of the principal as in DCE, or
  62:    * for users".
  63:    */
  64:   public static final int KRB_NT_PRINCIPAL = 1;
  65: 
  66:   /**
  67:    * Constant from the RFC: "Service and other unique instance (krbtgt)".
  68:    */
  69:   public static final int KRB_NT_SRV_HST = 3;
  70: 
  71:   /**
  72:    * Constant from the RFC: "Service with host name as instance (telnet,
  73:    * rcommands)".
  74:    */
  75:   public static final int KRB_NT_SRV_INST = 2;
  76: 
  77:   /**
  78:    * Constant from the RFC: "Service with host as remaining components".
  79:    */
  80:   public static final int KRB_NT_SRV_XHST = 4;
  81: 
  82:   /**
  83:    * Constant from the RFC: "Unique ID".
  84:    */
  85:   public static final int KRB_NT_UID = 5;
  86: 
  87:   /**
  88:    * Constant from the RFC: "Name type not known".
  89:    */
  90:   public static final int KRB_NT_UNKNOWN = 0;
  91: 
  92:   private String name;
  93:   private int type;
  94:   private String realm;
  95: 
  96:   /**
  97:    * Create a new instance with the given name and a type of
  98:    * {@link #KRB_NT_PRINCIPAL}.
  99:    * @param name the principal's name
 100:    */
 101:   public KerberosPrincipal(String name)
 102:   {
 103:     this(name, KRB_NT_PRINCIPAL);
 104:   }
 105: 
 106:   /**
 107:    * Create a new instance with the given name and type.  The name is
 108:    * parsed according to the rules in the RFC.  If there is no realm,
 109:    * then the local realm is used instead.
 110:    * 
 111:    * @param name the principal's name
 112:    * @param type the principal's type
 113:    */
 114:   public KerberosPrincipal(String name, int type)
 115:   // Marked as unimplemented because we don't look for the realm as needed.
 116:     throws NotImplementedException
 117:   {
 118:     if (type < KRB_NT_UNKNOWN || type > KRB_NT_UID)
 119:       throw new IllegalArgumentException("unknown type: " + type);
 120:     this.name = name;
 121:     this.type = type;
 122:     this.realm = parseRealm();
 123:   }
 124: 
 125:   private String parseRealm()
 126:   {
 127:     // Handle quoting as specified by the Kerberos RFC.
 128:     int i, len = name.length();
 129:     boolean quoted = false;
 130:     for (i = 0; i < len; ++i)
 131:       {
 132:         if (quoted)
 133:           {
 134:             quoted = false;
 135:             continue;
 136:           }
 137:         char c = name.charAt(i);
 138:         if (c == '\\')
 139:           {
 140:             quoted = true;
 141:             continue;
 142:           }
 143:         if (c == '@')
 144:           break;
 145:       }
 146:     if (quoted || i == len - 1)
 147:       throw new IllegalArgumentException("malformed principal: " + name);
 148:     if (i < len)
 149:       {
 150:         // We have the realm.  FIXME: verify its syntax?
 151:         return name.substring(i + 1);
 152:       }
 153:     // Try to find the default realm.
 154:     String def = SystemProperties.getProperty("java.security.krb5.realm");
 155:     if (def != null)
 156:       return def;
 157:     // Now ask the system.
 158:     // FIXME: use java.security.krb5.conf,
 159:     // or $JAVA_HOME/lib/security/krb5.conf to find the krb config file.
 160:     // Then pass to native code using krb5_set_config_files() and
 161:     // krb5_get_default_realm().  But... what about /etc/krb5.conf?
 162:     throw new IllegalArgumentException("default realm can't be found");
 163:   }
 164: 
 165:   /**
 166:    * Return the name of this principal.
 167:    */
 168:   public String getName()
 169:   {
 170:     return name;
 171:   }
 172: 
 173:   /**
 174:    * Return the realm of this principal.
 175:    */
 176:   public String getRealm()
 177:   {
 178:     return realm;
 179:   }
 180: 
 181:   /**
 182:    * Return the type of this principal.
 183:    */
 184:   public int getNameType()
 185:   {
 186:     return type;
 187:   }
 188: 
 189:   public int hashCode()
 190:   {
 191:     return name.hashCode();
 192:   }
 193: 
 194:   public boolean equals(Object other)
 195:   {
 196:     if (! (other instanceof KerberosPrincipal))
 197:       return false;
 198:     KerberosPrincipal kp = (KerberosPrincipal) other;
 199:     return name.equals(kp.name) && type == kp.type;
 200:   }
 201: 
 202:   public String toString()
 203:   {
 204:     // This is what came to mind.
 205:     return name + ":" + type; 
 206:   }
 207: }