Home » geronimo-2.2-source-release » org.apache.geronimo.security.network.protocol » [javadoc | source]

    1   /**
    2    *
    3    * Copyright 2004 The Apache Software Foundation
    4    *
    5    *  Licensed under the Apache License, Version 2.0 (the "License");
    6    *  you may not use this file except in compliance with the License.
    7    *  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.geronimo.security.network.protocol;
   18   
   19   import java.io.DataInputStream;
   20   import java.io.DataOutputStream;
   21   import java.io.IOException;
   22   import java.security.AccessController;
   23   import java.util.Collection;
   24   import javax.security.auth.Subject;
   25   
   26   import org.activeio.AsynchChannel;
   27   import org.activeio.FilterAsynchChannel;
   28   import org.activeio.Packet;
   29   import org.activeio.adapter.PacketInputStream;
   30   import org.activeio.adapter.PacketOutputStream;
   31   import org.activeio.packet.AppendedPacket;
   32   import org.activeio.packet.ByteArrayPacket;
   33   import org.activeio.packet.FilterPacket;
   34   
   35   import org.apache.geronimo.security.ContextManager;
   36   import org.apache.geronimo.security.IdentificationPrincipal;
   37   import org.apache.geronimo.security.SubjectId;
   38   
   39   /**
   40    * SubjectCarryingChannel is a FilterAsynchChannel that allows you to send 
   41    * the subject associated with the current write operation down to the remote
   42    * end of the channel.
   43    * 
   44    * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $
   45    */
   46   public class SubjectCarryingChannel extends FilterAsynchChannel {
   47   
   48       static final byte PASSTHROUGH = (byte)0x00;
   49       static final byte SET_SUBJECT = (byte)0x01;
   50       static final byte CLEAR_SUBJECT = (byte)0x2;
   51   
   52       final private ByteArrayPacket header = new ByteArrayPacket(new byte[1+8+4]);
   53   
   54       private Subject remoteSubject;
   55       private Subject localSubject;
   56       
   57       private final boolean enableLocalSubjectPublishing;
   58       private final boolean enableRemoteSubjectConsumption;
   59   
   60       public SubjectCarryingChannel(AsynchChannel next) {
   61           this(next, true, true);
   62       }
   63       
   64       public SubjectCarryingChannel(AsynchChannel next, boolean enableLocalSubjectPublishing, boolean enableRemoteSubjectConsumption) {
   65           super(next);
   66           this.enableLocalSubjectPublishing = enableLocalSubjectPublishing;
   67           this.enableRemoteSubjectConsumption = enableRemoteSubjectConsumption;
   68       }
   69       
   70       public void write(Packet packet) throws IOException {
   71           
   72           // Don't add anything to the packet stream if subject writing is not enabled.
   73           if( !enableLocalSubjectPublishing ) {
   74               super.write(packet);
   75               return;
   76           }
   77           
   78           Subject subject = Subject.getSubject(AccessController.getContext());
   79           if (remoteSubject != subject) {
   80               remoteSubject = subject;
   81               Collection principals = remoteSubject.getPrincipals(IdentificationPrincipal.class);
   82               
   83               if (principals.isEmpty()) {
   84                   super.write(createClearSubjectPackt());
   85               } else {                
   86                   IdentificationPrincipal principal = (IdentificationPrincipal) principals.iterator().next();
   87                   SubjectId subjectId = principal.getId();                
   88                   super.write(createSubjectPacket(subjectId.getSubjectId(), subjectId.getHash()));
   89               }
   90               
   91           }
   92           super.write(createPassthroughPacket(packet));
   93       }
   94   
   95       public class SubjectPacketFilter extends FilterPacket {
   96   
   97           SubjectPacketFilter(Packet packet) {
   98               super(packet);
   99           }
  100   
  101           public Object narrow(Class target) {
  102               if( target == SubjectContext.class ) {
  103                   return new SubjectContext() {
  104                       public Subject getSubject() {
  105                           return remoteSubject;
  106                       }
  107                   };
  108               }
  109               return super.narrow(target);
  110           }
  111   
  112           public Packet filter(Packet packet) {
  113               return new SubjectPacketFilter(packet);
  114           }
  115   
  116       }
  117   
  118       public void onPacket(Packet packet) {
  119           
  120           // Don't take anything to the packet stream if subject reading is not enabled.
  121           if( !enableRemoteSubjectConsumption ) {
  122               super.onPacket(packet);
  123               return;
  124           }
  125           
  126           try {
  127               switch( packet.read() ) {
  128                   case CLEAR_SUBJECT:
  129                       localSubject = null;
  130                       return;
  131                   case SET_SUBJECT:               
  132                       SubjectId subjectId = extractSubjectId(packet);
  133                       localSubject = ContextManager.getRegisteredSubject(subjectId);
  134                       return;
  135                   case PASSTHROUGH:
  136                       super.onPacket( new SubjectPacketFilter(packet) );
  137               }
  138           } catch (IOException e) {
  139               super.onPacketError(e);
  140           }
  141   
  142           super.onPacket(packet);
  143       }
  144   
  145       /**
  146        */
  147       private SubjectId extractSubjectId(Packet packet) throws IOException {
  148           DataInputStream is = new DataInputStream(new PacketInputStream(packet));
  149           Long id = new Long(is.readLong());
  150           byte hash[]=  new byte[ is.readInt() ];
  151           return new SubjectId(id, hash);
  152       }
  153   
  154       private Packet createClearSubjectPackt() {
  155           header.clear();
  156           header.write(CLEAR_SUBJECT);
  157           header.flip();
  158           return header;
  159       }
  160   
  161       private Packet createSubjectPacket(Long subjectId, byte[] hash) throws IOException {
  162           header.clear();
  163           DataOutputStream os = new DataOutputStream(new PacketOutputStream(header));
  164           os.writeByte(SET_SUBJECT);
  165           os.writeLong(subjectId.longValue());
  166           os.writeInt(hash.length);
  167           os.close();
  168           header.flip();
  169           return AppendedPacket.join(header, new ByteArrayPacket(hash));
  170       }
  171   
  172       private Packet createPassthroughPacket(Packet packet) {
  173           header.clear();
  174           header.write(PASSTHROUGH);
  175           header.flip();
  176           return AppendedPacket.join(header,packet);
  177       }
  178   
  179       public Subject getLocalSubject() {
  180           return localSubject;
  181       }
  182   
  183       public Subject getRemoteSubject() {
  184           return remoteSubject;
  185       }
  186       
  187   }

Home » geronimo-2.2-source-release » org.apache.geronimo.security.network.protocol » [javadoc | source]