KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > security > network > protocol > SubjectCarryingChannel


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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
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 JavaDoc;
33 import java.io.DataInputStream JavaDoc;
34 import java.io.DataOutputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.security.AccessController JavaDoc;
37 import java.util.Collection JavaDoc;
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: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
45  */

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 JavaDoc remoteSubject;
55     private Subject JavaDoc 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 JavaDoc {
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 JavaDoc subject = Subject.getSubject(AccessController.getContext());
79         if (remoteSubject != subject) {
80             remoteSubject = subject;
81             Collection JavaDoc 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 JavaDoc narrow(Class JavaDoc target) {
102             if (target == SubjectContext.class) {
103                 return new SubjectContext() {
104                     public Subject JavaDoc 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 JavaDoc e) {
139             super.onPacketError(e);
140         }
141
142         super.onPacket(packet);
143     }
144
145     /**
146      */

147     private SubjectId extractSubjectId(Packet packet) throws IOException JavaDoc {
148         DataInputStream JavaDoc is = new DataInputStream JavaDoc(new PacketToInputStream(packet));
149         Long JavaDoc id = new Long JavaDoc(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 JavaDoc subjectId, byte[] hash) throws IOException JavaDoc {
162         header.clear();
163         DataOutputStream JavaDoc os = new DataOutputStream JavaDoc(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 JavaDoc getLocalSubject() {
180         return localSubject;
181     }
182
183     public Subject JavaDoc getRemoteSubject() {
184         return remoteSubject;
185     }
186
187 }
188
Popular Tags