| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
/*  | 
 | 
 *  | 
 | 
 *  (C) Copyright IBM Corp. 1999 All Rights Reserved.  | 
 | 
 *  Copyright 1997 The Open Group Research Institute.  All rights reserved.  | 
 | 
 */  | 
 | 
 | 
 | 
package sun.security.krb5.internal;  | 
 | 
 | 
 | 
import sun.security.krb5.Config;  | 
 | 
import sun.security.krb5.Asn1Exception;  | 
 | 
import sun.security.util.*;  | 
 | 
import java.net.InetAddress;  | 
 | 
import java.net.Inet4Address;  | 
 | 
import java.net.Inet6Address;  | 
 | 
import java.net.UnknownHostException;  | 
 | 
import java.io.IOException;  | 
 | 
import java.util.Arrays;  | 
 | 
 | 
 | 
/**  | 
 | 
 * Implements the ASN.1 HostAddress type.  | 
 | 
 *  | 
 | 
 * <pre>{@code | 
 | 
 * HostAddress     ::= SEQUENCE  { | 
 | 
 *         addr-type       [0] Int32,  | 
 | 
 *         address         [1] OCTET STRING  | 
 | 
 * }  | 
 | 
 * }</pre>  | 
 | 
 *  | 
 | 
 * <p>  | 
 | 
 * This definition reflects the Network Working Group RFC 4120  | 
 | 
 * specification available at  | 
 | 
 * <a href="http://www.ietf.org/rfc/rfc4120.txt">  | 
 | 
 * http://www.ietf.org/rfc/rfc4120.txt</a>.  | 
 | 
 */  | 
 | 
 | 
 | 
public class HostAddress implements Cloneable { | 
 | 
    int addrType;  | 
 | 
    byte[] address = null;  | 
 | 
 | 
 | 
    private static InetAddress localInetAddress;   | 
 | 
    private static final boolean DEBUG = sun.security.krb5.internal.Krb5.DEBUG;  | 
 | 
    private volatile int hashCode = 0;  | 
 | 
 | 
 | 
    private HostAddress(int dummy) {} | 
 | 
 | 
 | 
    public Object clone() { | 
 | 
        HostAddress new_hostAddress = new HostAddress(0);  | 
 | 
        new_hostAddress.addrType = addrType;  | 
 | 
        if (address != null) { | 
 | 
            new_hostAddress.address = address.clone();  | 
 | 
        }  | 
 | 
        return new_hostAddress;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    public int hashCode() { | 
 | 
        if (hashCode == 0) { | 
 | 
            int result = 17;  | 
 | 
            result = 37*result + addrType;  | 
 | 
            if (address != null) { | 
 | 
                for (int i=0; i < address.length; i++)  { | 
 | 
                    result = 37*result + address[i];  | 
 | 
                }  | 
 | 
            }  | 
 | 
            hashCode = result;  | 
 | 
        }  | 
 | 
        return hashCode;  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean equals(Object obj) { | 
 | 
        if (this == obj) { | 
 | 
            return true;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (!(obj instanceof HostAddress)) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
 | 
 | 
        HostAddress h = (HostAddress)obj;  | 
 | 
        if (addrType != h.addrType ||  | 
 | 
            (address != null && h.address == null) ||  | 
 | 
            (address == null && h.address != null))  | 
 | 
            return false;  | 
 | 
        if (address != null && h.address != null) { | 
 | 
            if (address.length != h.address.length)  | 
 | 
                return false;  | 
 | 
            for (int i = 0; i < address.length; i++)  | 
 | 
                if (address[i] != h.address[i])  | 
 | 
                    return false;  | 
 | 
        }  | 
 | 
        return true;  | 
 | 
    }  | 
 | 
 | 
 | 
    private static synchronized InetAddress getLocalInetAddress()  | 
 | 
        throws UnknownHostException { | 
 | 
 | 
 | 
        if (localInetAddress == null) { | 
 | 
           localInetAddress = InetAddress.getLocalHost();  | 
 | 
        }  | 
 | 
        if (localInetAddress == null) { | 
 | 
            throw new UnknownHostException();  | 
 | 
        }  | 
 | 
        return (localInetAddress);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public InetAddress getInetAddress() throws UnknownHostException { | 
 | 
          | 
 | 
        if (addrType == Krb5.ADDRTYPE_INET ||  | 
 | 
            addrType == Krb5.ADDRTYPE_INET6) { | 
 | 
            return (InetAddress.getByAddress(address));  | 
 | 
        } else { | 
 | 
              | 
 | 
            return null;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private int getAddrType(InetAddress inetAddress) { | 
 | 
        int addressType = 0;  | 
 | 
        if (inetAddress instanceof Inet4Address)  | 
 | 
            addressType = Krb5.ADDRTYPE_INET;  | 
 | 
        else if (inetAddress instanceof Inet6Address)  | 
 | 
            addressType = Krb5.ADDRTYPE_INET6;  | 
 | 
        return (addressType);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
    public HostAddress() throws UnknownHostException { | 
 | 
        InetAddress inetAddress = getLocalInetAddress();  | 
 | 
        addrType = getAddrType(inetAddress);  | 
 | 
        address = inetAddress.getAddress();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public HostAddress(int new_addrType, byte[] new_address)  | 
 | 
        throws KrbApErrException, UnknownHostException { | 
 | 
        switch(new_addrType) { | 
 | 
        case Krb5.ADDRTYPE_INET:          | 
 | 
            if (new_address.length != 4)  | 
 | 
                throw new KrbApErrException(0, "Invalid Internet address");  | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_CHAOS:  | 
 | 
            if (new_address.length != 2)   | 
 | 
                throw new KrbApErrException(0, "Invalid CHAOSnet address");  | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_ISO:     | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_IPX:     | 
 | 
            if (new_address.length != 6)  | 
 | 
                throw new KrbApErrException(0, "Invalid XNS address");  | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_APPLETALK:    | 
 | 
            if (new_address.length != 3)  | 
 | 
                throw new KrbApErrException(0, "Invalid DDP address");  | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_DECNET:      | 
 | 
            if (new_address.length != 2)  | 
 | 
                throw new KrbApErrException(0, "Invalid DECnet Phase IV address");  | 
 | 
            break;  | 
 | 
        case Krb5.ADDRTYPE_INET6:       | 
 | 
            if (new_address.length != 16)  | 
 | 
                throw new KrbApErrException(0, "Invalid Internet IPv6 address");  | 
 | 
            break;  | 
 | 
        }  | 
 | 
 | 
 | 
        addrType = new_addrType;  | 
 | 
        if (new_address != null) { | 
 | 
           address = new_address.clone();  | 
 | 
        }  | 
 | 
        if (DEBUG) { | 
 | 
            if (addrType == Krb5.ADDRTYPE_INET ||  | 
 | 
                addrType == Krb5.ADDRTYPE_INET6) { | 
 | 
                System.out.println("Host address is " + | 
 | 
                        InetAddress.getByAddress(address));  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public HostAddress(InetAddress inetAddress) { | 
 | 
        addrType = getAddrType(inetAddress);  | 
 | 
        address = inetAddress.getAddress();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public HostAddress(DerValue encoding) throws Asn1Exception, IOException { | 
 | 
        DerValue der = encoding.getData().getDerValue();  | 
 | 
        if ((der.getTag() & (byte)0x1F) == (byte)0x00) { | 
 | 
            addrType = der.getData().getBigInteger().intValue();  | 
 | 
        }  | 
 | 
        else  | 
 | 
            throw new Asn1Exception(Krb5.ASN1_BAD_ID);  | 
 | 
        der = encoding.getData().getDerValue();  | 
 | 
        if ((der.getTag() & (byte)0x1F) == (byte)0x01) { | 
 | 
            address = der.getData().getOctetString();  | 
 | 
        }  | 
 | 
        else  | 
 | 
            throw new Asn1Exception(Krb5.ASN1_BAD_ID);  | 
 | 
        if (encoding.getData().available() > 0)  | 
 | 
            throw new Asn1Exception(Krb5.ASN1_BAD_ID);  | 
 | 
    }  | 
 | 
 | 
 | 
    /**  | 
 | 
         * Encodes a HostAddress object.  | 
 | 
         * @return a byte array of encoded HostAddress object.  | 
 | 
         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.  | 
 | 
         * @exception IOException if an I/O error occurs while reading encoded data.  | 
 | 
         *  | 
 | 
         */  | 
 | 
 | 
 | 
    public byte[] asn1Encode() throws Asn1Exception, IOException { | 
 | 
        DerOutputStream bytes = new DerOutputStream();  | 
 | 
        DerOutputStream temp = new DerOutputStream();  | 
 | 
        temp.putInteger(this.addrType);  | 
 | 
        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp);  | 
 | 
        temp = new DerOutputStream();  | 
 | 
        temp.putOctetString(address);  | 
 | 
        bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);  | 
 | 
        temp = new DerOutputStream();  | 
 | 
        temp.write(DerValue.tag_Sequence, bytes);  | 
 | 
        return temp.toByteArray();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static HostAddress parse(DerInputStream data, byte explicitTag,  | 
 | 
                                    boolean optional)  | 
 | 
        throws Asn1Exception, IOException{ | 
 | 
        if ((optional) &&  | 
 | 
            (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) { | 
 | 
            return null;  | 
 | 
        }  | 
 | 
        DerValue der = data.getDerValue();  | 
 | 
        if (explicitTag != (der.getTag() & (byte)0x1F))  { | 
 | 
            throw new Asn1Exception(Krb5.ASN1_BAD_ID);  | 
 | 
        }  | 
 | 
        else { | 
 | 
            DerValue subDer = der.getData().getDerValue();  | 
 | 
            return new HostAddress(subDer);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public String toString() { | 
 | 
        StringBuilder sb = new StringBuilder();  | 
 | 
        sb.append(Arrays.toString(address));  | 
 | 
        sb.append('(').append(addrType).append(')'); | 
 | 
        return sb.toString();  | 
 | 
    }  | 
 | 
}  |