001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2005 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: */package org.objectweb.security.context;
022:
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Iterator;
026: import java.util.List;
027:
028: /**
029: * Class allowing to marshall/unmarshall Security Context class
030: * @author Guillaume Riviere (initial developer)
031: * @author Florent Benoit
032: */
033: public class Marshalling {
034:
035: /**
036: * security context id
037: */
038: public static final int SEC_CTX_ID = 101;
039:
040: /**
041: * Utility class
042: */
043: private Marshalling() {
044:
045: }
046:
047: /**
048: * Custom UTF8 marshalling SecurityContext
049: * The resulting bute array is composed of the following elements:
050: * principal-name, roles-number, role1, ...., runas-number, runas1, ....
051: * then principal stack then roles of principal stack
052: * @return byte [] the marshalled context
053: * @param ctx SecurityContext
054: */
055: public static byte[] marshallSecurityContext(SecurityContext ctx) {
056: byte[] result = null;
057: try {
058: if (ctx != null) {
059: // build a new byte from ctx
060: ArrayList cResult = new ArrayList();
061: // add the pname
062: addBytes(cResult, ctx.getPrincipalName());
063: // add the roles
064: String[] roles = ctx.getRoles();
065: int nbRoles = 0;
066: if (roles != null) {
067: nbRoles = roles.length;
068: }
069: addBytes(cResult, new Integer(nbRoles).toString());
070: for (int i = 0; i < nbRoles; i++) {
071: addBytes(cResult, roles[i]);
072: }
073:
074: // add runas
075: addBytes(cResult, new Integer(ctx.getRunAsRoleStack()
076: .size()).toString());
077: Iterator iRunAs = ctx.getRunAsRoleStack().iterator();
078: while (iRunAs.hasNext()) {
079: addBytes(cResult, (String) iRunAs.next());
080: }
081:
082: // add runas principal stack
083: addBytes(cResult, new Integer(ctx
084: .getRunAsPrincipalStack().size()).toString());
085: iRunAs = ctx.getRunAsPrincipalStack().iterator();
086: while (iRunAs.hasNext()) {
087: addBytes(cResult, (String) iRunAs.next());
088: }
089:
090: // add runas roles of principal mapping
091: addBytes(cResult, new Integer(ctx
092: .getRunAsPrincipalRolesStack().size())
093: .toString());
094: iRunAs = ctx.getRunAsPrincipalRolesStack().iterator();
095: while (iRunAs.hasNext()) {
096: addBytes(cResult, (String[]) iRunAs.next());
097: }
098:
099: // result casting
100: result = new byte[cResult.size()];
101: for (int i = 0; i < cResult.size(); i++) {
102: result[i] = ((Byte) cResult.get(i)).byteValue();
103: }
104: }
105:
106: } catch (java.io.UnsupportedEncodingException uee) {
107: uee.printStackTrace();
108: }
109: return result;
110: }
111:
112: /**
113: * Custom UTF8 marshalling SecurityContext
114: * @param byteCtx the marshalled context
115: * @return SecurityContext
116: */
117: public static SecurityContext unmarshallSecurityContext(
118: byte[] byteCtx) {
119: SecurityContext result = null;
120: if ((byteCtx != null) && (byteCtx.length > 0)) {
121: try {
122: Iterator istrs = getBytes2Strings(byteCtx).iterator();
123: String principalName = (String) istrs.next();
124: int nbRoles = new Integer((String) istrs.next())
125: .intValue();
126: ArrayList roles = null;
127: if (nbRoles > 0) {
128: roles = new ArrayList();
129: }
130: while (nbRoles > 0) {
131: roles.add(istrs.next());
132: nbRoles--;
133: }
134:
135: // unmarshall runAs role
136: int nbRunas = new Integer((String) istrs.next())
137: .intValue();
138: ArrayList runas = null;
139: if (nbRunas > 0) {
140: runas = new ArrayList();
141: }
142: while (nbRunas > 0) {
143: runas.add(istrs.next());
144: nbRunas--;
145: }
146:
147: // unmarshall runAs principal
148: int nbRunasPrincipal = new Integer((String) istrs
149: .next()).intValue();
150: ArrayList runasPrincipal = null;
151: if (nbRunasPrincipal > 0) {
152: runasPrincipal = new ArrayList();
153: }
154: while (nbRunasPrincipal > 0) {
155: runasPrincipal.add(istrs.next());
156: nbRunasPrincipal--;
157: }
158:
159: // unmarshall runAs principal to roles mapping
160: int nbRunasRoles = new Integer((String) istrs.next())
161: .intValue();
162: ArrayList runasRoles = null;
163: if (nbRunasRoles > 0) {
164: int arrayLength = new Integer((String) istrs.next())
165: .intValue();
166:
167: if (nbRunasRoles > 0) {
168: runasRoles = new ArrayList();
169: }
170: while (nbRunasRoles > 0) {
171: String[] st = new String[arrayLength];
172: for (int j = 0; j < arrayLength; j++) {
173: st[j] = (String) istrs.next();
174: }
175: runasRoles.add(st);
176: nbRunasRoles--;
177: }
178: }
179: result = new SecurityContext(principalName, roles,
180: runas, runasPrincipal, runasRoles);
181:
182: } catch (java.io.UnsupportedEncodingException uee) {
183: uee.printStackTrace();
184: }
185: }
186: return result;
187: }
188:
189: /**
190: * Add to the collection of a byte[], the given string.
191: * (its lengths, following by its value)
192: * @param c collection of byte[]
193: * @param toAdd string to transform to a byte[] and to add to the collection
194: * @throws java.io.UnsupportedEncodingException if the UTF-8 encoding fails
195: */
196: private static void addBytes(Collection c, String toAdd)
197: throws java.io.UnsupportedEncodingException {
198: byte[] b = toAdd.getBytes("UTF8");
199: c.add(new Byte((byte) b.length));
200: for (int i = 0; i < b.length; i++) {
201: c.add(new Byte(b[i]));
202: }
203: }
204:
205: /**
206: * Add to the collection of a byte[], the given string.
207: * (its lengths, following by its value)
208: * @param c collection of byte[]
209: * @param toAdd string to transform to a byte[] and to add to the collection
210: * @throws java.io.UnsupportedEncodingException if the UTF-8 encoding fails
211: */
212: private static void addBytes(Collection c, String[] toAdd)
213: throws java.io.UnsupportedEncodingException {
214: // add length of the array
215: addBytes(c, new Integer(toAdd.length).toString());
216: // add each string of the array
217: for (int n = 0; n < toAdd.length; n++) {
218: byte[] b = toAdd[n].getBytes("UTF8");
219: c.add(new Byte((byte) b.length));
220: for (int i = 0; i < b.length; i++) {
221: c.add(new Byte(b[i]));
222: }
223: }
224: }
225:
226: /**
227: * Transform a bytes array to a Strin array.
228: * (The bytes array contains for each string, its length, following by its value).
229: * @param bytes byte array to transform
230: * @return the array list of string
231: * @throws java.io.UnsupportedEncodingException if the UTF-8 encoding fails
232: */
233: private static List getBytes2Strings(byte[] bytes)
234: throws java.io.UnsupportedEncodingException {
235: ArrayList strs = new ArrayList();
236: int index = 0;
237: while (bytes.length > index) {
238: int rSize = bytes[index];
239: index++;
240: byte[] rName = new byte[rSize];
241: for (int j = 0; j < rSize; j++) {
242: rName[j] = bytes[index];
243: index++;
244: }
245: strs.add(new String(rName, "UTF8"));
246: }
247: return strs;
248: }
249:
250: }
|