001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *  
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *  
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License. 
018 *  
019 */
020package org.apache.directory.kerberos.client;
021
022
023import java.io.DataInputStream;
024import java.io.IOException;
025import java.io.OutputStream;
026import java.net.DatagramPacket;
027import java.net.DatagramSocket;
028import java.net.InetSocketAddress;
029import java.net.Socket;
030import java.net.SocketAddress;
031import java.nio.ByteBuffer;
032
033
034/**
035 * A class for sending and receiving kerberos request and response data
036 * 
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 */
039public class KerberosChannel
040{
041    /** the TCP socket */
042    private Socket tcpSocket;
043
044    /** the UDP socket */
045    private DatagramSocket udpSocket;
046
047    /** data input stream to read from */
048    private DataInputStream in;
049
050    /** data output stream to write to */
051    private OutputStream out;
052
053    /** flag to detect if this is a UDP channel */
054    private boolean useUdp;
055
056    private int timeOut = 60000;
057
058    /** the UDP socket address of the server */
059    private SocketAddress udpServerAddr = null;
060
061
062    protected void openConnection( String hostName, int portNo, int timeOut, boolean isUdp ) throws IOException
063    {
064        this.useUdp = isUdp;
065        this.timeOut = timeOut;
066
067        if ( isUdp )
068        {
069            udpServerAddr = new InetSocketAddress( hostName, portNo );
070            udpSocket = new DatagramSocket();
071        }
072        else
073        {
074            tcpSocket = new Socket( hostName, portNo );
075            tcpSocket.setSoTimeout( ( int ) timeOut );
076            in = new DataInputStream( tcpSocket.getInputStream() );
077            out = tcpSocket.getOutputStream();
078        }
079    }
080
081
082    protected ByteBuffer sendAndReceive( ByteBuffer encodedBuf ) throws IOException
083    {
084        byte[] reqData = encodedBuf.array();
085
086        ByteBuffer repData;
087
088        if ( useUdp )
089        {
090            DatagramPacket reqPacket = new DatagramPacket( reqData, reqData.length, udpServerAddr );
091            udpSocket.send( reqPacket );
092
093            byte[] buffer = new byte[2048];
094            DatagramPacket repPacket = new DatagramPacket( buffer, buffer.length );
095            udpSocket.receive( repPacket );
096
097            byte[] receivedData = repPacket.getData();
098            repData = ByteBuffer.allocate( receivedData.length );
099            repData.put( receivedData );
100        }
101        else
102        {
103            out.write( reqData );
104            out.flush();
105
106            int len = in.readInt();
107
108            repData = ByteBuffer.allocate( len + 4 );
109            repData.putInt( len );
110
111            byte[] tmp = new byte[1024 * 8];
112            while ( in.available() > 0 )
113            {
114                int read = in.read( tmp );
115                repData.put( tmp, 0, read );
116            }
117        }
118
119        repData.flip();
120
121        return repData;
122    }
123
124
125    protected boolean isUseTcp()
126    {
127        return !useUdp;
128    }
129
130
131    protected void close() throws IOException
132    {
133        if ( useUdp )
134        {
135            if ( udpSocket != null )
136            {
137                udpSocket.close();
138            }
139        }
140        else
141        {
142            if ( tcpSocket != null )
143            {
144                tcpSocket.close();
145            }
146        }
147    }
148}