/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.auth.internal.kerberos.v5; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import org.apache.harmony.auth.internal.nls.Messages; import org.apache.harmony.javax.security.auth.kerberos.KerberosKey; import org.apache.harmony.javax.security.auth.kerberos.KerberosPrincipal; import org.apache.harmony.security.asn1.DerInputStream; /** * @see http://www.ietf.org/rfc/rfc4120.txt */ public class KrbClient { // default kdc server private static final String DEFAULT_KDC = "java.security.krb5.kdc"; //$NON-NLS-1$ // default realm private static final String DEFAULT_REALM = "java.security.krb5.realm"; //$NON-NLS-1$ private static String kdc; private static String realm; private static int port = 88;// default private static final int BUF_SIZE = 1024; private static boolean isInitialized = false; /** * Get credentials from Authentication Service. * * @param address * - service host * @param port * - service port * @param cname * - client's principal identifier * @param realm * - client's realm * @return - ticket */ public static KDCReply doAS(PrincipalName cname, char[] password) throws KerberosException { setEnv(); final PrincipalName sname = new PrincipalName( PrincipalName.NT_SRV_XHST, new String[] { "krbtgt", realm }); //$NON-NLS-1$ final KDCRequest request = new KDCRequest(KDCRequest.AS_REQ, cname, realm, sname); try { final DatagramSocket socket = request.send( InetAddress.getByName(kdc), port); final ByteArrayOutputStream out = new ByteArrayOutputStream( BUF_SIZE); final byte[] buf = new byte[BUF_SIZE]; final DatagramPacket resp = new DatagramPacket(buf, buf.length); int bytesRead = BUF_SIZE; while (bytesRead == BUF_SIZE) { socket.receive(resp); bytesRead = resp.getLength(); out.write(buf, resp.getOffset(), bytesRead); } final DerInputStream in = new DerInputStream(out.toByteArray()); if (in.tag == KDCReply.AS_REP_ASN1.constrId) { // TODO AS reply final KDCReply reply = (KDCReply) KDCReply.AS_REP_ASN1 .decode(in); final KerberosKey key = new KerberosKey(new KerberosPrincipal( cname.getName()[0] + '@' + realm, cname.getType()), password, "DES"); reply.decrypt(key); return reply; } else if (in.tag == KerberosErrorMessage.ASN1.constrId) { final KerberosErrorMessage errMsg = KerberosErrorMessage .decode(in); // auth.52=Error code: {0} throw new KerberosException(Messages.getString( "auth.52", errMsg.getErrorCode())); //$NON-NLS-1$ } else { throw new KerberosException(); // FIXME } } catch (final IOException e) { throw new KerberosException(e.getMessage()); // FIXME } } public static KDCReply doTGS() throws KerberosException { setEnv(); return null; } public static synchronized String getRealm() throws KerberosException { if (!isInitialized) { setEnv(); } return realm; } private static void setEnv() throws KerberosException { if (isInitialized) { return; } // TODO put in doPrivileged kdc = System.getProperty(DEFAULT_KDC); realm = System.getProperty(DEFAULT_REALM); if (kdc == null && realm != null || kdc != null && realm == null) { // both properties should be set or unset together throw new KerberosException();// FIXME message } else if (kdc == null && realm == null) { // reading config from configuration file 'krb5.conf' KrbConfig config = null; try { config = KrbConfig.getSystemConfig(); } catch (final IOException e) { throw new KerberosException(e.getMessage()); } if (config == null) { // no config file was found throw new KerberosException();// FIXME err msg } realm = config.getValue("libdefaults", //$NON-NLS-1$ "default_realm"); //$NON-NLS-1$ // TODO set KDC return; } final int pos = kdc.indexOf(':'); if (pos != -1) { port = Integer.parseInt(kdc.substring(pos + 1)); kdc = kdc.substring(0, pos); } isInitialized = true; } private KrbClient() { // no objects } }