/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.javax.security.auth.kerberos; import java.io.IOException; import java.io.Serializable; import java.security.Permission; import java.security.PermissionCollection; import org.apache.harmony.auth.internal.nls.Messages; public final class ServicePermission extends Permission implements Serializable { private static final long serialVersionUID = -1227585031618624935L; private static final String INITIATE = "initiate"; //$NON-NLS-1$ private static final String ACCEPT = "accept"; //$NON-NLS-1$ private static final String INITIATE_ACCEPT = "initiate,accept"; //$NON-NLS-1$ private static final String[] ACTIONS_TABLE = { "", ACCEPT, INITIATE, INITIATE_ACCEPT }; //$NON-NLS-1$ private final static char ACCEPT_MASK = 1; private final static char INITIATE_MASK = 2; private static final int INITIATE_LEN = INITIATE.length(); private static final int ACCEPT_LEN = ACCEPT.length(); private static final int MIN_LEN = Math.min(INITIATE_LEN, ACCEPT_LEN); /** * ACCEPT_MASK, INITIATE_ACCEPT or (INITIATE_ACCEPT | ACCEPT_MASK) */ private String actions; public ServicePermission(String name, String actions) { super(name); initActions(actions); if (name == null) { throw new NullPointerException(Messages.getString("auth.2F")); //$NON-NLS-1$ } if (name.trim().length() == 0) { throw new IllegalArgumentException(Messages.getString("auth.30")); //$NON-NLS-1$ } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || ServicePermission.class != obj.getClass()) { return false; } final ServicePermission sp = (ServicePermission) obj; return actions == sp.actions && getName().equals(sp.getName()); } @Override public String getActions() { return actions; } @Override public int hashCode() { return getName().hashCode() * actions.length(); } @Override public boolean implies(Permission permission) { if (this == permission) { return true; } if (permission == null || ServicePermission.class != permission.getClass()) { return false; } final ServicePermission sp = (ServicePermission) permission; final String name = getName(); return (actions == INITIATE_ACCEPT || actions == sp.actions) && (name.length() == 1 && name.charAt(0) == '*' || name .equals(permission.getName())); } // initialization of actions private void initActions(String actions) { if (actions == null || actions.length() < MIN_LEN) { throw new IllegalArgumentException(Messages.getString("auth.2E")); //$NON-NLS-1$ } final char[] c_acts = actions.toCharArray(); int result = 0; int ptr = 0; final int len6 = c_acts.length - ACCEPT_LEN; final int len8 = c_acts.length - INITIATE_LEN; do { // skipping whitespaces while (ptr <= len6 && (c_acts[ptr] == ' ' || c_acts[ptr] == '\t' || c_acts[ptr] == '\n' || c_acts[ptr] == 0x0B || c_acts[ptr] == '\f' || c_acts[ptr] == '\r')) { ++ptr; } if (ptr > len6) { // expect string "accept" or "initiate", not just white // spaces throw new IllegalArgumentException( Messages.getString("auth.2E")); //$NON-NLS-1$ } // parsing string if ((c_acts[ptr] == 'a' || c_acts[ptr] == 'A') && (c_acts[ptr + 1] == 'c' || c_acts[ptr + 1] == 'C') && (c_acts[ptr + 2] == 'c' || c_acts[ptr + 2] == 'C') && (c_acts[ptr + 3] == 'e' || c_acts[ptr + 3] == 'E') && (c_acts[ptr + 4] == 'p' || c_acts[ptr + 4] == 'P') && (c_acts[ptr + 5] == 't' || c_acts[ptr + 5] == 'T')) { result |= ACCEPT_MASK; ptr += ACCEPT_LEN; } else if (ptr <= len8 && (c_acts[ptr] == 'i' || c_acts[ptr] == 'I') && (c_acts[ptr + 1] == 'n' || c_acts[ptr + 1] == 'N') && (c_acts[ptr + 2] == 'i' || c_acts[ptr + 2] == 'I') && (c_acts[ptr + 3] == 't' || c_acts[ptr + 3] == 'T') && (c_acts[ptr + 4] == 'i' || c_acts[ptr + 4] == 'I') && (c_acts[ptr + 5] == 'a' || c_acts[ptr + 5] == 'A') && (c_acts[ptr + 6] == 't' || c_acts[ptr + 6] == 'T') && (c_acts[ptr + 7] == 'e' || c_acts[ptr + 7] == 'E')) { result |= INITIATE_MASK; ptr += INITIATE_LEN; } else { throw new IllegalArgumentException( Messages.getString("auth.2E")); //$NON-NLS-1$ } // skipping trailing whitespaces while (ptr < c_acts.length && (c_acts[ptr] == ' ' || c_acts[ptr] == '\t' || c_acts[ptr] == '\n' || c_acts[ptr] == 0x0B || c_acts[ptr] == '\f' || c_acts[ptr] == '\r')) { ptr++; } if (ptr == c_acts.length) { this.actions = ACTIONS_TABLE[result]; return; } } while (c_acts[ptr++] == ','); // unknown trailing symbol throw new IllegalArgumentException(Messages.getString("auth.2E")); //$NON-NLS-1$ } @Override public PermissionCollection newPermissionCollection() { return new KrbServicePermissionCollection(); } private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); initActions(getActions()); } private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException { s.defaultWriteObject(); } }