1 17 18 package org.apache.geronimo.security.network.protocol; 19 20 import org.activeio.AsyncChannel; 21 import org.activeio.FilterAsyncChannel; 22 import org.activeio.Packet; 23 import org.activeio.adapter.PacketOutputStream; 24 import org.activeio.adapter.PacketToInputStream; 25 import org.activeio.packet.AppendedPacket; 26 import org.activeio.packet.ByteArrayPacket; 27 import org.activeio.packet.FilterPacket; 28 import org.apache.geronimo.security.ContextManager; 29 import org.apache.geronimo.security.IdentificationPrincipal; 30 import org.apache.geronimo.security.SubjectId; 31 32 import javax.security.auth.Subject ; 33 import java.io.DataInputStream ; 34 import java.io.DataOutputStream ; 35 import java.io.IOException ; 36 import java.security.AccessController ; 37 import java.util.Collection ; 38 39 46 public class SubjectCarryingChannel extends FilterAsyncChannel { 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(AsyncChannel next) { 61 this(next, true, true); 62 } 63 64 public SubjectCarryingChannel(AsyncChannel 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 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 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 147 private SubjectId extractSubjectId(Packet packet) throws IOException { 148 DataInputStream is = new DataInputStream (new PacketToInputStream(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 } 188 | Popular Tags |