pax_global_header00006660000000000000000000000064135627537310014526gustar00rootroot0000000000000052 comment=242b3d5ec8f45d862bae128d6dcaa8e0e5cc3da1 yanfs-yanfs-1.4/000077500000000000000000000000001356275373100136305ustar00rootroot00000000000000yanfs-yanfs-1.4/.gitignore000066400000000000000000000002001356275373100156100ustar00rootroot00000000000000*.class *.war *.ear tmp/* dist/* reports/* out/* .svn/* /bin/ .idea/workspace.xml target/ .settings/ .idea/ .classpath .project yanfs-yanfs-1.4/README.md000066400000000000000000000025641356275373100151160ustar00rootroot00000000000000# yanfs [![Download](https://api.bintray.com/packages/raisercostin/maven/yanfs/images/download.svg)](https://bintray.com/raisercostin/maven/yanfs/_latestVersion) [![Build Status](https://travis-ci.org/raisercostin/yanfs.svg?branch=master)](https://travis-ci.org/raisercostin/yanfs) Migrated from https://java.net/projects/yanfs/sources/svn/show This project represents a Java implementation of the XDR, RPC, NFSv2, and NFSv3 protocols in client side form. WebNFS was the original name for this implementation but the name has changed to reflect the expanded scope of the project to include a server side implementation. ## Maven ### Dependency ``` com.sun yanfs 1.4 ``` No need to include a repository as is available at https://jcenter.bintray.com/com/sun/yanfs/ # Development - To release `mvn release:prepare release:perform -DskipTests=true -Prelease -Darguments="-DskipTests=true -Prelease"` yanfs-yanfs-1.4/pom.xml000066400000000000000000000074221356275373100151520ustar00rootroot00000000000000 4.0.0 org.raisercostin maven-defaults-raisercostin 1.1 com.sun yanfs 1.4 yanfs This project represents a Java implementation of the XDR, RPC, NFSv2, and NFSv3 protocols in client side form. WebNFS was the original name for this implementation but the name has changed to reflect the expanded scope of the project to include a server side implementation. ${git.url} scm:git:${git.url}.git scm:git:${git.url}.git ${git.url} yanfs-1.4 ${dist.id.prefix}-maven-releases https://api.bintray.com/maven/${bintray.user}/${bintray.repo}/${bintray.package}/;publish=1 Github https://github.com/raisercostin/${project.artifactId}/issues raisercostin ${project.artifactId} github.com https://${git.host}/${git.userOrGroup}/${git.repo} raisercostin bintray raisercostin maven ${project.artifactId} yyyy-MM-dd_HH:mm:ss ${maven.build.timestamp} https://api.bintray.com/maven/${bintray.user}/${bintray.repo}/${bintray.package} ${dist.url}/releases/ ${dist.url}/snapshots/ ${dist.url}/sites/${project.groupId}-${project.artifactId}-${project.version} false UTF-8 UTF-8 1.7 1.7 1.7 1.7 The Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt Costin Grigore raisercostin@gmail.com raisercostin http://raisercostin.org jcenter-bintray https://jcenter.bintray.com/ true false raisercostin-bintray https://dl.bintray.com/raisercostin/maven true false yanfs-yanfs-1.4/src/000077500000000000000000000000001356275373100144175ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/000077500000000000000000000000001356275373100153435ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/000077500000000000000000000000001356275373100162645ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/000077500000000000000000000000001356275373100170425ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/000077500000000000000000000000001356275373100176475ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/file/000077500000000000000000000000001356275373100205665ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/file/XFileAccessor.java000066400000000000000000000252751356275373100241360ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. * */ package com.sun.file; import com.sun.xfile.*; import java.io.*; /** * The XFileAccessor interface is implemented by filesystems that * need to be accessed via the XFile API. * * @author Brent Callaghan * @version 1.0, 04/08/98 * @see com.sun.xfile.XFile */ public class XFileAccessor implements com.sun.xfile.XFileAccessor { private XFile xf; private File file; private RandomAccessFile raf; private boolean readOnly; private long fp; // file pointer char sep = System.getProperty("file.separator").charAt(0); /** * Open this file object * * @param xf the XFile for this file * @param serial true if serial access * @param readOnly true if read only */ public boolean open(XFile xf, boolean serial, boolean readOnly) { this.xf = xf; this.readOnly = readOnly; file = new File(unEscape(xf.getPath().replace('/', sep))); return file.exists(); } /* * Find any of "%nn" escapes in the string * (where nn are hex digits) and convert to the * equivalent ASCII character, e.g. "%3f" -> "?" * See RFC 1738. */ private String unEscape(String s) { String hD = "0123456789abcdef"; int p2; String ns = ""; int len = s.length(); for (int p = 0; p < len; p = p2 + 1) { p2 = s.indexOf("%", p); if (p2 < 0) // not found p2 = len; ns += s.substring(p, p2); if (p2 == len) break; /* * Check for %nn where nn are hex digits */ if (p2 < (len - 2)) { int d1 = hD.indexOf(s.toLowerCase().charAt(p2 + 1)); int d2 = hD.indexOf(s.toLowerCase().charAt(p2 + 2)); if (d1 > 0 && d2 > 0) { ns += new String(new byte[] {(byte)(d1 << 4 | d2)}); p2 += 2; continue; } } ns += "%"; } return ns; } /** * Get the XFile for this Accessor * * @return XFile for this object */ public XFile getXFile() { return xf; } /** * Tests if this XFileAccessor object exists. * * @return true if the file specified by this object * exists; false otherwise. */ public boolean exists() { return file.exists(); } /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this * object; false otherwise. */ public boolean canWrite() { return file.canWrite(); } /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ public boolean canRead() { return file.canRead(); } /** * Tests if the file represented by this * object is a "normal" file. *

* A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is * guaranteed to be a normal file. * * @return true if the file specified by this * XFile object exists and is a "normal" * file; false otherwise. */ public boolean isFile() { return file.isFile(); } /** * Tests if the file represented by this XFileAccessor * object is a directory. * * @return true if this XFileAccessor object * exists and is a directory; false * otherwise. */ public boolean isDirectory() { return file.isDirectory(); } /** * Returns the time that the file represented by this * XFile object was last modified. *

* The return value is system dependent and should only be * used to compare with other values returned by last modified. * It should not be interpreted as an absolute time. * * @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ public long lastModified() { return file.lastModified(); } /** * Returns the length of the file represented by this * XFileAccessor object. * * @return the length, in bytes, of the file specified by * this object, or 0L if the specified * file does not exist. */ public long length() { return file.length(); } /** * Creates a file whose pathname is specified by this * XFileAccessor object. * * @return true if the file could be created; * false otherwise. */ public boolean mkfile() { try { // This little maneuver creates a zero length file FileOutputStream of = new FileOutputStream(file); of.getFD().sync(); of.close(); return true; } catch (IOException e) { return false; } } /** * Creates a directory whose pathname is specified by this * XFileAccessor object. * * @return true if the directory could be created; * false otherwise. */ public boolean mkdir() { return file.mkdir(); } /** * Renames the file specified by this XFileAccessor object to * have the pathname given by the XFileAccessor object argument. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ public boolean renameTo(XFile dest) { return file.renameTo(new File(dest.getPath())); } /** * Returns a list of the files in the directory specified by * this XFileAccessor object. * * @return an array of file names in the specified directory. * This list does not include the current directory or * the parent directory ("." and * ".." on Unix systems). */ public String[] list() { return file.list(); } /** * Deletes the file specified by this object. If the target * file to be deleted is a directory, it must be empty for * deletion to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ public boolean delete() { return file.delete(); } /** * Reads a subarray as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @return number of bytes read; -1 if EOF * @exception IOException If an I/O error has occurred. */ public int read(byte b[], int off, int len, long foff) throws IOException { if (raf == null) raf = new RandomAccessFile(file, readOnly ? "r" : "rw"); if (foff != fp) { fp = foff; raf.seek(foff); } int c = raf.read(b, off, len); if (c > 0) fp += c; return (c); } /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @exception IOException If an I/O error has occurred. */ public void write(byte b[], int off, int len, long foff) throws IOException { if (raf == null) raf = new RandomAccessFile(file, readOnly ? "r" : "rw"); if (foff != fp) { fp = foff; raf.seek(foff); } raf.write(b, off, len); fp += len; } /** * Forces any buffered output bytes to be written out. *

* Since RandomAccessFile has no corresponding method * this does nothing. * * @exception IOException if an I/O error occurs. */ public void flush() throws IOException { } /** * Close the file * * @exception IOException If an I/O error has occurred. */ public void close() throws IOException { if (raf != null) raf.close(); } /** * Returns a string representation of this object. * * @return a string giving the pathname of this object. */ public String toString() { return file.toString(); } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/000077500000000000000000000000001356275373100211355ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/C018FE95.java000066400000000000000000000260501356275373100230070ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.OutputStream; /** * An object of this class implements the functionality of a GSSContext * for a specific mechanism. * A C018FE95 object can be thought of having 3 states: * -before initialization * -during initialization with its peer * -after it is established *

* The context options can only be requested in state 1. In state 3, * the per message operations are available to the callers. The get * methods for the context options will return the requested options * while in state 1 and 2, and the established values in state 3. * Some mechanisms may allow the access to the per-message operations * and the context flags before the context is fully established. The * isProtReady method is used to indicate that these services are * available. */ public interface C018FE95 { /** * Sets the mechanism options to be used during context * creation on the initiator's side. This is used to * initialize a new C018FE95 object. * * @param myCred the principal's credentials; may be null * @param targName the context peer * @param desLifetime the requested lifetime; 0 indicates use * default * @param mechOptions ORed GSSContext options * @exception GSSException may be thrown */ public void _S235D9C1 (GSSCredSpi myCred, GSSNameSpi targName, int desLifetime, int ctxtOptions) throws GSSException; /** * Sets the mechanism options to be used during context * creation on the acceptor's side. This is used to initialize * a new C018FE95 object. * * @param myCred the principal's credentials; may be null * @exception GSSException may be thrown */ public void _S90010CC (GSSCredSpi myCred) throws GSSException; /** * Sets the channel bindings to be used during context * establishment. This method is only called if the application * wishes to use channel bindings with this context. * * @param chb channel bindings to be set * @exception GSSException may be thrown */ public void _S9B00AB2 (ChannelBinding chb) throws GSSException; /** * Retrieves the mechanism options. * * @return int GSSContext options ORed together */ public int _S00027C3 (); /** * Inquire the remaining lifetime. * * @return the lifetime in seconds. May return reserved * value GSSContext.INDEFINITE for an indefinite lifetime. */ public int _S4080EED (); /** * Returns the mechanism oid. * * @return the Oid for this context */ public Oid _S0200735 (); /** * Returns the context initiator name. * * @return initiator name * @exception GSSException may be thrown */ public GSSNameSpi _S000EEFF () throws GSSException; /** * Returns the context acceptor name. * * @return context acceptor(target) name * @exception GSSException may be thrown */ public GSSNameSpi _S011CEF9 () throws GSSException; /** * Returns the delegated credential for the context. This * is an optional feature of contexts which not all * mechanisms will support. A context can be requested to * support credential delegation by using the CRED_DELEG. * This is only valid on the acceptor side of the context. * @return GSSCredSpi object for the delegated credential * @exception GSSException may be thrown * @see GSSContext#getDelegCredState */ public GSSCredSpi _S0293FFA () throws GSSException; /** * Tests if this is the initiator side of the context. * * @return boolean indicating if this is initiator (true) * or target (false) */ public boolean _S123049E (); /** * Tests if the context can be used for per-message service. * Context may allow the calls to the per-message service * functions before being fully established. * * @return boolean indicating if per-message methods can * be called. */ public boolean _S1116FAA (); /** * Initiator context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. On the * first call it will be ignored. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException may be thrown */ public int _S0E039DB (InputStream is, OutputStream os) throws GSSException; /** * Acceptor's context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException may be thrown */ public int _S80A2F2C (InputStream is, OutputStream os) throws GSSException; /** * Queries the context for largest data size to accomodate * the specified protection and for the token to remain less then * maxTokSize. * * @param qop the quality of protection that the context will be * asked to provide. * @param confReq a flag indicating whether confidentiality will be * requested or not * @param outputSize the maximum size of the output token * @return the maximum size for the input message that can be * provided to the wrap() method in order to guarantee that these * requirements are met. * @exception GSSException may be thrown */ public int _S808028B (int qop, boolean confReq, int maxTokSize) throws GSSException; /** * Provides per-message token encapsulation. * * @param is the user-provided message to be protected * @param os the token to be sent to the peer. It includes * the message from is with the requested protection. * @param msgPro on input it contains the requested qop and * confidentiality state, on output, the applied values * @exception GSSException may be thrown * @see MessageInfo * @see unwrap */ public void _S1309AFD (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Retrieves the message token previously encapsulated in the wrap * call. * * @param is the token from the peer * @param os unprotected message data * @param msgProp will contain the applied qop and confidentiality * of the input token and any informatory status values * @exception GSSException may be thrown * @see MessageInfo * @see wrap */ public void _S1576D09 (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Applies per-message integrity services. * * @param is the user-provided message * @param os the token to be sent to the peer along with the * message token. The message token is not encapsulated. * @param msgProp on input the desired QOP and output the applied QOP * @exception GSSException */ public void _S1513DBA (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Checks the integrity of the supplied tokens. * This token was previously generated by getMIC. * * @param is token generated by getMIC * @param msgStr the message to check integrity for * @param msgProp will contain the applied QOP and confidentiality * states of the token as well as any informatory status codes * @exception GSSException may be thrown */ public void _S00256CF (InputStream is, InputStream msgStr, MessageProp mProp) throws GSSException; /** * Produces a token representing this context. After this call * the context will no longer be usable until an import is * performed on the returned token. * * @return exported context token * @exception GSSException may be thrown */ public byte []_S725B2DA () throws GSSException; /** * Imports a previously exported context. This will be called * for newly created objects. * * @param is the previously exported token * @exception GSSException may be thrown * @see export */ public void _S0AC8F9E (byte []token) throws GSSException; /** * Releases context resources and terminates the * context between 2 peer. * * @exception GSSException may be thrown */ public void _S020B957 () throws GSSException; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/ChannelBinding.java000066400000000000000000000127631356275373100246540ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.net.InetAddress; /** * The JGSS accommodates the concept of caller-provided channel * binding information. Channel bindings are used to strengthen * the quality with which peer entity authentication is provided * during context establishment. They enable the JGSS callers to * bind the establishment of the a security context to relevant * characteristics like addresses or to application specific data. *

* The caller initiating the security context must determine the * appropriate channel binding values to set in the GSSContext * object. The acceptor must provide identical binding in order * to validate that received tokens possess correct * channel-related characteristics. *

* Use of channel bindings is optional in JGSS. Since channel- * binding information may be transmitted in context establishment * tokens, applications should therefore not use confidential data * as channel-binding components. * @see GSSContext#setChannelBinding * @see java.net.InetAddress */ public class ChannelBinding { private InetAddress m_initiator; private InetAddress m_acceptor; private byte[] m_appData; /** * Construct a channel bindings object that contains all the user * specified tags. * * @param initAddr the address of the context initiator * @param acceptAddr address of the context acceptor * @param appData a byte array of application data to be used as * part of the channel-binding */ public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr, byte[] appData) { m_initiator = initAddr; m_acceptor = acceptAddr; if (appData != null) { m_appData = new byte[appData.length]; java.lang.System.arraycopy(appData, 0, m_appData, 0, m_appData.length); } } /** * Construct a channel bindings object without any addressing * information. * * @param appData a byte array of application data to be used as * part of the channel-binding */ public ChannelBinding(byte[] appData) { m_initiator = null; m_acceptor = null; m_appData = new byte[appData.length]; java.lang.System.arraycopy(appData, 0, m_appData, 0, m_appData.length); } /** * Get the initiator's address for this channel binding. * * @return the initiator's address. null if no address * information is contained */ public InetAddress getInitiatorAddress() { return m_initiator; } /** * Get the acceptor's address for this channel binding. * * @return the acceptor's address. null if no address * information is contained */ public InetAddress getAcceptorAddress() { return m_acceptor; } /** * Get the application specified data for this channel binding. * The byte array is not copied. * * @return byte[] the application data that comprises this * channel-binding */ public byte[] getApplicationData() { return m_appData; } /** * Compares two instances of ChannelBinding * * @return true if objects are the same * @overrides java.lang.Object#equals */ public boolean equals(Object obj) { if (! (obj instanceof ChannelBinding)) return false; ChannelBinding cb = (ChannelBinding)obj; //check for application data being null in one but not the other if ((getApplicationData() == null && cb.getApplicationData() != null) || (getApplicationData() != null && cb.getApplicationData() == null)) return (false); return (this.m_initiator.equals(cb.getInitiatorAddress()) && this.m_acceptor.equals(cb.getAcceptorAddress()) && (this.getApplicationData() == null || this.m_appData.equals(cb.getApplicationData()))); } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/DERParser.java000066400000000000000000000146171356275373100236000ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.ByteArrayOutputStream; import java.util.Vector; /** * This is a package private class used to decode/encode ASN.1 DER * oids. */ class DERParser { /** * Returns the DER encoded length from the InputStream. */ static int readLength(InputStream is) throws GSSException { int length, tmp; //get the length of Oid - check if short form try { if (((tmp = is.read()) & 0x080) == 0) length = tmp; else { //must be long form tmp &= 0x7f; for (length = 0; tmp > 0; tmp--) { length <<= 8; length += (0xff & is.read()); } } } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } return (length); } /** * Decodes a DER encoding of an Oid object into vector components. */ static Vector decodeOid(InputStream is) throws GSSException { //check the tag first try { if (is.read() != 0x06) throw new GSSException(GSSException.DEFECTIVE_TOKEN); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } return (decodeOidOctets(is, readLength(is))); } /** * Decodes the specified number of oid octets. * Returns a vector of integer components. */ static Vector decodeOidOctets(InputStream is, int numOfOctets) throws GSSException { Vector v = new Vector(9, 3); //first octet is combination of first two numbers try { int comp, tmp = is.read(); if (tmp < 40) comp = 0; else if (tmp < 80) comp = 1; else comp = 2; v.addElement(new Integer(comp)); v.addElement(new Integer(tmp - (40 * comp))); //get the rest of the octets for (int i = 1; i < numOfOctets; i++) { comp = 0; //assume that at most 4 octets make up each component for (int j=0; j < 4; j++) { comp <<= 7; tmp = is.read(); comp |= (tmp & 0x7f); if ((tmp & 0x80) == 0) break; i++; } v.addElement(new Integer(comp)); } } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } return (v); } /** * Encodes DER length. */ static void writeLength(OutputStream os, int len) throws IOException { //encode the length - for all practical purposes, the length //should always be less then 0x80 (128) if (len < 0x80) os.write(len); else if (len < 0x100) { os.write(0x081); os.write(len); } else if (len < 0x80000) { os.write(0x082); os.write(len >> 8); os.write(len & 0xff); } else if (len < 0x1000000) { os.write(0x083); os.write(len >> 16); os.write((len >> 8) & 0xff); os.write(len & 0xff); } else { os.write(0x084); os.write(len >>> 24); os.write((len >> 16) & 0xff); os.write((len >> 8) & 0xff); os.write(len & 0xff); } } /** * Produces ASN.1 DER encoding for the object. * @return byte[] DER encoding for the object */ static byte[] encodeOid(Vector v) throws GSSException { //use byte array output stream - 32 initial bytes should be enough ByteArrayOutputStream o = new ByteArrayOutputStream(); int length = 1; try { //start with Oid tag o.write(0x06); //figure our the length - must have at least 2 elements X.208 if (v.size() < 2) throw new IllegalArgumentException(); for (int i = 2; i < v.size(); i++) { int compLen = 0; int nextComp = ((Integer)v.elementAt(i)).intValue(); //count # of 7 bit octets this will occupy for (compLen = 0; nextComp > 0; nextComp >>= 7, compLen++) ;//nothing to do //must have at least 1 octet if (compLen == 0) length += 1; else length += compLen; } writeLength(o, length); //now write the components writeOidOctets(o, v); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } return (o.toByteArray()); } /** * Encodes the oid octets onto the stream. */ static void writeOidOctets(OutputStream o, Vector v) throws IOException { //first 2 components occupy 1 octet o.write(((Integer)v.elementAt(0)).intValue() * 40 + ((Integer)v.elementAt(1)).intValue()); for (int i = 2; i < v.size(); i++) { int tmp, nextComp = ((Integer)v.elementAt(i)).intValue(); //each component may be at most 4 octets long for (int c = 0; c < 4; c++) { tmp = (nextComp & 0x7f); nextComp >>>= 7; //every octet except for last has bit 8 on if (nextComp > 0) o.write(tmp | 0x80); else { o.write(tmp); break; } } } } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSContext.java000066400000000000000000001651061356275373100240120ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * This class represents the JGSS security context and its associated * operations. JGSS security contexts are established between * peers using locally established credentials. Multiple contexts * may exist simultaneously between a pair of peers, using the same * or different set of credentials. The JGSS is independent of * the underlying transport protocols and depends on its callers to * transport the tokens between peers. *

* The context object can be thought of as having 3 implicit states: * before it is established, during its context establishment, and * after a fully established context exists. *

* Before the context establishment phase is initiated, the context * initiator may request specific characteristics desired of the * established context. These can be set using the set methods. After the * context is established, the caller can check the actual characteristic * and services offered by the context using the query methods. *

* The context establishment phase begins with the first call to the init * method by the context initiator. During this phase the init and accept * methods will produce GSS-API authentication tokens which the calling * application needs to send to its peer. The init and accept methods may * return a CONTINUE_NEEDED code which indicates that a token is needed * from its peer in order to continue the context establishment phase. A * return code of COMPLETE signals that the local end of the context is * established. This may still require that a token be sent to the peer, * depending if one is produced by GSS-API. The isEstablished method can * also be used to determine if the local end of the context has been * fully established. During the context establishment phase, the * isProtReady method may be called to determine if the context can be * used for the per-message operations. This allows implementation to * use per-message operations on contexts which aren't fully established. *

* After the context has been established or the isProtReady method * returns "true", the query routines can be invoked to determine the actual * characteristics and services of the established context. The * application can also start using the per-message methods of wrap and * getMIC to obtain cryptographic operations on application supplied data. *

* When the context is no longer needed, the application should call * dispose to release any system resources the context may be using. *

RFC 2078 *
This class corresponds to the context level calls together with * the per message calls of RFC 2078. The gss_init_sec_context and * gss_accept_sec_context calls have been made simpler by only taking * required parameters. The context can have its properties set before * the first call to init. The supplementary status codes for the per-message * operations are returned in an instance of the MessageProp class, which is * used as an argument in these calls.
*/ public class GSSContext { /** * Indefinite lifetime value for a context. Set to the * largest value for an int in Java. * @see #getLifetime */ public static final int INDEFINITE = Integer.MAX_VALUE; /** * Return value from either accept or init stating that * the context creation phase is complete for this peer. * @see #init * @see #accept */ public static final int COMPLETE = 0; /** * Return value from either accept or init stating that * another token is required from the peer to continue context * creation. This may be returned several times indicating * multiple token exchanges. * @see #init * @see #accept */ public static final int CONTINUE_NEEDED = 1; /** * Context option flag - credential delegation. */ public static final int CRED_DELEG = 0x1; /** * Context option flag - mutual authentication. */ public static final int MUTUAL_AUTH = 0x02; /** * Context option flag - replay detection. */ public static final int REPLAY_DET = 0x04; /** * Context option flag - sequence detection. */ public static final int SEQUENCE_DET = 0x08; /** * Context option flag - anonymity. */ public static final int ANON = 0x10; /** * Context option flag - confidentiality. */ public static final int CONF = 0x20; /** * Context option flag - integrity. */ public static final int INTG = 0x40; /** * Context option flag - transferability (output flag only). * Indicates if context may be transferred by using export(). * @see #export */ public static final int TRANS = 0x80; /** * Constructor for creating a context on the initiator's side. * Context flags may be modified through the set methods prior * to calling init(). * * @param peer Name of the target peer. * @param mechOid Oid of the desired mechanism; * may be null to indicate the default mechanism * @param myCred the credentials for the initiator; may be * null to indicate desire to use the default credentials * @param lifetime the request lifetime, in seconds, for the context * @exception GSSException with possible major codes of BAD_NAME, * BAD_MECH, BAD_NAMETYPE. * @see #init */ public GSSContext(GSSName peer, Oid mechOid, GSSCredential myCred, int lifetime) throws GSSException { initialize(); m_myCred = myCred; m_reqLifetime = lifetime; m_targName = peer; if (mechOid == null) m_mechOid = GSSManager.getDefaultMech(); else m_mechOid = mechOid; } /** * Constructor for creating a context on the acceptor' side. The * context's properties will be determined from the input token * supplied to accept(). * * @param myCred GSSCredential for the acceptor. Use null to * request usage of default credentials. * @exception GSSException with possible major codes of BAD_NAME, * BAD_MECH, BAD_NAMETYPE. * @see #accept */ public GSSContext(GSSCredential myCred) throws GSSException { initialize(); m_myCred = myCred; } /** * Constructor for creating a GSSContext from a previously * exported context. The context properties will be determined * from the input token. *

RFC 2078 *
equivalent to gss_import_sec_context
* @param interProcessToken the token emitted from export routine * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * NO_CONTEXT, DEFECTIVE_TOKEN, UNAVAILABLE, UNAUTHORIZED, FAILURE * @see #export */ public GSSContext(byte [] interProcessToken) throws GSSException { initialize(); /* * Strip the mechanism oid from the token * * the token encoding is implementation specific, and * we start by having 4 bytes of length, followed by the * mechanism oid of the specified length, followed by the * mechanism part of the token. This is the same as our C * version. */ try { int length = (interProcessToken[0] & 0xff); for (int i = 1; i < 4; i++) { length <<= 8; length += (interProcessToken[i] & 0xff); } ByteArrayInputStream is = new ByteArrayInputStream(interProcessToken); //ask mechanism to import this context m_mechCtxt = GSSManager._M4092FBA ( Oid.getFromDEROctets(is, length)); m_mechCtxt._S0AC8F9E (interProcessToken); m_curState = READY; } catch (ArrayIndexOutOfBoundsException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } } /** * Called by the context initiator to start the context creation * process. This is equivalent to the stream based method except * that the token buffers are handled as byte arrays instead of * using stream objects. This method may return an output token * which the application will need to send to the peer for * processing by the accept call. "null" return value indicates * that no token needs to be sent to the peer. The application * can call isEstablished to determine if the context * establishment phase is complete for this peer. A return value * of "false" from isEstablished indicates that more tokens are * expected to be supplied to the init method. Please note that * the init method may return a token for the peer, and * isEstablished return "true" also. This indicates that the token * needs to be sent to the peer, but the local end of the context * is now fully established. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. *

RFC 2078 *
equivalent to gss_init_sec_context; The requested context * options can be set before the first call, and the available * options can be obtained after the context is fully established. *
* @param inputBuf token generated by the peer; this parameter is * ignored on the first call * @param outputBuf token generated for the peer; this may be empty * @return establishment state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException with possible major values of DEFECTIVE_TOKEN, * DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, CREDENTIALS_EXPIRED, * BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, BAD_NAMETYPE, BAD_NAME, * BAD_MECH, and FAILURE * @see #init(InputStream,OutputStream) * @see #setChannelBinding */ public byte[] init(byte []inputBuf, int offset, int length) throws GSSException { ByteArrayInputStream is = null; if (inputBuf != null) is = new ByteArrayInputStream(inputBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); init(is, os); if (os.size() == 0) return (null); return (os.toByteArray()); } /** * Called by the context initiator to start the context creation * process. This is equivalent to the byte array based method. * This method may write an output token to the outputBuf, which * the application will need to send to the peer for processing * by the accept call. 0 bytes written to the output stream * indicate that no token needs to be sent to the peer. The * method will return either COMPLETE or CONTINUE_NEEDED * indicating the status of the current context. A return value * of COMPLETE indicates that the context establishment phase is * complete for this peer, while CONTINUE_NEEDED means that * another token is expected from the peer. The isEstablished * method can also be used to determine this state. Note that * it is possible to have a token for the peer while this method * returns COMPLETE. This indicates that the local end of the * context is established, but the token needs to be sent to * the peer to complete the context establishment. *

* The GSS-API authentication tokens contain a definitive * start and end. This method will attempt to read one of these * tokens per invocation, and may block on the stream if only * part of the token is available. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. *

RFC 2078 *
equivalent to gss_init_sec_context; The requested context * options can be set before the first call, and the available * options can be obtained after the context is fully established. *
* @param inputBuf token generated by the peer; this parameter is * ignored on the first call * @param outputBuf token generated for the peer; this may be empty * @return establishment state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException with possible major values of DEFECTIVE_TOKEN, * DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, CREDENTIALS_EXPIRED, * BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, BAD_NAMETYPE, BAD_NAME, * BAD_MECH, and FAILURE * @see #init(byte[],int,int) * @see #accept(byte[],int,int) * @see #setChannelBinding */ public int init(InputStream inputBuf, OutputStream outputBuf) throws GSSException { if (m_mechCtxt == null) { m_mechCtxt = GSSManager._M4092FBA (m_mechOid); GSSCredSpi mechCred = null; if (m_myCred != null) mechCred = m_myCred.getMechCred(m_mechOid, true); m_mechCtxt._S235D9C1 (mechCred, m_targName.canonicalizeInPlace(m_mechOid), m_reqLifetime, m_reqFlags); if (m_chB != null) m_mechCtxt._S9B00AB2 (m_chB); m_curState = IN_PROGRESS; } //debug code if (m_curState != IN_PROGRESS) { throw new GSSException(GSSException.FAILURE, -1, "wrong status in init"); } int retStatus = m_mechCtxt._S0E039DB (inputBuf, outputBuf); if (retStatus == COMPLETE) m_curState = READY; return (retStatus); } /** * Called by the context acceptor upon receiving a token from * the peer. This call is equivalent to the stream based method * except that the token buffers are handled as byte arrays * instead of using stream objects. *

* This method may return an output token which the application * will need to send to the peer for further processing by the * init call. "null" return value indicates that no token needs * to be sent to the peer. The application can call isEstablished * to determine if the context establishment phase is complete * for this peer. A return value of "false" from isEstablished * indicates that more tokens are expected to be supplied to this * method. *

* Please note that the accept method may return a token for the * peer, and isEstablished return "true" also. This indicates that * the token needs to be sent to the peer, but the local end of the * context is now fully established. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. * Called by the context acceptor upon receiving a token from * the peer. May need to be called again if returns CONTINUE_NEEDED. * *

RFC 2078 *
equivalent to gss_accept_sec_context; context options can * obtained through the query methods *
* @param inputToken token that was received from the initiator * @param outputBut token generated for the peer; may be empty * @return creation state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException may be thrown with major status values of * DEFECTIVE_TOKEN, DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, * CREDENTIALS_EXPIRED, BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, * BAD_MECH, and FAILURE * @see #init(byte[],int,int) * @see #accept(InputStream,OutputStream) * @see #setChannelBinding */ public byte[] accept(byte[] inTok, int offset, int length) throws GSSException { ByteArrayInputStream is = new ByteArrayInputStream(inTok, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); accept(is, os); //check if token is available for the peer if (os.size() == 0) return (null); return (os.toByteArray()); } /** * Called by the context acceptor upon receiving a token from * the peer. This call is equivalent to the byte array method. * It may write an output token to the outputBuf, which the * application will need to send to the peer for processing * by its init method. 0 bytes written to the output stream * indicate that no token needs to be sent to the peer. The * method will return either COMPLETE or CONTINUE_NEEDED * indicating the status of the current context. A return * value of COMPLETE indicates that the context establishment * phase is complete for this peer, while CONTINUE_NEEDED means * that another token is expected from the peer. The isEstablished * method can also be used to determine this state. Note that it * is possible to have a token for the peer while this method * returns COMPLETE. This indicates that the local end of the * context is established, but the token needs to be sent to * the peer to complete the context establishment. *

* The GSS-API authentication tokens contain a definitive start * and end. This method will attempt to read one of these tokens * per invocation, and may block on the stream if only part of the * token is available. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. * *

RFC 2078 *
equivalent to gss_accept_sec_context; context options can * obtained through the query methods
* @param inputToken token that was received from the initiator * @param outputBut token generated for the peer; may be empty * @return creation state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException may be thrown with major status values of * DEFECTIVE_TOKEN, DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, * CREDENTIALS_EXPIRED, BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, * BAD_MECH, and FAILURE * @see #accept(byte[],int,int) * @see #init(InputStream,OutputStream) * @see #setChannelBinding */ public int accept(InputStream inputBuf, OutputStream outputBuf) throws GSSException { if (m_mechCtxt == null) { //get the mechanism oid from the inputBuf Oid mechOid = getTokenMech(inputBuf); m_mechCtxt = GSSManager._M4092FBA (mechOid); if (m_myCred != null) m_mechCtxt._S90010CC ( m_myCred.getMechCred (mechOid, true)); if (m_chB != null) m_mechCtxt._S9B00AB2 (m_chB); m_curState = IN_PROGRESS; } //debug code if (m_curState != IN_PROGRESS) { throw new GSSException(GSSException.FAILURE, -1, "wrong status in accept"); } int retStatus = m_mechCtxt._S80A2F2C (inputBuf, outputBuf); if (retStatus == COMPLETE) m_curState = READY; return (retStatus); } /** * Returns true is this is a fully established context. Used after * the init and accept methods to check if more tokens are needed * from the peer. * * @return boolean indicating if this side of the context is * fully established. */ public boolean isEstablished() { return (m_curState == READY); } /** * Release any system resources and cryptographic information * stored in the context object. This will invalidate the * context. *

RFC 2078 *
equivalent to gss_delete_sec_context
* @exception GSSException with major codes NO_CONTEXT or FAILURE */ public void dispose() throws GSSException { checkState(IN_PROGRESS); m_mechCtxt._S020B957 (); m_curState = DELETED; } /** * Returns the maximum message size that, if presented to the * wrap method with the same confReq and qop parameters will * result in an output token containing no more then maxTokenSize * bytes. *

RFC 2078 *
equivalent to gss_wrap_size_limit
* @param qop quality of protection to apply to the message * @param confReq boolean indicating if privacy should be applied * @param maxTokenSize the maximum size of the token to be emitted * from wrap * @return maximum input buffer size for encapsulation by wrap * using the specified QOP and confReq without exceeding * the maxTokenSize * @exception GSSException with the possible major codes of BAD_QOP, * CONTEXT_EXPIRED, and FAILURE. * @see #wrap */ public int getWrapSizeLimit(int qop, boolean confReq, int maxTokenSize) throws GSSException { checkState(READY); return (m_mechCtxt._S808028B (qop, confReq, maxTokenSize)); } /** * Allows to apply per-message security services over the * established security context. The method will return a * token with a cryptographic MIC and may optionally encrypt * the specified inBuf. This method is equivalent i * functionality to its stream counterpart. The returned * byte array will contain both the MIC and the message. * The msgProp object is used to specify a QOP value which * selects cryptographic algorithms, and a privacy service, * if supported by the chosen mechanism. *

* Supports the wrapping and unwrapping of zero-length messages. *

* The application will be responsible for sending the token * to the peer. * *

RFC 2078 *
equivalent to gss_wrap; MessageProp object is used to * select QOP and confidentiality
* @param inBuf the application data to be protected * @param offset the offset in the inBuf where the data begins * @param length the length of the data starting at offset * @param msgPro indicates the desired QOP and confidentiality state, * and upon return the actual QOP and message confidentiality state * @return buffer to be sent to the peer for processing by unwrap * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * CREDENTIALS_EXPIRED, BAD_QOP, FAILURE. * @see #wrap(InputStream,OutputStream, MessageProp) * @see #unwrap(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] wrap(byte[] inBuf, int offset, int length, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * ByteArrayInputStream is = new ByteArrayInputStream(inBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); wrap(is, os, msgProp); //return output token return (os.toByteArray()); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Allows to apply per-message security services over the * established security context. The method will produce * a token with a cryptographic MIC and may optionally * encrypt the specified inBuf. The outBuf will contain * both the MIC and the message. The msgProp object is * used to specify a QOP value to select cryptographic * algorithms, and a privacy service, if supported by the * chosen mechanism. *

* Supports the wrapping and unwrapping of zero-length messages. *

* The application will be responsible for sending the token * to the peer. * *

RFC 2078 *
equivalent to gss_wrap; MessageProp object is used to * select QOP and confidentiality
* @param inputBuf the application data to be protected * @param outputBuf the token to be sent to the peer * @param msgPro indicates the desired QOP and confidentiality state, * and upon return the actual QOP and message confidentiality state * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * CREDENTIALS_EXPIRED, BAD_QOP, FAILURE. * @see #wrap(byte,int,int,MessageProp) * @see #unwrap(InputStream,OutputStream,MessageProp) * @see MessageProp */ public void wrap(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._S1309AFD (inBuf, outBuf, msgProp); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Used by the peer application to process tokens generated * with the wrap call. This call is equal in functionality * to its stream counterpart. The method will return the * message supplied in the peer application to the wrap call, * verifying the embedded MIC. The msgProp instance will * indicate whether the message was encrypted and will contain * the QOP indicating the strength of protection that was used * to provide the confidentiality and integrity services. *

* Supports the wrapping and unwrapping of zero-length messages. * *

RFC 2078 *
equivalent to the gss_unwrap
* * @param inBuf token received from peer application which was * generated by call to wrap * @param offset within the inBuf where the token begins. * @param length The length of the token in inBuf. * @param msgProp Upon return from the this method, will contain * QOP and privacy state of the supplied message as well as * any supplementary status values. * @return the application message used in the wrap call * @exception GSSException with possible major codes of DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED, CREDENTIALS_EXPIRED, and FAILURE. * @see #unwrap(InputStream,OutputStream,MessageProp) * @see #wrap(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] unwrap(byte[] inBuf, int offset, int length, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * ByteArrayInputStream is = new ByteArrayInputStream(inBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); unwrap(is, os, msgProp); //return output token if (os.size() > 0) return (os.toByteArray()); return (null); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Used by the peer application to process tokens generated with * the wrap call. This call is equal in functionality to its byte * array counterpart. It will produce the message supplied in the * peer application to the wrap call, verifying the embedded MIC. * The msgProp parameter will indicate whether the message was * encrypted and will contain the QOP indicating the strength * of protection that was used to provide the confidentiality * and integrity services. The msgProp object will also contain * the supplementary status information for the token. *

* Supports the wrapping and unwrapping of zero-length messages. * *

RFC 2078 *
equivalent to the gss_unwrap
* * @param inBuf token received from peer application which was * generated by call to wrap * @param outBuf original message passed into wrap * @param msgProp Upon return from the this method, will contain * QOP and privacy state of the supplied message as well as * any supplementary status values. * @exception GSSException with possible major codes of DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED, CREDENTIALS_EXPIRED, and FAILURE. * @see #unwrap(byte[],int,int,MessageProp) * @see #wrap(InputStream,OutputStream,MessageProp) * @see MessageProp */ public void unwrap(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._S1576D09 (inBuf, outBuf, msgProp); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Returns a token containing a cryptographic MIC for the * supplied message, for transfer to the peer application. * Unlike wrap, which encapsulates the user message in the * returned token, only the message MIC is returned in the * output token. This method is identical in functionality * to its stream counterpart. *

* Note that privacy can only be applied through the wrap call. *

* Supports the derivation of MICs from zero-length messages. * *

RFC 2078 *
equivalent to gss_getMIC
* @param inBuf message to apply security service to * @param offset The offset within the inMsg where the * token begins. * @param length the length of the application message * @param msgProp Indicates the desired QOP to be used. Use QOP of 0 * to indicate default value. The confidentiality flag * is ignored. Upon return from this method, this object * will contain the actual QOP applied (in case 0 was selected). * @return token containing cryptographic information for the * requested security service over the passed in message * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * BAD_QOP, FAILURE. * @see #getMIC(InputStream,OutputStream,MessageProp) * @see #verifyMIC(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] getMIC(byte[] inMsg, int offset, int length, MessageProp msgProp) throws GSSException { ByteArrayInputStream is = new ByteArrayInputStream(inMsg, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); getMIC(is, os, msgProp); //return output token return (os.toByteArray()); } /** * Produces a token containing a cryptographic MIC for the * supplied message, for transfer to the peer application. * Unlike wrap, which encapsulates the user message in the * returned token, only the message MIC is produced in the * output token. This method is identical in functionality * to its byte array counterpart. *

* Note that privacy can only be applied through the wrap call. *

* Supports the derivation of MICs from zero-length messages. * *

RFC 2078 *
equivalent to gss_getMIC
* @param inBuf Buffer containing the message to generate MIC over. * @param outBuf The buffer to write the GSS-API output token into. * @param msgProp Indicates the desired QOP to be used. Use QOP of 0 * to indicate default value. The confidentiality flag * is ignored. Upon return from this method, this object * will contain the actual QOP applied (in case 0 was selected). * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * BAD_QOP, FAILURE. * @see #getMIC(byte[],int,int,MessageProp) * @see #verifyMIC(byte[],int,int,byte[],int,int,MessageProp) * @see MessageProp */ public void getMIC(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._S1513DBA (inBuf, outBuf, msgProp); } /** * Verifies the cryptographic MIC, contained in the token * parameter, over the supplied message. The msgProp parameter * will contain the QOP indicating the strength of protection * that was applied to the message and any supplementary status * values for the token. This method is equivalent in * functionality to its stream counterpart. * *

RFC 2078 *
equivalent to gss_verifyMIC
* @param inTok token generated by peer's getMIC method * @param tokOffset the offset within the inTok where the token begins * @param tokLen the length of the token * @param inMsg Application message to verify the Cryptographic MIC * over. * @param msgOffset the offset within the inMsg where the message * begins * @param msgLen the length of the message * @param msgProp upon return from this method, this object * will contain the applied QOP and supplementary status * values for the supplied token. The privacy state will * always be set to false. * @exception GSSException with possible major codes DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED * @see #verifyMIC(InputStream,InputStream,MessageProp) * @see #wrap(byte[],int,int,MessageProp) * @see MessageProp */ public void verifyMIC(byte []inTok, int tokOffset, int tokLen, byte[] inMsg, int msgOffset, int msgLen, MessageProp msgProp) throws GSSException { ByteArrayInputStream sTok = new ByteArrayInputStream(inTok, tokOffset, tokLen); ByteArrayInputStream sMsg = new ByteArrayInputStream(inMsg, msgOffset, msgLen); verifyMIC(sTok, sMsg, msgProp); } /** * Verifies the cryptographic MIC, contained in the token * parameter, over the supplied message. The msgProp parameter * will contain the QOP indicating the strength of protection * that was applied to the message. This method is equivalent * in functionality to its byte array counterpart. * *

RFC 2078 *
equivalent to gss_verifyMIC
* @param inputTok Contains the token generated by peer's getMIC * method. * @param inputMsg Contains application message to verify the * cryptographic MIC over. * @param msgProp upon return from this method, this object * will contain the applied QOP and supplementary statustatus * values for the supplied token. The privacy state will * always be set to false. * @exception GSSException with possible major codes DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED * @see #verifyMIC(byte[],int,int,byte[],int,int,MessageProp) * @see #wrap(InputStream,OutputStream) * @see MessageProp */ public void verifyMIC(InputStream inTok, InputStream inMsg, MessageProp msgProp) throws GSSException { //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._S00256CF (inTok, inMsg, msgProp); } /** * Provided to support the sharing of work between multiple * processes. This routine will typically be used by the * context-acceptor, in an application where a single process * receives incoming connection requests and accepts security * contexts over them, then passes the established context to * one or more other processes for message exchange. *

* This method deactivates the security context and creates an * interprocess token which, when passed to the byte array * constructor of the GSSContext class in another process, * will re-activate the context in the second process. *

* Only a single instantiation of a given context may be active * at any one time; a subsequent attempt by a context exporter * to access the exported security context will fail. * *

RFC 2078 *
equivalent to gss_export_sec_context
* @return inter-process token representing the context * in export form * @exception GSSException with possible major codes of UNAVAILABLE, * CONTEXT_EXPIRED, NO_CONTEXT, FAILURE. * @see GSSContext#GSSContext(byte[]) * @see #isTransferable */ public byte [] export() throws GSSException { checkState(READY); byte [] outTok = m_mechCtxt._S725B2DA (); dispose(); return (outTok); } /** * Sets the request state of the mutual authentication flag * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the mutual_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if mutual authentication * should be requested during context establishment. * @exception GSSException may be thrown * @see #getMutualAuthState */ public void requestMutualAuth(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= MUTUAL_AUTH; else m_reqFlags ^= MUTUAL_AUTH; } /** * Sets the request state of the replay detection service * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the replay_det_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if replay detection is desired * over the established context. * @exception GSSException may be thrown * @see #getReplayDetState */ public void requestReplayDet(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= REPLAY_DET; else m_reqFlags ^= REPLAY_DET; } /** * Sets the request state of the sequence checking service * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the sequence_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if sequence checking service * is desired over the established context. * @exception GSSException may be thrown * @see #getSequenceDetState */ public void requestSequenceDet(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= SEQUENCE_DET; else m_reqFlags ^= SEQUENCE_DET; } /** * Sets the request state of the credential delegation flag * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the deleg_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if credential delegation is desired. * @exception GSSException may be thrown * @see #getDelegCredState */ public void requestCredDeleg(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= CRED_DELEG; else m_reqFlags ^= CRED_DELEG; } /** * Requests anonymous support over the context. This method is * only valid before the context creation process begins and * only for the initiator. * *

RFC 2078 *
equivalent to anon_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if anonymity support is desired. * @exception GSSException may be thrown * @see #getAnonymityState */ public void requestAnonymity(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= ANON; else m_reqFlags ^= ANON; } /** * Requests that confidentiality service be available over * the context. This method is only valid before the context * creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the conf_req_flag parameter in * gss_init_sec_context
* @param Boolean indicating if confidentiality services are to * be requested for the context. * @exception GSSException may be thrown * @see #getConfState */ public void requestConf(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= CONF; else m_reqFlags ^= CONF; } /** * Requests that integrity service be available over * the context. This method is only valid before the context * creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the integ_req_flag parameter in * gss_init_sec_context
* @param Boolean indicating if integrity services are to * be requested for the context. * @exception GSSException may be thrown * @see #getIntegState */ public void requestInteg(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= INTG; else m_reqFlags ^= INTG; } /** * Sets the desired lifetime for the context in seconds. * This method is only valid before the context creation * process begins and only for the initiator. * *

RFC 2078 *
equivalent to the lifetime_req parameter in * gss_init_sec_context
* @param The desired context lifetime in seconds. * @exception GSSException may be thrown * @see #getLifetime */ public void requestLifetime(int lifetime) throws GSSException { checkState(PRE_INIT); m_reqLifetime = lifetime; } /** * Sets the channel bindings to be used during context * establishment. This method is only valid before the * context creation process begins. * *

RFC 2078 *
equivalent to the chan_bindings parameter in * gss_init_sec_context and gss_accept_sec_context
* @param Channel binding to be used. * @exception GSSException may be thrown * @see ChannelBinding */ public void setChannelBinding(ChannelBinding cb) throws GSSException { checkState(PRE_INIT); m_chB = cb; } /** * Returns the state of the delegated credentials for the context. * When issued before context establishment completes or * when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the deleg_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating if delegated credentials are available * @see #requestCredDeleg * @see #isProtReady */ public boolean getDelegCredState() { if (m_curState < READY) return ((m_reqFlags & CRED_DELEG) == CRED_DELEG); return ((m_mechCtxt._S00027C3 () & CRED_DELEG) == CRED_DELEG); } /** * Returns the state of the mutual authentication option for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the mutual_state flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating state of mutual authentication option * @see #requestMutualAuth * @see #isProtReady */ public boolean getMutualAuthState() { if (m_curState < READY) return ((m_reqFlags & MUTUAL_AUTH) == MUTUAL_AUTH); return ((m_mechCtxt._S00027C3 () & MUTUAL_AUTH) == MUTUAL_AUTH); } /** * Returns the state of the replay detection service for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the replay_det_state flag output * parameter in gss_init_sec_context, gss_accept_sec_context * and gss_inquire_context
* @return boolean indicating replay detection state * @see #requestReplayDet * @see #isProtReady */ public boolean getReplayDetState() { if (m_curState < READY) return ((m_reqFlags & REPLAY_DET) == REPLAY_DET); return ((m_mechCtxt._S00027C3 () & REPLAY_DET) == REPLAY_DET); } /** * Returns the state of the sequence detection service for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the sequence_state flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating sequence detection state * @see #requestSequenceDet * @see #isProtReady */ public boolean getSequenceDetState() { if (m_curState < READY) return ((m_reqFlags & SEQUENCE_DET) == SEQUENCE_DET); return ((m_mechCtxt._S00027C3 () & SEQUENCE_DET) == SEQUENCE_DET); } /** * Returns true if this is an anonymous context. When issued * before context establishment completes or when the * isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the anon_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating anonymity state * @see #requestAnonymity * @see #isProtReady */ public boolean getAnonymityState() { if (m_curState < READY) return ((m_reqFlags & ANON) == ANON); return ((m_mechCtxt._S00027C3 () & ANON) == ANON); } /** * Indicates if the context is transferable to other processes * through the use of the export method. This call is only valid * on fully established contexts. * *

RFC 2078 *
equivalent to the trans_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating the transferability of the context * @exception GSSException may be thrown * @see #export */ public boolean isTransferable() throws GSSException { checkState(READY); return ((m_mechCtxt._S00027C3 () & TRANS) == TRANS); } /** * Indicates if the per message operations can be applied over * the context. Some mechanisms may allow to apply per-message * operations before the context is fully established. This will * also indicate that the get methods will return actual context * state characteristics instead of the desired ones. * *

RFC 2078 *
equivalent to the prot_ready_state flag output * parameter in gss_init_sec_context and * gss_accept_sec_context
* @return boolean indicating if per message operations are available */ public boolean isProtReady() { if (m_mechCtxt == null) return false; return (m_mechCtxt._S1116FAA ()); } /** * Returns the confidentiality service state over the context. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the conf_avail flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating confidentiality state * @see #requestConf * @see #isProtReady */ public boolean getConfState() { if (m_curState < READY) return ((m_reqFlags & CONF) == CONF); return ((m_mechCtxt._S00027C3 () & CONF) == CONF); } /** * Returns the integrity service state over the context. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the integ_avail flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating integrity state * @see #requestInteg * @see #isProtReady */ public boolean getIntegState() { if (m_curState < READY) return ((m_reqFlags & INTG) == INTG); return ((m_mechCtxt._S00027C3 () & INTG) == INTG); } /** * Returns the context lifetime in seconds. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * lifetime, otherwise it will indicate the actual lifetime over * the established context. * *

RFC 2078 *
equivalent to the lifetime_rec output parameter in * gss_init_sec_context, gss_accept_sec_context, * gss_inquire_context and to gss_context_time call
* @return lifetime in seconds * @see #requestLifetime * @see #isProtReady */ public int getLifetime() { if (m_curState < READY) return (m_reqLifetime); return (m_mechCtxt._S4080EED ()); } /** * Retrieves the name of the context initiator. * This call is valid only after context has been fully established * or when the isProtReady methods returns true. * *

RFC 2078 *
equivalent to the src_name parameter in * gss_accept_sec_context and gss_inquire_context
* @return name of the context initiator * @exception GSSException with possible major codes of CONTEXT_EXPIRED * and FAILURE * @see #isProtReady */ public GSSName getSrcName() throws GSSException { checkState(IN_PROGRESS); return (new GSSName(m_mechCtxt._S000EEFF ())); } /** * Retrieves the name of the context target (acceptor). * This call is only valid on fully established contexts * or when the isProtReady methods returns true. * *

RFC 2078 *
equivalent to the targ_name parameter in * gss_inquire_context
* @return name of the context target (acceptor) * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE * @see #isProtReady */ public GSSName getTargName() throws GSSException { checkState(IN_PROGRESS); return (new GSSName(m_mechCtxt._S011CEF9 ())); } /** * Returns the mechanism oid for the context. * *

RFC 2078 *
equivalent to the mech_type parameter in * gss_accept_sec_context and gss_inquire_context
* @return Oid object for the context's mechanism * @exception GSSException may be thrown when the mechanism * oid can't be determined * */ public Oid getMech() throws GSSException { checkState(IN_PROGRESS); return (m_mechCtxt._S0200735 ()); } /** * Returns the delegated credential object on the acceptor's side. * To check for availability of delegated credentials call * getDelegCredState. This call is only valid on fully established * contexts. * *

RFC 2078 *
equivalent to delegated_cred_handle parameter * in gss_accept_sec_context
* @return delegated credential object for the context * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE * @see #getDelegCredState */ public GSSCredential getDelegCred() throws GSSException { checkState(IN_PROGRESS); return (new GSSCredential(m_mechCtxt._S0293FFA ())); } /** * Returns true if this is the initiator of the context. * This call is only valid after the context creation process * has started. * *

RFC 2078 *
equivalent to locally_initiated output parameter * in gss_inquire_context
* @return true if this is the context initiator * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE */ public boolean isInitiator() throws GSSException { checkState(IN_PROGRESS); return (m_mechCtxt._S123049E ()); } /** * Ensures the object is in the required state. * * @param minimumState the minimum required state. * @exception GSSException is thrown when the state is incorrect. */ private void checkState(int minimumState) throws GSSException { if (m_curState < minimumState) throw new GSSException(GSSException.NO_CONTEXT); //this is just temporary for debugging if (minimumState > PRE_INIT && m_mechCtxt == null) throw new GSSException(GSSException.NO_CONTEXT, -1, "error in checkState"); } /** * Private initializer of context variables */ private void initialize() { m_reqFlags = MUTUAL_AUTH | SEQUENCE_DET | REPLAY_DET; m_myCred = null; m_reqLifetime = INDEFINITE; m_curState = PRE_INIT; m_mechOid = null; m_targName = null; m_chB = null; } /** * Reads the token header as defined in RFC 2078 and * returns the mechanism oid. Currently this requires that * the stream support mark/reset operations. As an * alternative we can strip this header, and pass the information * into the mechanism. */ private Oid getTokenMech(InputStream is) throws GSSException { try { is.mark(100); if (is.read() != 0x60) throw new GSSException(GSSException.DEFECTIVE_TOKEN); //we can skip the token length DERParser.readLength(is); //next we have the full der encoding of the oid Oid res = new Oid(is); is.reset(); return (res); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } } //private flags for the context state private static final int PRE_INIT = 1; private static final int IN_PROGRESS = 2; private static final int READY = 3; private static final int DELETED = 4; //instance variables private C018FE95 m_mechCtxt; private int m_reqFlags; private GSSCredential m_myCred; private int m_reqLifetime; private int m_curState; private Oid m_mechOid; private GSSName m_targName; private ChannelBinding m_chB; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSContext.m4000066400000000000000000001652461356275373100234160ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * This class represents the JGSS security context and its associated * operations. JGSS security contexts are established between * peers using locally established credentials. Multiple contexts * may exist simultaneously between a pair of peers, using the same * or different set of credentials. The JGSS is independent of * the underlying transport protocols and depends on its callers to * transport the tokens between peers. *

* The context object can be thought of as having 3 implicit states: * before it is established, during its context establishment, and * after a fully established context exists. *

* Before the context establishment phase is initiated, the context * initiator may request specific characteristics desired of the * established context. These can be set using the set methods. After the * context is established, the caller can check the actual characteristic * and services offered by the context using the query methods. *

* The context establishment phase begins with the first call to the init * method by the context initiator. During this phase the init and accept * methods will produce GSS-API authentication tokens which the calling * application needs to send to its peer. The init and accept methods may * return a CONTINUE_NEEDED code which indicates that a token is needed * from its peer in order to continue the context establishment phase. A * return code of COMPLETE signals that the local end of the context is * established. This may still require that a token be sent to the peer, * depending if one is produced by GSS-API. The isEstablished method can * also be used to determine if the local end of the context has been * fully established. During the context establishment phase, the * isProtReady method may be called to determine if the context can be * used for the per-message operations. This allows implementation to * use per-message operations on contexts which aren't fully established. *

* After the context has been established or the isProtReady method * returns "true", the query routines can be invoked to determine the actual * characteristics and services of the established context. The * application can also start using the per-message methods of wrap and * getMIC to obtain cryptographic operations on application supplied data. *

* When the context is no longer needed, the application should call * dispose to release any system resources the context may be using. *

RFC 2078 *
This class corresponds to the context level calls together with * the per message calls of RFC 2078. The gss_init_sec_context and * gss_accept_sec_context calls have been made simpler by only taking * required parameters. The context can have its properties set before * the first call to init. The supplementary status codes for the per-message * operations are returned in an instance of the MessageProp class, which is * used as an argument in these calls.
*/ public class GSSContext { /** * Indefinite lifetime value for a context. Set to the * largest value for an int in Java. * @see #getLifetime */ public static final int INDEFINITE = Integer.MAX_VALUE; /** * Return value from either accept or init stating that * the context creation phase is complete for this peer. * @see #init * @see #accept */ public static final int COMPLETE = 0; /** * Return value from either accept or init stating that * another token is required from the peer to continue context * creation. This may be returned several times indicating * multiple token exchanges. * @see #init * @see #accept */ public static final int CONTINUE_NEEDED = 1; /** * Context option flag - credential delegation. */ public static final int CRED_DELEG = 0x1; /** * Context option flag - mutual authentication. */ public static final int MUTUAL_AUTH = 0x02; /** * Context option flag - replay detection. */ public static final int REPLAY_DET = 0x04; /** * Context option flag - sequence detection. */ public static final int SEQUENCE_DET = 0x08; /** * Context option flag - anonymity. */ public static final int ANON = 0x10; /** * Context option flag - confidentiality. */ public static final int CONF = 0x20; /** * Context option flag - integrity. */ public static final int INTG = 0x40; /** * Context option flag - transferability (output flag only). * Indicates if context may be transferred by using export(). * @see #export */ public static final int TRANS = 0x80; /** * Constructor for creating a context on the initiator's side. * Context flags may be modified through the set methods prior * to calling init(). * * @param peer Name of the target peer. * @param mechOid Oid of the desired mechanism; * may be null to indicate the default mechanism * @param myCred the credentials for the initiator; may be * null to indicate desire to use the default credentials * @param lifetime the request lifetime, in seconds, for the context * @exception GSSException with possible major codes of BAD_NAME, * BAD_MECH, BAD_NAMETYPE. * @see #init */ public GSSContext(GSSName peer, Oid mechOid, GSSCredential myCred, int lifetime) throws GSSException { initialize(); m_myCred = myCred; m_reqLifetime = lifetime; m_targName = peer; if (mechOid == null) m_mechOid = GSSManager.getDefaultMech(); else m_mechOid = mechOid; } /** * Constructor for creating a context on the acceptor' side. The * context's properties will be determined from the input token * supplied to accept(). * * @param myCred GSSCredential for the acceptor. Use null to * request usage of default credentials. * @exception GSSException with possible major codes of BAD_NAME, * BAD_MECH, BAD_NAMETYPE. * @see #accept */ public GSSContext(GSSCredential myCred) throws GSSException { initialize(); m_myCred = myCred; } /** * Constructor for creating a GSSContext from a previously * exported context. The context properties will be determined * from the input token. *

RFC 2078 *
equivalent to gss_import_sec_context
* @param interProcessToken the token emitted from export routine * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * NO_CONTEXT, DEFECTIVE_TOKEN, UNAVAILABLE, UNAUTHORIZED, FAILURE * @see #export */ public GSSContext(byte [] interProcessToken) throws GSSException { initialize(); /* * Strip the mechanism oid from the token * * the token encoding is implementation specific, and * we start by having 4 bytes of length, followed by the * mechanism oid of the specified length, followed by the * mechanism part of the token. This is the same as our C * version. */ try { int length = (interProcessToken[0] & 0xff); for (int i = 1; i < 4; i++) { length <<= 8; length += (interProcessToken[i] & 0xff); } ByteArrayInputStream is = new ByteArrayInputStream(interProcessToken); //ask mechanism to import this context m_mechCtxt = GSSManager.getCtxtInstance ( Oid.getFromDEROctets(is, length)); m_mechCtxt._importSecCtxt (interProcessToken); m_curState = READY; } catch (ArrayIndexOutOfBoundsException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } } /** * Called by the context initiator to start the context creation * process. This is equivalent to the stream based method except * that the token buffers are handled as byte arrays instead of * using stream objects. This method may return an output token * which the application will need to send to the peer for * processing by the accept call. "null" return value indicates * that no token needs to be sent to the peer. The application * can call isEstablished to determine if the context * establishment phase is complete for this peer. A return value * of "false" from isEstablished indicates that more tokens are * expected to be supplied to the init method. Please note that * the init method may return a token for the peer, and * isEstablished return "true" also. This indicates that the token * needs to be sent to the peer, but the local end of the context * is now fully established. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. *

RFC 2078 *
equivalent to gss_init_sec_context; The requested context * options can be set before the first call, and the available * options can be obtained after the context is fully established. *
* @param inputBuf token generated by the peer; this parameter is * ignored on the first call * @param outputBuf token generated for the peer; this may be empty * @return establishment state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException with possible major values of DEFECTIVE_TOKEN, * DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, CREDENTIALS_EXPIRED, * BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, BAD_NAMETYPE, BAD_NAME, * BAD_MECH, and FAILURE * @see #init(InputStream,OutputStream) * @see #setChannelBinding */ public byte[] init(byte []inputBuf, int offset, int length) throws GSSException { ByteArrayInputStream is = null; if (inputBuf != null) is = new ByteArrayInputStream(inputBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); init(is, os); if (os.size() == 0) return (null); return (os.toByteArray()); } /** * Called by the context initiator to start the context creation * process. This is equivalent to the byte array based method. * This method may write an output token to the outputBuf, which * the application will need to send to the peer for processing * by the accept call. 0 bytes written to the output stream * indicate that no token needs to be sent to the peer. The * method will return either COMPLETE or CONTINUE_NEEDED * indicating the status of the current context. A return value * of COMPLETE indicates that the context establishment phase is * complete for this peer, while CONTINUE_NEEDED means that * another token is expected from the peer. The isEstablished * method can also be used to determine this state. Note that * it is possible to have a token for the peer while this method * returns COMPLETE. This indicates that the local end of the * context is established, but the token needs to be sent to * the peer to complete the context establishment. *

* The GSS-API authentication tokens contain a definitive * start and end. This method will attempt to read one of these * tokens per invocation, and may block on the stream if only * part of the token is available. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. *

RFC 2078 *
equivalent to gss_init_sec_context; The requested context * options can be set before the first call, and the available * options can be obtained after the context is fully established. *
* @param inputBuf token generated by the peer; this parameter is * ignored on the first call * @param outputBuf token generated for the peer; this may be empty * @return establishment state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException with possible major values of DEFECTIVE_TOKEN, * DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, CREDENTIALS_EXPIRED, * BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, BAD_NAMETYPE, BAD_NAME, * BAD_MECH, and FAILURE * @see #init(byte[],int,int) * @see #accept(byte[],int,int) * @see #setChannelBinding */ public int init(InputStream inputBuf, OutputStream outputBuf) throws GSSException { if (m_mechCtxt == null) { m_mechCtxt = GSSManager.getCtxtInstance (m_mechOid); GSSCredSpi mechCred = null; if (m_myCred != null) mechCred = m_myCred.getMechCred(m_mechOid, true); m_mechCtxt._setInitOptions (mechCred, m_targName.canonicalizeInPlace(m_mechOid), m_reqLifetime, m_reqFlags); if (m_chB != null) m_mechCtxt._setChannelBinding (m_chB); m_curState = IN_PROGRESS; } //debug code if (m_curState != IN_PROGRESS) { throw new GSSException(GSSException.FAILURE, -1, "wrong status in init"); } int retStatus = m_mechCtxt._initSecCtxt (inputBuf, outputBuf); if (retStatus == COMPLETE) m_curState = READY; return (retStatus); } /** * Called by the context acceptor upon receiving a token from * the peer. This call is equivalent to the stream based method * except that the token buffers are handled as byte arrays * instead of using stream objects. *

* This method may return an output token which the application * will need to send to the peer for further processing by the * init call. "null" return value indicates that no token needs * to be sent to the peer. The application can call isEstablished * to determine if the context establishment phase is complete * for this peer. A return value of "false" from isEstablished * indicates that more tokens are expected to be supplied to this * method. *

* Please note that the accept method may return a token for the * peer, and isEstablished return "true" also. This indicates that * the token needs to be sent to the peer, but the local end of the * context is now fully established. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. * Called by the context acceptor upon receiving a token from * the peer. May need to be called again if returns CONTINUE_NEEDED. * *

RFC 2078 *
equivalent to gss_accept_sec_context; context options can * obtained through the query methods *
* @param inputToken token that was received from the initiator * @param outputBut token generated for the peer; may be empty * @return creation state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException may be thrown with major status values of * DEFECTIVE_TOKEN, DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, * CREDENTIALS_EXPIRED, BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, * BAD_MECH, and FAILURE * @see #init(byte[],int,int) * @see #accept(InputStream,OutputStream) * @see #setChannelBinding */ public byte[] accept(byte[] inTok, int offset, int length) throws GSSException { ByteArrayInputStream is = new ByteArrayInputStream(inTok, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); accept(is, os); //check if token is available for the peer if (os.size() == 0) return (null); return (os.toByteArray()); } /** * Called by the context acceptor upon receiving a token from * the peer. This call is equivalent to the byte array method. * It may write an output token to the outputBuf, which the * application will need to send to the peer for processing * by its init method. 0 bytes written to the output stream * indicate that no token needs to be sent to the peer. The * method will return either COMPLETE or CONTINUE_NEEDED * indicating the status of the current context. A return * value of COMPLETE indicates that the context establishment * phase is complete for this peer, while CONTINUE_NEEDED means * that another token is expected from the peer. The isEstablished * method can also be used to determine this state. Note that it * is possible to have a token for the peer while this method * returns COMPLETE. This indicates that the local end of the * context is established, but the token needs to be sent to * the peer to complete the context establishment. *

* The GSS-API authentication tokens contain a definitive start * and end. This method will attempt to read one of these tokens * per invocation, and may block on the stream if only part of the * token is available. *

* Upon completion of the context establishment, the available * context options may be queried through the get methods. * *

RFC 2078 *
equivalent to gss_accept_sec_context; context options can * obtained through the query methods
* @param inputToken token that was received from the initiator * @param outputBut token generated for the peer; may be empty * @return creation state of either COMPLETE or CONTINUE_NEEDED * @exception GSSException may be thrown with major status values of * DEFECTIVE_TOKEN, DEFECTIVE_CREDENTIAL, BAD_SIG, NO_CRED, * CREDENTIALS_EXPIRED, BAD_BINDINGS, OLD_TOKEN, DUPLICATE_ELEMENT, * BAD_MECH, and FAILURE * @see #accept(byte[],int,int) * @see #init(InputStream,OutputStream) * @see #setChannelBinding */ public int accept(InputStream inputBuf, OutputStream outputBuf) throws GSSException { if (m_mechCtxt == null) { //get the mechanism oid from the inputBuf Oid mechOid = getTokenMech(inputBuf); m_mechCtxt = GSSManager.getCtxtInstance (mechOid); if (m_myCred != null) m_mechCtxt._setAcceptOptions ( m_myCred.getMechCred (mechOid, true)); if (m_chB != null) m_mechCtxt._setChannelBinding (m_chB); m_curState = IN_PROGRESS; } //debug code if (m_curState != IN_PROGRESS) { throw new GSSException(GSSException.FAILURE, -1, "wrong status in accept"); } int retStatus = m_mechCtxt._acceptSecCtxt (inputBuf, outputBuf); if (retStatus == COMPLETE) m_curState = READY; return (retStatus); } /** * Returns true is this is a fully established context. Used after * the init and accept methods to check if more tokens are needed * from the peer. * * @return boolean indicating if this side of the context is * fully established. */ public boolean isEstablished() { return (m_curState == READY); } /** * Release any system resources and cryptographic information * stored in the context object. This will invalidate the * context. *

RFC 2078 *
equivalent to gss_delete_sec_context
* @exception GSSException with major codes NO_CONTEXT or FAILURE */ public void dispose() throws GSSException { checkState(IN_PROGRESS); m_mechCtxt._dispose (); m_curState = DELETED; } /** * Returns the maximum message size that, if presented to the * wrap method with the same confReq and qop parameters will * result in an output token containing no more then maxTokenSize * bytes. *

RFC 2078 *
equivalent to gss_wrap_size_limit
* @param qop quality of protection to apply to the message * @param confReq boolean indicating if privacy should be applied * @param maxTokenSize the maximum size of the token to be emitted * from wrap * @return maximum input buffer size for encapsulation by wrap * using the specified QOP and confReq without exceeding * the maxTokenSize * @exception GSSException with the possible major codes of BAD_QOP, * CONTEXT_EXPIRED, and FAILURE. * @see #wrap */ public int getWrapSizeLimit(int qop, boolean confReq, int maxTokenSize) throws GSSException { checkState(READY); return (m_mechCtxt._getWrapSizeLimit (qop, confReq, maxTokenSize)); } /** * Allows to apply per-message security services over the * established security context. The method will return a * token with a cryptographic MIC and may optionally encrypt * the specified inBuf. This method is equivalent i * functionality to its stream counterpart. The returned * byte array will contain both the MIC and the message. * The msgProp object is used to specify a QOP value which * selects cryptographic algorithms, and a privacy service, * if supported by the chosen mechanism. *

* Supports the wrapping and unwrapping of zero-length messages. *

* The application will be responsible for sending the token * to the peer. * *

RFC 2078 *
equivalent to gss_wrap; MessageProp object is used to * select QOP and confidentiality
* @param inBuf the application data to be protected * @param offset the offset in the inBuf where the data begins * @param length the length of the data starting at offset * @param msgPro indicates the desired QOP and confidentiality state, * and upon return the actual QOP and message confidentiality state * @return buffer to be sent to the peer for processing by unwrap * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * CREDENTIALS_EXPIRED, BAD_QOP, FAILURE. * @see #wrap(InputStream,OutputStream, MessageProp) * @see #unwrap(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] wrap(byte[] inBuf, int offset, int length, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * ByteArrayInputStream is = new ByteArrayInputStream(inBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); wrap(is, os, msgProp); //return output token return (os.toByteArray()); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Allows to apply per-message security services over the * established security context. The method will produce * a token with a cryptographic MIC and may optionally * encrypt the specified inBuf. The outBuf will contain * both the MIC and the message. The msgProp object is * used to specify a QOP value to select cryptographic * algorithms, and a privacy service, if supported by the * chosen mechanism. *

* Supports the wrapping and unwrapping of zero-length messages. *

* The application will be responsible for sending the token * to the peer. * *

RFC 2078 *
equivalent to gss_wrap; MessageProp object is used to * select QOP and confidentiality
* @param inputBuf the application data to be protected * @param outputBuf the token to be sent to the peer * @param msgPro indicates the desired QOP and confidentiality state, * and upon return the actual QOP and message confidentiality state * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * CREDENTIALS_EXPIRED, BAD_QOP, FAILURE. * @see #wrap(byte,int,int,MessageProp) * @see #unwrap(InputStream,OutputStream,MessageProp) * @see MessageProp */ public void wrap(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._wrap (inBuf, outBuf, msgProp); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Used by the peer application to process tokens generated * with the wrap call. This call is equal in functionality * to its stream counterpart. The method will return the * message supplied in the peer application to the wrap call, * verifying the embedded MIC. The msgProp instance will * indicate whether the message was encrypted and will contain * the QOP indicating the strength of protection that was used * to provide the confidentiality and integrity services. *

* Supports the wrapping and unwrapping of zero-length messages. * *

RFC 2078 *
equivalent to the gss_unwrap
* * @param inBuf token received from peer application which was * generated by call to wrap * @param offset within the inBuf where the token begins. * @param length The length of the token in inBuf. * @param msgProp Upon return from the this method, will contain * QOP and privacy state of the supplied message as well as * any supplementary status values. * @return the application message used in the wrap call * @exception GSSException with possible major codes of DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED, CREDENTIALS_EXPIRED, and FAILURE. * @see #unwrap(InputStream,OutputStream,MessageProp) * @see #wrap(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] unwrap(byte[] inBuf, int offset, int length, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * ByteArrayInputStream is = new ByteArrayInputStream(inBuf, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); unwrap(is, os, msgProp); //return output token if (os.size() > 0) return (os.toByteArray()); return (null); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Used by the peer application to process tokens generated with * the wrap call. This call is equal in functionality to its byte * array counterpart. It will produce the message supplied in the * peer application to the wrap call, verifying the embedded MIC. * The msgProp parameter will indicate whether the message was * encrypted and will contain the QOP indicating the strength * of protection that was used to provide the confidentiality * and integrity services. The msgProp object will also contain * the supplementary status information for the token. *

* Supports the wrapping and unwrapping of zero-length messages. * *

RFC 2078 *
equivalent to the gss_unwrap
* * @param inBuf token received from peer application which was * generated by call to wrap * @param outBuf original message passed into wrap * @param msgProp Upon return from the this method, will contain * QOP and privacy state of the supplied message as well as * any supplementary status values. * @exception GSSException with possible major codes of DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED, CREDENTIALS_EXPIRED, and FAILURE. * @see #unwrap(byte[],int,int,MessageProp) * @see #wrap(InputStream,OutputStream,MessageProp) * @see MessageProp */ public void unwrap(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { /* * XXX EXPORT DELETE START * * Turn off the privacy. Once an export control liscence * is issued, this routine can be turned back on. * //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._unwrap (inBuf, outBuf, msgProp); * XXX EXPORT DELETE END */ // XXX delete this line once this routine is turned back on. throw new GSSException(GSSException.FAILURE); } /** * Returns a token containing a cryptographic MIC for the * supplied message, for transfer to the peer application. * Unlike wrap, which encapsulates the user message in the * returned token, only the message MIC is returned in the * output token. This method is identical in functionality * to its stream counterpart. *

* Note that privacy can only be applied through the wrap call. *

* Supports the derivation of MICs from zero-length messages. * *

RFC 2078 *
equivalent to gss_getMIC
* @param inBuf message to apply security service to * @param offset The offset within the inMsg where the * token begins. * @param length the length of the application message * @param msgProp Indicates the desired QOP to be used. Use QOP of 0 * to indicate default value. The confidentiality flag * is ignored. Upon return from this method, this object * will contain the actual QOP applied (in case 0 was selected). * @return token containing cryptographic information for the * requested security service over the passed in message * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * BAD_QOP, FAILURE. * @see #getMIC(InputStream,OutputStream,MessageProp) * @see #verifyMIC(byte[],int,int,MessageProp) * @see MessageProp */ public byte[] getMIC(byte[] inMsg, int offset, int length, MessageProp msgProp) throws GSSException { ByteArrayInputStream is = new ByteArrayInputStream(inMsg, offset, length); ByteArrayOutputStream os = new ByteArrayOutputStream(); getMIC(is, os, msgProp); //return output token return (os.toByteArray()); } /** * Produces a token containing a cryptographic MIC for the * supplied message, for transfer to the peer application. * Unlike wrap, which encapsulates the user message in the * returned token, only the message MIC is produced in the * output token. This method is identical in functionality * to its byte array counterpart. *

* Note that privacy can only be applied through the wrap call. *

* Supports the derivation of MICs from zero-length messages. * *

RFC 2078 *
equivalent to gss_getMIC
* @param inBuf Buffer containing the message to generate MIC over. * @param outBuf The buffer to write the GSS-API output token into. * @param msgProp Indicates the desired QOP to be used. Use QOP of 0 * to indicate default value. The confidentiality flag * is ignored. Upon return from this method, this object * will contain the actual QOP applied (in case 0 was selected). * @exception GSSException with possible major codes of CONTEXT_EXPIRED, * BAD_QOP, FAILURE. * @see #getMIC(byte[],int,int,MessageProp) * @see #verifyMIC(byte[],int,int,byte[],int,int,MessageProp) * @see MessageProp */ public void getMIC(InputStream inBuf, OutputStream outBuf, MessageProp msgProp) throws GSSException { //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._getMIC (inBuf, outBuf, msgProp); } /** * Verifies the cryptographic MIC, contained in the token * parameter, over the supplied message. The msgProp parameter * will contain the QOP indicating the strength of protection * that was applied to the message and any supplementary status * values for the token. This method is equivalent in * functionality to its stream counterpart. * *

RFC 2078 *
equivalent to gss_verifyMIC
* @param inTok token generated by peer's getMIC method * @param tokOffset the offset within the inTok where the token begins * @param tokLen the length of the token * @param inMsg Application message to verify the Cryptographic MIC * over. * @param msgOffset the offset within the inMsg where the message * begins * @param msgLen the length of the message * @param msgProp upon return from this method, this object * will contain the applied QOP and supplementary status * values for the supplied token. The privacy state will * always be set to false. * @exception GSSException with possible major codes DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED * @see #verifyMIC(InputStream,InputStream,MessageProp) * @see #wrap(byte[],int,int,MessageProp) * @see MessageProp */ public void verifyMIC(byte []inTok, int tokOffset, int tokLen, byte[] inMsg, int msgOffset, int msgLen, MessageProp msgProp) throws GSSException { ByteArrayInputStream sTok = new ByteArrayInputStream(inTok, tokOffset, tokLen); ByteArrayInputStream sMsg = new ByteArrayInputStream(inMsg, msgOffset, msgLen); verifyMIC(sTok, sMsg, msgProp); } /** * Verifies the cryptographic MIC, contained in the token * parameter, over the supplied message. The msgProp parameter * will contain the QOP indicating the strength of protection * that was applied to the message. This method is equivalent * in functionality to its byte array counterpart. * *

RFC 2078 *
equivalent to gss_verifyMIC
* @param inputTok Contains the token generated by peer's getMIC * method. * @param inputMsg Contains application message to verify the * cryptographic MIC over. * @param msgProp upon return from this method, this object * will contain the applied QOP and supplementary statustatus * values for the supplied token. The privacy state will * always be set to false. * @exception GSSException with possible major codes DEFECTIVE_TOKEN, * BAD_SIG, CONTEXT_EXPIRED * @see #verifyMIC(byte[],int,int,byte[],int,int,MessageProp) * @see #wrap(InputStream,OutputStream) * @see MessageProp */ public void verifyMIC(InputStream inTok, InputStream inMsg, MessageProp msgProp) throws GSSException { //clear status values msgProp.resetStatusValues(); checkState(READY); m_mechCtxt._verifyMIC (inTok, inMsg, msgProp); } /** * Provided to support the sharing of work between multiple * processes. This routine will typically be used by the * context-acceptor, in an application where a single process * receives incoming connection requests and accepts security * contexts over them, then passes the established context to * one or more other processes for message exchange. *

* This method deactivates the security context and creates an * interprocess token which, when passed to the byte array * constructor of the GSSContext class in another process, * will re-activate the context in the second process. *

* Only a single instantiation of a given context may be active * at any one time; a subsequent attempt by a context exporter * to access the exported security context will fail. * *

RFC 2078 *
equivalent to gss_export_sec_context
* @return inter-process token representing the context * in export form * @exception GSSException with possible major codes of UNAVAILABLE, * CONTEXT_EXPIRED, NO_CONTEXT, FAILURE. * @see GSSContext#GSSContext(byte[]) * @see #isTransferable */ public byte [] export() throws GSSException { checkState(READY); byte [] outTok = m_mechCtxt._export (); dispose(); return (outTok); } /** * Sets the request state of the mutual authentication flag * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the mutual_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if mutual authentication * should be requested during context establishment. * @exception GSSException may be thrown * @see #getMutualAuthState */ public void requestMutualAuth(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= MUTUAL_AUTH; else m_reqFlags ^= MUTUAL_AUTH; } /** * Sets the request state of the replay detection service * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the replay_det_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if replay detection is desired * over the established context. * @exception GSSException may be thrown * @see #getReplayDetState */ public void requestReplayDet(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= REPLAY_DET; else m_reqFlags ^= REPLAY_DET; } /** * Sets the request state of the sequence checking service * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the sequence_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if sequence checking service * is desired over the established context. * @exception GSSException may be thrown * @see #getSequenceDetState */ public void requestSequenceDet(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= SEQUENCE_DET; else m_reqFlags ^= SEQUENCE_DET; } /** * Sets the request state of the credential delegation flag * for the context. This method is only valid before the * context creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the deleg_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if credential delegation is desired. * @exception GSSException may be thrown * @see #getDelegCredState */ public void requestCredDeleg(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= CRED_DELEG; else m_reqFlags ^= CRED_DELEG; } /** * Requests anonymous support over the context. This method is * only valid before the context creation process begins and * only for the initiator. * *

RFC 2078 *
equivalent to anon_req_flag parameter in * gss_init_sec_context
* @param Boolean representing if anonymity support is desired. * @exception GSSException may be thrown * @see #getAnonymityState */ public void requestAnonymity(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= ANON; else m_reqFlags ^= ANON; } /** * Requests that confidentiality service be available over * the context. This method is only valid before the context * creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the conf_req_flag parameter in * gss_init_sec_context
* @param Boolean indicating if confidentiality services are to * be requested for the context. * @exception GSSException may be thrown * @see #getConfState */ public void requestConf(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= CONF; else m_reqFlags ^= CONF; } /** * Requests that integrity service be available over * the context. This method is only valid before the context * creation process begins and only for the initiator. * *

RFC 2078 *
equivalent to the integ_req_flag parameter in * gss_init_sec_context
* @param Boolean indicating if integrity services are to * be requested for the context. * @exception GSSException may be thrown * @see #getIntegState */ public void requestInteg(boolean state) throws GSSException { checkState(PRE_INIT); if (state) m_reqFlags |= INTG; else m_reqFlags ^= INTG; } /** * Sets the desired lifetime for the context in seconds. * This method is only valid before the context creation * process begins and only for the initiator. * *

RFC 2078 *
equivalent to the lifetime_req parameter in * gss_init_sec_context
* @param The desired context lifetime in seconds. * @exception GSSException may be thrown * @see #getLifetime */ public void requestLifetime(int lifetime) throws GSSException { checkState(PRE_INIT); m_reqLifetime = lifetime; } /** * Sets the channel bindings to be used during context * establishment. This method is only valid before the * context creation process begins. * *

RFC 2078 *
equivalent to the chan_bindings parameter in * gss_init_sec_context and gss_accept_sec_context
* @param Channel binding to be used. * @exception GSSException may be thrown * @see ChannelBinding */ public void setChannelBinding(ChannelBinding cb) throws GSSException { checkState(PRE_INIT); m_chB = cb; } /** * Returns the state of the delegated credentials for the context. * When issued before context establishment completes or * when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the deleg_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating if delegated credentials are available * @see #requestCredDeleg * @see #isProtReady */ public boolean getDelegCredState() { if (m_curState < READY) return ((m_reqFlags & CRED_DELEG) == CRED_DELEG); return ((m_mechCtxt._getOptions () & CRED_DELEG) == CRED_DELEG); } /** * Returns the state of the mutual authentication option for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the mutual_state flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating state of mutual authentication option * @see #requestMutualAuth * @see #isProtReady */ public boolean getMutualAuthState() { if (m_curState < READY) return ((m_reqFlags & MUTUAL_AUTH) == MUTUAL_AUTH); return ((m_mechCtxt._getOptions () & MUTUAL_AUTH) == MUTUAL_AUTH); } /** * Returns the state of the replay detection service for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the replay_det_state flag output * parameter in gss_init_sec_context, gss_accept_sec_context * and gss_inquire_context
* @return boolean indicating replay detection state * @see #requestReplayDet * @see #isProtReady */ public boolean getReplayDetState() { if (m_curState < READY) return ((m_reqFlags & REPLAY_DET) == REPLAY_DET); return ((m_mechCtxt._getOptions () & REPLAY_DET) == REPLAY_DET); } /** * Returns the state of the sequence detection service for * the context. When issued before context establishment completes * or when the isProtReady method returns false, it returns the * desired state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the sequence_state flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating sequence detection state * @see #requestSequenceDet * @see #isProtReady */ public boolean getSequenceDetState() { if (m_curState < READY) return ((m_reqFlags & SEQUENCE_DET) == SEQUENCE_DET); return ((m_mechCtxt._getOptions () & SEQUENCE_DET) == SEQUENCE_DET); } /** * Returns true if this is an anonymous context. When issued * before context establishment completes or when the * isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the anon_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating anonymity state * @see #requestAnonymity * @see #isProtReady */ public boolean getAnonymityState() { if (m_curState < READY) return ((m_reqFlags & ANON) == ANON); return ((m_mechCtxt._getOptions () & ANON) == ANON); } /** * Indicates if the context is transferable to other processes * through the use of the export method. This call is only valid * on fully established contexts. * *

RFC 2078 *
equivalent to the trans_state flag output parameter in * gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating the transferability of the context * @exception GSSException may be thrown * @see #export */ public boolean isTransferable() throws GSSException { checkState(READY); return ((m_mechCtxt._getOptions () & TRANS) == TRANS); } /** * Indicates if the per message operations can be applied over * the context. Some mechanisms may allow to apply per-message * operations before the context is fully established. This will * also indicate that the get methods will return actual context * state characteristics instead of the desired ones. * *

RFC 2078 *
equivalent to the prot_ready_state flag output * parameter in gss_init_sec_context and * gss_accept_sec_context
* @return boolean indicating if per message operations are available */ public boolean isProtReady() { if (m_mechCtxt == null) return false; return (m_mechCtxt._isProtReady ()); } /** * Returns the confidentiality service state over the context. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the conf_avail flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating confidentiality state * @see #requestConf * @see #isProtReady */ public boolean getConfState() { if (m_curState < READY) return ((m_reqFlags & CONF) == CONF); return ((m_mechCtxt._getOptions () & CONF) == CONF); } /** * Returns the integrity service state over the context. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * state, otherwise it will indicate the actual state over * the established context. * *

RFC 2078 *
equivalent to the integ_avail flag output parameter * in gss_init_sec_context, gss_accept_sec_context and * gss_inquire_context
* @return boolean indicating integrity state * @see #requestInteg * @see #isProtReady */ public boolean getIntegState() { if (m_curState < READY) return ((m_reqFlags & INTG) == INTG); return ((m_mechCtxt._getOptions () & INTG) == INTG); } /** * Returns the context lifetime in seconds. * When issued before context establishment completes or when * the isProtReady method returns false, it returns the desired * lifetime, otherwise it will indicate the actual lifetime over * the established context. * *

RFC 2078 *
equivalent to the lifetime_rec output parameter in * gss_init_sec_context, gss_accept_sec_context, * gss_inquire_context and to gss_context_time call
* @return lifetime in seconds * @see #requestLifetime * @see #isProtReady */ public int getLifetime() { if (m_curState < READY) return (m_reqLifetime); return (m_mechCtxt._getLifetime ()); } /** * Retrieves the name of the context initiator. * This call is valid only after context has been fully established * or when the isProtReady methods returns true. * *

RFC 2078 *
equivalent to the src_name parameter in * gss_accept_sec_context and gss_inquire_context
* @return name of the context initiator * @exception GSSException with possible major codes of CONTEXT_EXPIRED * and FAILURE * @see #isProtReady */ public GSSName getSrcName() throws GSSException { checkState(IN_PROGRESS); return (new GSSName(m_mechCtxt._getSrcName ())); } /** * Retrieves the name of the context target (acceptor). * This call is only valid on fully established contexts * or when the isProtReady methods returns true. * *

RFC 2078 *
equivalent to the targ_name parameter in * gss_inquire_context
* @return name of the context target (acceptor) * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE * @see #isProtReady */ public GSSName getTargName() throws GSSException { checkState(IN_PROGRESS); return (new GSSName(m_mechCtxt._getTargName ())); } /** * Returns the mechanism oid for the context. * *

RFC 2078 *
equivalent to the mech_type parameter in * gss_accept_sec_context and gss_inquire_context
* @return Oid object for the context's mechanism * @exception GSSException may be thrown when the mechanism * oid can't be determined * */ public Oid getMech() throws GSSException { checkState(IN_PROGRESS); return (m_mechCtxt._getMech ()); } /** * Returns the delegated credential object on the acceptor's side. * To check for availability of delegated credentials call * getDelegCredState. This call is only valid on fully established * contexts. * *

RFC 2078 *
equivalent to delegated_cred_handle parameter * in gss_accept_sec_context
* @return delegated credential object for the context * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE * @see #getDelegCredState */ public GSSCredential getDelegCred() throws GSSException { checkState(IN_PROGRESS); return (new GSSCredential(m_mechCtxt._getDelegCred ())); } /** * Returns true if this is the initiator of the context. * This call is only valid after the context creation process * has started. * *

RFC 2078 *
equivalent to locally_initiated output parameter * in gss_inquire_context
* @return true if this is the context initiator * @exception GSSException with possible major codes of * CONTEXT_EXPIRED and FAILURE */ public boolean isInitiator() throws GSSException { checkState(IN_PROGRESS); return (m_mechCtxt._isInitiator ()); } /** * Ensures the object is in the required state. * * @param minimumState the minimum required state. * @exception GSSException is thrown when the state is incorrect. */ private void checkState(int minimumState) throws GSSException { if (m_curState < minimumState) throw new GSSException(GSSException.NO_CONTEXT); //this is just temporary for debugging if (minimumState > PRE_INIT && m_mechCtxt == null) throw new GSSException(GSSException.NO_CONTEXT, -1, "error in checkState"); } /** * Private initializer of context variables */ private void initialize() { m_reqFlags = MUTUAL_AUTH | SEQUENCE_DET | REPLAY_DET; m_myCred = null; m_reqLifetime = INDEFINITE; m_curState = PRE_INIT; m_mechOid = null; m_targName = null; m_chB = null; } /** * Reads the token header as defined in RFC 2078 and * returns the mechanism oid. Currently this requires that * the stream support mark/reset operations. As an * alternative we can strip this header, and pass the information * into the mechanism. */ private Oid getTokenMech(InputStream is) throws GSSException { try { is.mark(100); if (is.read() != 0x60) throw new GSSException(GSSException.DEFECTIVE_TOKEN); //we can skip the token length DERParser.readLength(is); //next we have the full der encoding of the oid Oid res = new Oid(is); is.reset(); return (res); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } } //private flags for the context state private static final int PRE_INIT = 1; private static final int IN_PROGRESS = 2; private static final int READY = 3; private static final int DELETED = 4; //instance variables private GSSCtxtSpi m_mechCtxt; private int m_reqFlags; private GSSCredential m_myCred; private int m_reqLifetime; private int m_curState; private Oid m_mechOid; private GSSName m_targName; private ChannelBinding m_chB; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSCredSpi.java000066400000000000000000000112171356275373100237100ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; /** * This interface is implemented by each mechanism to provide the * functionality of a credential. Each GSSCredential uses provider * objects implementing this interface. A GSSCredential may have * several credential elements underneath it, but each GSSCredSpi * object can represent at most 1 credential element. */ public interface GSSCredSpi { /** * Initialized the credential object. Called after the * object is first instantiated. * * @param desiredName - desired name of the principal * @param initLifetime - desired lifetime for the init * credential; 0 signals use mechanism default * @param acceptLifetime - desired lifetime for the accept * credential; 0 signals use mechanism default * @param usage - the desired usage for this credential * @exception - GSSException may be thrown */ public void init(GSSNameSpi desiredName, int initLifetime, int acceptLifetime, int usage) throws GSSException; /** * Called to invalidate this credential element and release * any system recourses and cryptographic information owned * by the credential. * * @exception GSSException with major codes NO_CRED and FAILURE */ public void dispose() throws GSSException; /** * Returns the principal name for this credential. The name * is in mechanism specific format. * * @return GSSNameSpi representing principal name of this credential * @exception GSSException may be thrown */ public GSSNameSpi getName() throws GSSException; /** * Returns the init lifetime remaining. * * @return the init lifetime remaining in seconds * @exception GSSException may be thrown */ public int getInitLifetime() throws GSSException; /** * Returns the accept lifetime remaining. * * @return the accept lifetime remaining in seconds * @exception GSSException may be thrown */ public int getAcceptLifetime() throws GSSException; /** * Returns the lifetime remaining. This should take * into account the credential usage, and return the * appropriate lifetime. See RFC 2078 for details. * * @return the lifetime remaining in seconds * @exception GSSException may be thrown */ public int getLifetime() throws GSSException; /** * Returns the credential usage. This must be one * GSSCredential.ACCEPT_ONLY, GSSCredential.INITIATE_ONLY, * or GSSCredential.INITIATE_AND_ACCEPT. * * @return the credential usage * @exception GSSException may be thrown */ public int getUsage() throws GSSException; /** * Returns the oid representing the underlying credential * mechanism oid. * * @return the Oid for this credential mechanism * @exception GSSException may be thrown */ public Oid getMechanism(); } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSCredential.java000066400000000000000000000515501356275373100244350ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.util.Vector; import java.util.Enumeration; /** * This class manages GSS-API credentials and their associated * operations. A credential contains all the necessary cryptographic * information to enable the creation of a context on behalf of the * entity that it represents. It may contain multiple distinct mechanism * specific credential elements, each containing mechanism specific * information, and all referring to the same entity. *

* A credential may be used to perform context initiation, acceptance, * or both. *

RFC 2078 *
This class represents the credential management GSS-API calls, * which are: * The gss_inquire_cred and gss_inquire_cred_by_mech calls have been * distributed over several property querying methods each returning * specific GSSCredential information. *
*/ public class GSSCredential { /** * Credential usage flag requesting that it be able to be used * for both context initiation and acceptance. */ public static final int INITIATE_AND_ACCEPT = 0; /** * Credential usage flag requesting that it be able to be used * for context initiation only. */ public static final int INITIATE_ONLY = 1; /** * Credential usage flag requesting that it be able to be used * for context acceptance only. */ public static final int ACCEPT_ONLY = 2; /** * Indefinite lifetime for a credential. It is set to the * largest value for an int in Java. * @see #getRemainingLifetime **/ public static final int INDEFINITE = Integer.MAX_VALUE; /** * Constructor for default credentials. * This will use the default mechanism, default mechanism name, * and an INDEFINITE lifetime. *
RFC 2078 *
equivalent to gss_acquire_cred
* @param usage - the intended usage for this credential; this * must be one of the constants defined in this class. * @exception GSSException with possible major code of FAILURE **/ public GSSCredential(int usage) throws GSSException { add((GSSName)null, INDEFINITE, INDEFINITE, (Oid)null, usage); } /** * Constructor for default mechanism credential. * Uses default mechanism and INDEFINITE lifetime. *
RFC 2078 *
equivalent to gss_acquire_cred
* @param aName - name of the principal for whom this credential * is to be acquired * @param usage - the intended usage for this credential; this * must be one of the constants defined in this class * @exception GSSException with possible major codes of FAILURE and * BAD_NAME **/ public GSSCredential(GSSName aName, int usage) throws GSSException { add(aName, INDEFINITE, INDEFINITE, (Oid)null, usage); } /** * Constructor for a single mechanism credential. * null values can be specified for name and mechanism to obtain * system specific defaults. *
RFC 2078 *
equivalent to gss_acquire_cred
* @param aName - name of the principal for whom this credential * is to be acquired; use null for system specific default * principal * @param lifetime - the duration of this credential * @param mechOid - mechanism over which this credential is to * be acquired * @param usage - the intended usage for this credential; this * must be one of the constants defined in this class * @exception GSSException with possible major codes of FAILURE, * BAD_MECH, and BAD_NAME **/ public GSSCredential(GSSName aName, int lifetime, Oid mechOid, int usage) throws GSSException { add(aName, lifetime, lifetime, mechOid, usage); } /** * Constructor for a credential over a set of mechanisms. * Acquires credentials for each of the mechanisms specified * in mechs array. null value can be used for Name to obtain * system specific default. To determine for which mechanisms * acquiring of the credential was successful use the getMechs * method. Note that this call is equivalent to creating a * single mechanism credential and using addCred to extend the * credential over other mechanisms. *
RFC 2078 *
equivalent to gss_acquire_cred
* @param aName - name of the principal for whom this credential * is to be acquired; use null for system specific default * principal * @param lifetime - the desired duration of this credential * @param mechs - mechanisms over which this credential is to * be acquired * @param usage - the intended usage for this credential; this * must be one of the constants defined in this class * @exception GSSException with possible major codes of FAILURE, * BAD_MECH, and BAD_NAME */ public GSSCredential(GSSName aName, int lifetime, Oid [] mechs, int usage) throws GSSException { for (int i = 0; i < mechs.length; i++) add(aName, lifetime, lifetime, mechs[i], usage); } /** * Package private constructor used to create a credential * object using the supplied mechanism credential element. * * @param GSSCredSpi mechanism specific credential object */ GSSCredential(GSSCredSpi mechCred) { m_mechCreds.addElement(mechCred); } /** * Used to dispose of any sensitive information that the * GSSCredential may be containing. Should be called as soon * as the credential is no longer needed to minimize the time * sensitive information is maintained. *
RFC 2078 *
equivalent to gss_release_cred
* @exception GSSException with possible major code of FAILURE */ public void dispose() throws GSSException { for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) { ((GSSCredSpi)e.nextElement()).dispose(); } m_mechCreds.removeAllElements(); } /** * Retrieves the name of the entity that the credential has been * acquired for. *
RFC 2078 *
equivalent to obtaining the cred_name parameter * from gss_inquire_cred
* @return GSSName for the credential's principal * @exception GSSException with possible major codes of FAILURE, * NO_CRED, DEFECTIVE_CREDENTIAL, CREDENTIAL_EXPIRED */ public GSSName getGSSName() throws GSSException { /* * will return name containing mechanism elements for * all mechs this credential supports */ if (m_mechCreds.size() < 1) throw new GSSException(GSSException.NO_CRED); GSSName aName = new GSSName(); for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements(); ) { aName.addMechName(((GSSCredSpi)e.nextElement()).getName()); } return (aName); } /** * Queries the selected mechanism for the principal name of the * credential. The mechanism must be one of the mechanisms over * which the credential is acquired. *
RFC 2078 *
equivalent to obtaining the cred_name parameter from * gss_inquire_cred_by_mech
* @param mechOID the credential mechanism to be queried * @Return GSSName for the credential's principal; this GSSName * object will be an MN * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, CREDENTIALS_EXPIRED, FAILURE and * BAD_MECH */ public GSSName getGSSName(Oid mechOID) throws GSSException { GSSName aName = new GSSName(); aName.addMechName(getMechCred(mechOID, true).getName()); return (aName); } /** * Obtains the remaining lifetime for a credential. The remaining * lifetime is the minimum lifetime for any of the credential * elements. Return of 0 indicates the credential is already * expired. *
RFC 2078 *
equivalent to lifetime parameter in gss_inquire_cred *
* @return lifetime in seconds * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, FAILURE. */ public int getRemainingLifetime() throws GSSException { int lifetime = GSSCredential.INDEFINITE; GSSCredSpi aCred; if (m_mechCreds.size() < 0) throw new GSSException(GSSException.NO_CRED); /* find the minimum lifetime */ for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) { aCred = (GSSCredSpi)e.nextElement(); if (aCred.getLifetime() < lifetime) lifetime = aCred.getLifetime(); } return (lifetime); } /** * Returns the remaining lifetime in seconds for the credential * to remain capable of initiating security context under the * specified mechanism. Return of 0 indicates that the * credential is already expired. *
RFC 2078 *
equivalent to lifetime_init parameter in * gss_inquire_cred_by_mech
* @param mech Oid for the credential mechanism to be queried * @return the remaining initiation lifetime in seconds * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, FAILURE and BAD_MECH */ public int getRemainingInitLifetime(Oid mech) throws GSSException { GSSCredSpi aCred = getMechCred(mech, true); return (aCred.getInitLifetime()); } /** * Returns the remaining lifetime in seconds for the credential * to remain capable of accepting security context under the * specified mechanism. Return of 0 indicates that the * credential is already expired. *
RFC 2078 *
equivalent to lifetime_accept parameter in * gss_inquire_cred_by_mech
* @param mech Oid for the credential mechanism to be queried * @return the remaining acceptance lifetime in seconds * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, FAILURE and BAD_MECH */ public int getRemainingAcceptLifetime(Oid mech) throws GSSException { GSSCredSpi aCred = getMechCred(mech, true); return (aCred.getAcceptLifetime()); } /** * Retrieve the credential usage flag, which is one of * INITIATE_ONLY, ACCEPT_ONLY, INITIATE_AND_ACCEPT. *
RFC 2078 *
equivalent to usage parameter in gss_inquire_cred
* @return credential usage which will be only of * INITIATE_ONLY, ACCEPT_ONLY, or INITIATE_AND_ACCEPT * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, CREDENTIALS_EXPIRED, FAILURE. */ public int getUsage() throws GSSException { boolean init = false, accept = false; GSSCredSpi aCred; if (m_mechCreds.size() < 0) throw new GSSException(GSSException.NO_CRED); /* find the usage for the credential */ for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) { aCred = (GSSCredSpi)e.nextElement(); if (aCred.getUsage() == GSSCredential.INITIATE_AND_ACCEPT) return (GSSCredential.INITIATE_AND_ACCEPT); else if (aCred.getUsage() == GSSCredential.INITIATE_ONLY) init = true; else if (aCred.getUsage() == GSSCredential.ACCEPT_ONLY) accept = true; //if both are set, then we are done.... if (init && accept) return (GSSCredential.INITIATE_AND_ACCEPT); } //can only be a single use credential if (init) return (GSSCredential.INITIATE_ONLY); return (GSSCredential.ACCEPT_ONLY); } /** * Retrieve the credential usage flag, which is one of * INITIATE_ONLY, ACCEPT_ONLY, INITIATE_AND_ACCEPT, for a * specific credential mechanism. *
RFC 2078 *
equivalent to usage parameter in * gss_inquire_cred_by_mech
* @param oid for the credential mechanism to query * @return credential usage which will be only of * INITIATE_ONLY, ACCEPT_ONLY, or INITIATE_AND_ACCEPT * @exception GSSException with possible major codes of NO_CRED, * DEFECTIVE_CREDENTIAL, CREDENTIALS_EXPIRED, FAILURE. */ public int getUsage(Oid mechOID) throws GSSException { GSSCredSpi aCred = getMechCred(mechOID, true); return (aCred.getUsage()); } /** * Returns the mechanism oids over which the credential has been * acquired. *
RFC 2078 *
equivalent to mech_set parameter of gss_inquire_cred
* @return the array of mechanism oid's over which this credential * has been acquired * @exception GSSException with possible major codes of FAILURE, * NO_CRED, DEFECTIVE_CREDENTIAL, CREDENTIAL_EXPIRED */ public Oid [] getMechs() throws GSSException { Oid [] oids = new Oid[m_mechCreds.size()]; int i = 0; if (m_mechCreds.size() < 1) throw new GSSException(GSSException.NO_CRED); for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) oids[i++] = ((GSSCredSpi)e.nextElement()).getMechanism(); return (oids); } /** * This method enables the construction of credentials one * mechanism at a time. A single mechanism credential will * be added as specified by the mech parameter. This is * equivalent to using the constructor for multiple mechanism * but gives finer control and feedback. *
RFC 2078 *
equivalent to gss_add_cred
* to obtain a new credential as in gss_add_cred, first call * clone and then addCred
* @param aName - name of the principal for whom this credential * is to be acquired; use null for system specific default * principal * @param initLifetime - the desired duration of this credential * initiation lifetime; value in seconds * @param acceptLifetime - the desired duration of this credential * accept lifetime; value in seconds * @param mechs - mechanism over which this credential is to * be acquired * @param usage - the intended usage for this credential; this * must be one of the constants defined in this class * @exception GSSException with possible major codes of * DUPLICATE_ELEMENT, BAD_MECH, BAD_NAME, BAD_NAME, NO_CRED, * or FAILURE. */ public synchronized void add(GSSName aName, int initLifetime, int acceptLifetime, Oid mech, int usage) throws GSSException { if (mech == null) mech = GSSManager.getDefaultMech(); //check if this cred already exists if (getMechCred(mech, false) != null) throw new GSSException(GSSException.DUPLICATE_ELEMENT); //ok, go ahead create new one....... GSSCredSpi newCred = GSSManager.getCredInstance(mech); newCred.init(aName.canonicalizeInPlace(mech), initLifetime, acceptLifetime, usage); //mechanism credential created successfully, so add m_mechCreds.addElement(newCred); } /** * Tests if this GSSCredential refers to the same entity as the * supplied object. The two GSSCredentials must be acquired over * the same mechanisms. * @return true if the two GSSCredentials refer to the same * entity; false otherwise. * @override java.lang.Object#equals */ public boolean equals(Object another) { if ( !(another instanceof GSSCredential)) return (false); GSSCredential aCred = (GSSCredential)another; if (aCred.m_mechCreds.size() != m_mechCreds.size()) return (false); GSSCredSpi intCred, anotherIntCred; try { for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) { intCred = (GSSCredSpi)e.nextElement(); anotherIntCred = aCred.getMechCred( intCred.getMechanism(), false); if (anotherIntCred == null) return (false); //ask internal creds to compare themselves if (intCred.equals(anotherIntCred) == false) return (false); } } catch (GSSException e) { return (false); } //all internal creds are equal, so we are equal too... return (true); } /** * Debugging aid. Returns string with information about * this credential object. */ public String toString() { StringBuffer sb = new StringBuffer(150); sb.append(super.toString()); sb.append("\nOver mechs:\t"); try { Oid [] mechs = getMechs(); for (int i = 0; i < mechs.length; i++) sb.append(mechs[i].toString() + " "); sb.append("\nFor principal:\t" + getGSSName().toString()); sb.append("\nUsage:\t" + getUsage()); if (getUsage() == ACCEPT_ONLY) sb.append(" (ACCEPT_ONLY)"); else if (getUsage() == INITIATE_ONLY) sb.append(" (INITIATE_ONLY)"); else sb.append(" (INITIATE and ACCEPT)"); sb.append("\nRemaining Lifetime:\t" + getRemainingLifetime()); } catch (GSSException e) { sb.append("\n***ERROR getting info:\t" + e.toString()); } return (sb.toString()); } /** * Returns the specified mechanism's credential-element. * * @param mechOid - the oid for mechanism to retrieve * @param throwExcep - boolean indicating if the function is * to throw exception or return null when element is not * found. * @return mechanism credential object * @exception GSSException of invalid mechanism */ GSSCredSpi getMechCred(Oid mechOid, boolean throwExcep) throws GSSException { for (Enumeration e = m_mechCreds.elements(); e.hasMoreElements();) { GSSCredSpi aCred = (GSSCredSpi)e.nextElement(); if (aCred.getMechanism().equals(mechOid)) return (aCred); } /* not found */ if (throwExcep == true) throw new GSSException(GSSException.BAD_MECH); else return (null); } /* private instance variables */ Vector m_mechCreds = new Vector(3, 3); } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSCtxtSpi.m4000066400000000000000000000261451356275373100233620ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.OutputStream; /** * An object of this class implements the functionality of a GSSContext * for a specific mechanism. * A GSSCtxtSpi object can be thought of having 3 states: * -before initialization * -during initialization with its peer * -after it is established *

* The context options can only be requested in state 1. In state 3, * the per message operations are available to the callers. The get * methods for the context options will return the requested options * while in state 1 and 2, and the established values in state 3. * Some mechanisms may allow the access to the per-message operations * and the context flags before the context is fully established. The * isProtReady method is used to indicate that these services are * available. */ public interface GSSCtxtSpi { /** * Sets the mechanism options to be used during context * creation on the initiator's side. This is used to * initialize a new GSSCtxtSpi object. * * @param myCred the principal's credentials; may be null * @param targName the context peer * @param desLifetime the requested lifetime; 0 indicates use * default * @param mechOptions ORed GSSContext options * @exception GSSException may be thrown */ public void _setInitOptions (GSSCredSpi myCred, GSSNameSpi targName, int desLifetime, int ctxtOptions) throws GSSException; /** * Sets the mechanism options to be used during context * creation on the acceptor's side. This is used to initialize * a new GSSCtxtSpi object. * * @param myCred the principal's credentials; may be null * @exception GSSException may be thrown */ public void _setAcceptOptions (GSSCredSpi myCred) throws GSSException; /** * Sets the channel bindings to be used during context * establishment. This method is only called if the application * wishes to use channel bindings with this context. * * @param chb channel bindings to be set * @exception GSSException may be thrown */ public void _setChannelBinding (ChannelBinding chb) throws GSSException; /** * Retrieves the mechanism options. * * @return int GSSContext options ORed together */ public int _getOptions (); /** * Inquire the remaining lifetime. * * @return the lifetime in seconds. May return reserved * value GSSContext.INDEFINITE for an indefinite lifetime. */ public int _getLifetime (); /** * Returns the mechanism oid. * * @return the Oid for this context */ public Oid _getMech (); /** * Returns the context initiator name. * * @return initiator name * @exception GSSException may be thrown */ public GSSNameSpi _getSrcName () throws GSSException; /** * Returns the context acceptor name. * * @return context acceptor(target) name * @exception GSSException may be thrown */ public GSSNameSpi _getTargName () throws GSSException; /** * Returns the delegated credential for the context. This * is an optional feature of contexts which not all * mechanisms will support. A context can be requested to * support credential delegation by using the CRED_DELEG. * This is only valid on the acceptor side of the context. * @return GSSCredSpi object for the delegated credential * @exception GSSException may be thrown * @see GSSContext#getDelegCredState */ public GSSCredSpi _getDelegCred () throws GSSException; /** * Tests if this is the initiator side of the context. * * @return boolean indicating if this is initiator (true) * or target (false) */ public boolean _isInitiator (); /** * Tests if the context can be used for per-message service. * Context may allow the calls to the per-message service * functions before being fully established. * * @return boolean indicating if per-message methods can * be called. */ public boolean _isProtReady (); /** * Initiator context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. On the * first call it will be ignored. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException may be thrown */ public int _initSecCtxt (InputStream is, OutputStream os) throws GSSException; /** * Acceptor's context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException may be thrown */ public int _acceptSecCtxt (InputStream is, OutputStream os) throws GSSException; /** * Queries the context for largest data size to accomodate * the specified protection and for the token to remain less then * maxTokSize. * * @param qop the quality of protection that the context will be * asked to provide. * @param confReq a flag indicating whether confidentiality will be * requested or not * @param outputSize the maximum size of the output token * @return the maximum size for the input message that can be * provided to the wrap() method in order to guarantee that these * requirements are met. * @exception GSSException may be thrown */ public int _getWrapSizeLimit (int qop, boolean confReq, int maxTokSize) throws GSSException; /** * Provides per-message token encapsulation. * * @param is the user-provided message to be protected * @param os the token to be sent to the peer. It includes * the message from is with the requested protection. * @param msgPro on input it contains the requested qop and * confidentiality state, on output, the applied values * @exception GSSException may be thrown * @see MessageInfo * @see unwrap */ public void _wrap (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Retrieves the message token previously encapsulated in the wrap * call. * * @param is the token from the peer * @param os unprotected message data * @param msgProp will contain the applied qop and confidentiality * of the input token and any informatory status values * @exception GSSException may be thrown * @see MessageInfo * @see wrap */ public void _unwrap (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Applies per-message integrity services. * * @param is the user-provided message * @param os the token to be sent to the peer along with the * message token. The message token is not encapsulated. * @param msgProp on input the desired QOP and output the applied QOP * @exception GSSException */ public void _getMIC (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException; /** * Checks the integrity of the supplied tokens. * This token was previously generated by getMIC. * * @param is token generated by getMIC * @param msgStr the message to check integrity for * @param msgProp will contain the applied QOP and confidentiality * states of the token as well as any informatory status codes * @exception GSSException may be thrown */ public void _verifyMIC (InputStream is, InputStream msgStr, MessageProp mProp) throws GSSException; /** * Produces a token representing this context. After this call * the context will no longer be usable until an import is * performed on the returned token. * * @return exported context token * @exception GSSException may be thrown */ public byte []_export () throws GSSException; /** * Imports a previously exported context. This will be called * for newly created objects. * * @param is the previously exported token * @exception GSSException may be thrown * @see export */ public void _importSecCtxt (byte []token) throws GSSException; /** * Releases context resources and terminates the * context between 2 peer. * * @exception GSSException may be thrown */ public void _dispose () throws GSSException; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSException.java000066400000000000000000000275441356275373100243270ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; /** * This exception is thrown whenever a fatal GSS-API error occurs * including mechanism specific errors. It contains * both the major and minor JGSS status codes. The mechanism * implementers are responsible for setting appropriate minor status * codes when throwing this exception. Methods are included to retrieve * the error string representation for both major and minor codes. *

RFC 2078 *
GSS-API major status codes are divided into fatal and * informatory status codes. In JGSS, fatal codes are represented using * exceptions of this class, and informatory codes are returned through * instances of the MesssageProp class used in the GSSContext methods. * This class also provides the functionality of gss_display_status.
* @see MessageProp * @see GSSContext#unwrap * @see GSSContext#verifyMIC */ public class GSSException extends Exception { /** * Channel bindings mismatch error. */ public static final int BAD_BINDINGS = 1; //start with 1 /** * Unsupported mechanism requested error. */ public static final int BAD_MECH = 2; /** * Invalid name provided error. */ public static final int BAD_NAME = 3; /** * Name of unsupported type provided error. */ public static final int BAD_NAMETYPE = 4; /** * Invalid status code error - this is the default status value. */ public static final int BAD_STATUS = 5; /** * Token had invalid integrity check error. */ public static final int BAD_MIC = 6; /** * Specified security context expired error. */ public static final int CONTEXT_EXPIRED = 7; /** * Expired credentials detected error. */ public static final int CREDENTIALS_EXPIRED = 8; /** * Defective credential error. */ public static final int DEFECTIVE_CREDENTIAL = 9; /** * Defective token error. */ public static final int DEFECTIVE_TOKEN = 10; /** * General failure, unspecified at GSS-API level. */ public static final int FAILURE = 11; /** * Invalid security context error. */ public static final int NO_CONTEXT = 12; /** * Invalid credentials error. */ public static final int NO_CRED = 13; /** * Unsupported QOP value error. */ public static final int BAD_QOP = 14; /** * Operation unauthorized error. */ public static final int UNAUTHORIZED = 15; /** * Operation unavailable error. */ public static final int UNAVAILABLE = 16; /** * Duplicate credential element requested error. */ public static final int DUPLICATE_ELEMENT = 17; /** * Name contains multi-mechanism elements error. */ public static final int NAME_NOT_MN = 18; /** * The token was a duplicate of an earlier token. * This is a fatal error code that may occur during * context establishment. It is not used to indicate * supplementary status values. The MessageProp object is * used for that purpose. */ public static final int DUPLICATE_TOKEN = 19; /** * The token's validity period has expired. This is a * fatal error code that may occur during context establishment. * It is not used to indicate supplementary status values. * The MessageProp object is used for that purpose. */ public static final int OLD_TOKEN = 20; /** * A later token has already been processed. This is a * fatal error code that may occur during context establishment. * It is not used to indicate supplementary status values. * The MessageProp object is used for that purpose. */ public static final int UNSEQ_TOKEN = 21; /** * An expected per-message token was not received. This is a * fatal error code that may occur during context establishment. * It is not used to indicate supplementary status values. * The MessageProp object is used for that purpose. */ public static final int GAP_TOKEN = 22; private static String[] messages = { "channel binding mismatch", // BAD_BINDINGS "unsupported mechanism requested", // BAD_MECH "invalid name provided", // BAD_NAME "name of unsupported type provided", //BAD_NAMETYPE "invalid input status selector", // BAD_STATUS "token had invalid integrity check", // BAD_SIG "specified security context expired", // CONTEXT_EXPIRED "expired credentials detected", // CREDENTIALS_EXPIRED "defective credential detected", // DEFECTIVE_CREDENTIAL "defective token detected", // DEFECTIVE_TOKEN "failure, unspecified at GSS-API level", // FAILURE "security context init/accept not yet called or context deleted", // NO_CONTEXT "no valid credentials provided", // NO_CRED "unsupported QOP value", // BAD_QOP "operation unauthorized", // UNAUTHORIZED "operation unavailable", // UNAVAILABLE "duplicate credential element requested", //DUPLICATE_ELEMENT "name contains multi-mechanism elements", // NAME_NOT_MN "the token was a duplicate of an earlier token", //DUPLICATE_TOKEN "the token's validity period has expired", //OLD_TOKEN "a later token has already been processed", //UNSEQ_TOKEN "an expected per-message token was not received", //GAP_TOKEN }; private int m_major; // the major code for this exception private int m_minor = 0; // the minor code for this exception private String m_minorMessage = null; //text string for minor code /** * Construct a GSSException object with a specified major code. * * @param majorCode the fatal error code causing this exception. * This value should be one of the ones defined in this * class. Invalid error codes get mapped to BAD_STATUS value. */ public GSSException (int majorCode) { if (validateMajor(majorCode)) m_major = majorCode; else m_major = BAD_STATUS; } /** * Construct a GSSException object with a specified major and * minor codes and minor explanation string. * * @param majorCode the fatal error code causing this exception. * This value should be one of the ones defined in this class. * Invalid error codes get mapped to BAD_STATUS value. * @param minorCode the mechanism specific error code. * @param minorString explanation of the minorCode. */ public GSSException (int majorCode, int minorCode, String minorString) { if (validateMajor(majorCode)) m_major = majorCode; else m_major = BAD_STATUS; m_minor = minorCode; m_minorMessage = minorString; } /** * Returns the major code representing the error that caused this * exception to be thrown. * *
RFC 2078 *
equivalent to major code being returned from function *
* @return int the fatal error code causing this exception * @see #getMajorString */ public int getMajor() { return m_major; } /** * Returns the mechanism error that caused this exception. The * minor code is set by the underlying mechanism. Value of 0 * indicates that mechanism error code is not set. * *
RFC 2078 *
equivalent to minor status codes in GSS-API functions *
* * @return int the mechanism error code; 0 indicates that it has * not been set. * @see #setMinor * @see #getMinorString */ public int getMinor(){ return m_minor; } /** * Returns a string explaining the major code in this exception. * *
RFC 2078 *
equivalent to gss_display_status for the major error * code.
* @return String explanation string for the major error code * @see #getMajor * @see #toString */ public String getMajorString() { return messages[m_major - 1]; } /** * Returns a string explaining the mechanism specific error code. * Can be used with the getMajorString call to provide mechanism * specific error details. If the minor status code is 0, then * no other error details will be available. * *
RFC 2078 *
equivalent to gss_display_status for the minor code. *
* @return String a textual explanation of mechanism error code * @see #getMinor * @see #getMajorString * @see #toString */ public String getMinorString() { if (m_minorMessage == null) m_minorMessage = ""; return m_minorMessage; } /** * Used by the exception thrower to set the mechanism error code * and its string explanation. This is used by mechanism * providers to indicate error details. * * @param minorCode the mechanism specific error code * @param message textual explanation of the mechanism error code */ public void setMinor(int minorCode, String message) { m_minor = minorCode; m_minorMessage = message; } /** * Returns string representing both the major and minor status * codes. * * @return a String with the error descriptions * @overrides Object#toString */ public String toString() { if (m_minor == 0) return (getMajorString()); return (getMajorString() + "(" + getMinorString() + ")"); } /** * Returns string representing both the major and minor status * codes. * * @return a String with the error descriptions * @overrides Throwable#geMessage */ public String getMessage() { return (toString()); } /* * Validates the major code in the proper range. */ private boolean validateMajor(int major) { if (m_major > 0 && m_major <= messages.length) return (true); return (false); } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSManager.java000066400000000000000000000516221356275373100237350ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.*; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; import java.util.Enumeration; import java.util.ResourceBundle; /** * This class implements functionality common to the entire GSS-API * package. This includes the management of the gss mechanisms * and their providers. *

RFC 2078 *
A side from JGSS provider management, this class * implements the equivalent of the following GSS-API routines: *
*/ public class GSSManager { static { initialize(); } private static void initialize() { int i = 1; try { ResourceBundle props = ResourceBundle.getBundle( "com.sun.gssapi.mechs"); while (true) { String name = props.getString("gss.provider." + i++); if (name == null) { break; } else { Class cl = Class.forName(name); Object instance = cl.newInstance(); if (instance instanceof Provider) { Security.addProvider((Provider)instance); } else { // This is not a valid Provider } } } } catch (Exception e) { // no-op } } /** * Indicates which mechanisms are configured within JGSS. *

RFC 2078 *
equivalent to gss_indicate_mechs
* * @return array of Oids indicating available mechanisms; * null when no mechanism are available */ public static Oid[] getMechs() { /* * Go through all the providers and retrieve jgss ones * note we skip the ProviderTable, because we want all * jgss providers not just ones loaded. */ Provider [] p = java.security.Security.getProviders(); Vector aV = new Vector(5, 3); for (int i = 0; i < p.length; i++) { String []mechs = MechInfo.getMechsForProvider(p[i]); if (mechs == null) continue; for (int j=0; j < mechs.length; j++) { try { addUniqueOid(aV, new Oid(mechs[j])); } catch (GSSException e) {} } } if (aV.size() == 0) return (null); Oid []mechs = new Oid[aV.size()]; aV.copyInto(mechs); return (mechs); } /** * Returns name types (Oids) supported by the selected mechanism. * Note that in cases where several providers implement the same * mechanism, only the first provider implementing the mechanism * is queried. *

RFC 2078 *
equivalent to gss_inquire_names_for_mech
* * @param mech the Oid for mechanism to be queried * @return names array of Oids indicating names supported by the * requested mechanism; or null if the mech is not supported * @exception GSSException with major code of BAD_MECH will be thrown * for invalid mechanism oids */ public static Oid[] getNamesForMech(Oid mech) throws GSSException { MechInfo aMech = getMechInfo(mech, false); return (aMech.getNames()); } /** * Returns all the mechanisms that support the specific name type. *

*

RFC 2078 *
equivalent to gss_inquire_mechs_for_name
* * @param nameType the Oid of the name type to be queried * @return mechs an array of mechanism Oids supporting the * requested name type; null if no mechanism supports the * requested name type */ public static Oid[] getMechsForName(Oid nameType) { Provider []p = java.security.Security.getProviders(); Vector v = new Vector(5,3); for (int i = 0; i < p.length; i++) { MechInfo [] mechs = MechInfo.getInfoForAllMechs(p[i]); if (mechs == null) continue; for (int j = 0; j < mechs.length; j++) { if (mechs[j].supportsName(nameType)) addUniqueOid(v, mechs[j].getOid()); } } if (v.size() == 0) return (null); Oid [] oids = new Oid[v.size()]; v.copyInto(oids); return (oids); } /** * Determines the default mechanism. The default mechanism is * determined through the setting in the security properties file * when the provider is installed or through dynamic configuration * of the providers.. The default mech is the first mechanism in * the first jgss provider. * @return the Oid for the default mechanism * @exception GSSException with major code set to BAD_MECH if * no jgss providers exist. */ public static Oid getDefaultMech() throws GSSException { if (m_defaultMech != null) return (m_defaultMech.getOid()); Provider []p = java.security.Security.getProviders(); //check each provider for (int i = 0; i < p.length; i++) { String []mechs = MechInfo.getMechsForProvider(p[i]); if (mechs == null) continue; m_defaultMech = new MechInfo(p[i], mechs[0]); return (m_defaultMech.getOid()); } throw new GSSException(GSSException.BAD_MECH); } /** * Adds only unique values to the specified vector. * @param v - vector to add to * @param oid - the oid to add */ private static void addUniqueOid(Vector v, Oid anOid) { for (Enumeration e = v.elements(); e.hasMoreElements();) { if ( ((Oid)e.nextElement()).equals(anOid)) return; } v.addElement(anOid); } /** * Returns a provider specific implementation of the credential * object. */ static GSSCredSpi getCredInstance(Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech.getCredInstance()); } /** * Returns a provider specific implementation of the name * object. */ static GSSNameSpi getNameInstance(Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech.getNameInstance()); } /** * Returns a provider specific implementation of the C018FE95 * object. */ static C018FE95 _M4092FBA (Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech._M4092FBA ()); } /** * Obtains the MechInfo object for the specified mechanism. * * @param installMech this boolean indicates if the mechanism * should be loaded if it isn't already */ private static synchronized MechInfo getMechInfo(Oid oid, boolean installMech) throws GSSException { //look in the hash table first MechInfo aMech = MechTable.getMechInfo(oid); if (aMech != null) { if (installMech) MechTable.putMechInfo(aMech); return (aMech); } //need to search all providers Provider [] p = java.security.Security.getProviders(); String mechString = oid.toString(); for (int i=0; i < p.length; i++) { if (MechInfo.implementsMech(p[i], mechString)) { try { aMech = new MechInfo(p[i], mechString); if (installMech) MechTable.putMechInfo(aMech); return (aMech); } catch (GSSException e) { //skip over this provider, there might be //other good ones continue; } } } //this mechanism is not installed on the system throw new GSSException(GSSException.BAD_MECH); } /** * Debug method. */ private static void showProviderDetails() { Provider [] p = java.security.Security.getProviders(); MechInfo [] mechs; boolean foundGSSProv = false; for (int i = 0; i < p.length; i++ ) { mechs = MechInfo.getInfoForAllMechs(p[i]); if (mechs == null) continue; foundGSSProv = true; } } //private class variable - default mechanism oid private static MechInfo m_defaultMech; } // end of Class GSSManager /** * Class to store mechanism information extracted from the providers. * It contains all the provider parsing code. */ class MechInfo { //hides the default constructor private MechInfo() { } /** * Constructor to populate the object with information from * the provider. * @param p - the provider to be queried for mechanism info * @param oid - the mechanism which the provider is to be * queried for * @exception GSSException with major status of BAD_MECH when * this provider does not implement the specified mechanism */ MechInfo(Provider p, String oid) throws GSSException { String aStr; m_oid = new Oid(oid); _V510CA83 = p; updateOidAlias(p, oid); if ((aStr = _M73F1AC8 (p, oid, "_K872D1AC")) != null) { StringTokenizer st = new StringTokenizer(aStr, ":"); m_names = new Oid[st.countTokens()]; int i = 0; while (st.hasMoreTokens()) { m_names[i] = new Oid(st.nextToken()); i++; } } else throw new GSSException(GSSException.BAD_MECH); _V2395ABD = _M73F1AC8 (p, oid, "_K532D1BD"); _V108CA91 = _M73F1AC8 (p, oid, "_K1000A49"); _V901D6C2 = _M73F1AC8 (p, oid, "_K2102CC5"); if (_V2395ABD == null || _V108CA91 == null || _V901D6C2 == null) throw new GSSException(GSSException.BAD_MECH); } /** * Checks if this mechanism supports the supplied name oid. * @param nameOid - the oid for name to be checked * in dot notation * @return true if name type is supported, false otherwise */ boolean supportsName(Oid nameOid) { for (int i = 0; i < m_names.length; i++) { if (m_names[i].equals(nameOid)) return (true); } return (false); } /** * Returns the names supported by this mech. */ Oid[] getNames() { return (m_names); } /** * Returns the oid for this mechanism. */ Oid getOid() { return (m_oid); } /** * Returns an instance of the class implementing the GSSCredSpi * interface for this mechanism. */ GSSCredSpi getCredInstance() throws GSSException { try { if (_V29ED8BF == null) { //create the class object _V29ED8BF = Class.forName(_V901D6C2); } return ((GSSCredSpi)_V29ED8BF.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns an instance of the class implementing the C018FE95 * interface for this mechanism. */ C018FE95 _M4092FBA () throws GSSException { try { if (_V30FDA16 == null) { //create the class object _V30FDA16 = Class.forName(_V108CA91); } return ((C018FE95)_V30FDA16.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns an instance of the class implementing the JGSSNameSpi * interface for this mechanism. */ GSSNameSpi getNameInstance() throws GSSException { try { if (_V80013BE == null) { //create the class object _V29ED8BF = Class.forName(_V2395ABD); } return ((GSSNameSpi)_V29ED8BF.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns the provider for this mechanism. * * @return p - provider for this mechanism. */ Provider getProvider() { return (_V510CA83); } /** * Returns a provider value for the given key. * Both alias and oid is attempted to get the value. * @param provider to query * @param mechanism oid to be queried * @param key for the value to retrieve (JGSS.Mech. is prepended to it) * @return the value from the provider for the give mechanism and key */ private static String _M73F1AC8 (Provider p, String _V0095DCA, String key) { String aStr; if ((aStr = p.getProperty("JGSS.Mech." + _V0095DCA + "." + key)) != null) { return (aStr); } if ((aStr = oidStrToAlias(_V0095DCA)) == null) return null; return (p.getProperty("JGSS.Mech." + aStr + "." + key)); } /** * Returns the alias name for the passed in mechanism oid. * @param mechanism oid in dot notation * @return alias name for the oid; null if not found */ private static String oidStrToAlias(String _V0095DCA) { return M_oidAlias.getProperty(_V0095DCA); } /** * Returns the oid string for the given alias. * @return oid str in dot notation for the supplied alias name; * null if it does net exist */ private static String aliasToOidStr(String mechAlias) { return M_oidAlias.getProperty(mechAlias); } /** * Updates the oid <--> alias mapping. * If the mapping already exists, it is *not* replaced. */ private static synchronized void updateOidAlias(Provider p, String _V0095DCA) { //check if mapping already exists if (M_oidAlias.getProperty(_V0095DCA) != null) return; String aStr = p.getProperty("JGSS.Mech." + _V0095DCA + ".Alias"); if (aStr != null) { M_oidAlias.put(_V0095DCA, aStr); M_oidAlias.put(aStr, _V0095DCA); } } /** * Queries if this is a JGSS provider implementing the * specified oid. */ static boolean implementsMech(Provider p, String oid) { String [] mechs = getMechsForProvider(p); if (mechs == null) return (false); for (int i = 0; i < mechs.length; i++) { if (mechs[i].equals(oid)) return (true); } return (false); } /** * Creates MechInfo objects for all the mechs this * provider supports. */ static MechInfo[] getInfoForAllMechs(Provider p) { String mechsStr = p.getProperty("JGSS.Mechs"); //does this provider even support JGSS ? if (mechsStr == null) return (null); StringTokenizer st = new StringTokenizer(mechsStr, ":"); MechInfo[] mInfo = new MechInfo[st.countTokens()]; for (int i = 0; i < mInfo.length; i++) { try { mInfo[i] = new MechInfo(p, st.nextToken()); } catch (GSSException e) { } } return (mInfo); } /** * Queries the provider for all the mechanisms it offers * @return mechs - the mechanism oids this provider offers */ static String[] getMechsForProvider(Provider p) { String aStr; if ((aStr = p.getProperty("JGSS.Mechs")) != null ) { //get the supported mechs - there may be more then one StringTokenizer st = new StringTokenizer(aStr,":"); String[] res = new String[st.countTokens()]; for (int i = 0; i < res.length; i++) res[i] = st.nextToken(); return (res); } return (null); } /** * Returns string with mechanism information. */ public String toString() { StringBuffer aBuf = new StringBuffer(100); aBuf.append("Mechanism oid:\t").append(m_oid); aBuf.append("\nMechanism alias:\t").append( oidStrToAlias(m_oid.toString())); aBuf.append("\nMy provider: "); if (_V510CA83 == null) aBuf.append("null"); else aBuf.append(_V510CA83.getInfo()); aBuf.append("\nSupported Names:\t"); for(int i = 0; i < m_names.length; i++) aBuf.append(m_names[i].toString()).append(" "); aBuf.append("\nName Class:\t").append(_V2395ABD); aBuf.append("\nCred Class:\t").append(_V901D6C2); aBuf.append("\nCtxt Class:\t").append(_V108CA91); return (aBuf.toString()); } //instance variables private Oid m_oid; //oid for this mech private Oid []m_names; //oids for names supported by the mech private String _V2395ABD; //name of the name class private String _V108CA91; //name of the ctxt class private String _V901D6C2; //name of the credential class private Provider _V510CA83; //provider for this mech private Class _V80013BE; //class implementing name private Class _V29ED8BF; //class implementing cred private Class _V30FDA16; //class implementing ctxt //class variables private static Properties M_oidAlias; //oid <-> alias mapping static { M_oidAlias = new Properties(); } } /* * Package private class that stores Oid -> MechInfo mapping for jgss * Only loaded mechanisms are in this table. */ class MechTable { /** * Hide constructor */ private MechTable() { } /** * Returns mechanism info for the specified oid. null if * it does not exit. */ static MechInfo getMechInfo(Oid oid) { return ((MechInfo)M_table.get(oid)); } /** * Puts the mapping for a mechanism into the table. * If the mechanism is already in the table, it is not * updated. Returns boolean indicating if the mechanism * information was stored. */ static boolean putMechInfo(MechInfo aMech) { if (M_table.containsKey(aMech.getOid())) return (false); M_table.put(aMech.getOid(), aMech); return (true); } //private table storing the mapping private static Hashtable M_table; static { M_table = new Hashtable(13); } } //end of Class MechTable yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSManager.m4000066400000000000000000000517671356275373100233460ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.*; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; import java.util.Vector; import java.util.Enumeration; import java.util.ResourceBundle; /** * This class implements functionality common to the entire GSS-API * package. This includes the management of the gss mechanisms * and their providers. *

RFC 2078 *
A side from JGSS provider management, this class * implements the equivalent of the following GSS-API routines: *
*/ public class GSSManager { static { initialize(); } private static void initialize() { int i = 1; try { ResourceBundle props = ResourceBundle.getBundle( "com.sun.gssapi.mechs"); while (true) { String name = props.getString("gss.provider." + i++); if (name == null) { break; } else { Class cl = Class.forName(name); Object instance = cl.newInstance(); if (instance instanceof Provider) { Security.addProvider((Provider)instance); } else { // This is not a valid Provider } } } } catch (Exception e) { // no-op } } /** * Indicates which mechanisms are configured within JGSS. *

RFC 2078 *
equivalent to gss_indicate_mechs
* * @return array of Oids indicating available mechanisms; * null when no mechanism are available */ public static Oid[] getMechs() { /* * Go through all the providers and retrieve jgss ones * note we skip the ProviderTable, because we want all * jgss providers not just ones loaded. */ Provider [] p = java.security.Security.getProviders(); Vector aV = new Vector(5, 3); for (int i = 0; i < p.length; i++) { String []mechs = MechInfo.getMechsForProvider(p[i]); if (mechs == null) continue; for (int j=0; j < mechs.length; j++) { try { addUniqueOid(aV, new Oid(mechs[j])); } catch (GSSException e) {} } } if (aV.size() == 0) return (null); Oid []mechs = new Oid[aV.size()]; aV.copyInto(mechs); return (mechs); } /** * Returns name types (Oids) supported by the selected mechanism. * Note that in cases where several providers implement the same * mechanism, only the first provider implementing the mechanism * is queried. *

RFC 2078 *
equivalent to gss_inquire_names_for_mech
* * @param mech the Oid for mechanism to be queried * @return names array of Oids indicating names supported by the * requested mechanism; or null if the mech is not supported * @exception GSSException with major code of BAD_MECH will be thrown * for invalid mechanism oids */ public static Oid[] getNamesForMech(Oid mech) throws GSSException { MechInfo aMech = getMechInfo(mech, false); return (aMech.getNames()); } /** * Returns all the mechanisms that support the specific name type. *

*

RFC 2078 *
equivalent to gss_inquire_mechs_for_name
* * @param nameType the Oid of the name type to be queried * @return mechs an array of mechanism Oids supporting the * requested name type; null if no mechanism supports the * requested name type */ public static Oid[] getMechsForName(Oid nameType) { Provider []p = java.security.Security.getProviders(); Vector v = new Vector(5,3); for (int i = 0; i < p.length; i++) { MechInfo [] mechs = MechInfo.getInfoForAllMechs(p[i]); if (mechs == null) continue; for (int j = 0; j < mechs.length; j++) { if (mechs[j].supportsName(nameType)) addUniqueOid(v, mechs[j].getOid()); } } if (v.size() == 0) return (null); Oid [] oids = new Oid[v.size()]; v.copyInto(oids); return (oids); } /** * Determines the default mechanism. The default mechanism is * determined through the setting in the security properties file * when the provider is installed or through dynamic configuration * of the providers.. The default mech is the first mechanism in * the first jgss provider. * @return the Oid for the default mechanism * @exception GSSException with major code set to BAD_MECH if * no jgss providers exist. */ public static Oid getDefaultMech() throws GSSException { if (m_defaultMech != null) return (m_defaultMech.getOid()); Provider []p = java.security.Security.getProviders(); //check each provider for (int i = 0; i < p.length; i++) { String []mechs = MechInfo.getMechsForProvider(p[i]); if (mechs == null) continue; m_defaultMech = new MechInfo(p[i], mechs[0]); return (m_defaultMech.getOid()); } throw new GSSException(GSSException.BAD_MECH); } /** * Adds only unique values to the specified vector. * @param v - vector to add to * @param oid - the oid to add */ private static void addUniqueOid(Vector v, Oid anOid) { for (Enumeration e = v.elements(); e.hasMoreElements();) { if ( ((Oid)e.nextElement()).equals(anOid)) return; } v.addElement(anOid); } /** * Returns a provider specific implementation of the credential * object. */ static GSSCredSpi getCredInstance(Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech.getCredInstance()); } /** * Returns a provider specific implementation of the name * object. */ static GSSNameSpi getNameInstance(Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech.getNameInstance()); } /** * Returns a provider specific implementation of the GSSCtxtSpi * object. */ static GSSCtxtSpi getCtxtInstance (Oid mech) throws GSSException { //get mech out of the mech table, and if need be load it MechInfo aMech = getMechInfo(mech, true); return (aMech.getCtxtInstance ()); } /** * Obtains the MechInfo object for the specified mechanism. * * @param installMech this boolean indicates if the mechanism * should be loaded if it isn't already */ private static synchronized MechInfo getMechInfo(Oid oid, boolean installMech) throws GSSException { //look in the hash table first MechInfo aMech = MechTable.getMechInfo(oid); if (aMech != null) { if (installMech) MechTable.putMechInfo(aMech); return (aMech); } //need to search all providers Provider [] p = java.security.Security.getProviders(); String mechString = oid.toString(); for (int i=0; i < p.length; i++) { if (MechInfo.implementsMech(p[i], mechString)) { try { aMech = new MechInfo(p[i], mechString); if (installMech) MechTable.putMechInfo(aMech); return (aMech); } catch (GSSException e) { //skip over this provider, there might be //other good ones continue; } } } //this mechanism is not installed on the system throw new GSSException(GSSException.BAD_MECH); } /** * Debug method. */ private static void showProviderDetails() { Provider [] p = java.security.Security.getProviders(); MechInfo [] mechs; boolean foundGSSProv = false; for (int i = 0; i < p.length; i++ ) { mechs = MechInfo.getInfoForAllMechs(p[i]); if (mechs == null) continue; foundGSSProv = true; } } //private class variable - default mechanism oid private static MechInfo m_defaultMech; } // end of Class GSSManager /** * Class to store mechanism information extracted from the providers. * It contains all the provider parsing code. */ class MechInfo { //hides the default constructor private MechInfo() { } /** * Constructor to populate the object with information from * the provider. * @param p - the provider to be queried for mechanism info * @param oid - the mechanism which the provider is to be * queried for * @exception GSSException with major status of BAD_MECH when * this provider does not implement the specified mechanism */ MechInfo(Provider p, String oid) throws GSSException { String aStr; m_oid = new Oid(oid); m_myP = p; updateOidAlias(p, oid); if ((aStr = getProvValue (p, oid, "NAMES")) != null) { StringTokenizer st = new StringTokenizer(aStr, ":"); m_names = new Oid[st.countTokens()]; int i = 0; while (st.hasMoreTokens()) { m_names[i] = new Oid(st.nextToken()); i++; } } else throw new GSSException(GSSException.BAD_MECH); m_nameClassName = getProvValue (p, oid, "NAME"); m_ctxtClassName = getProvValue (p, oid, "CONTEXT"); m_credClassName = getProvValue (p, oid, "CRED"); if (m_nameClassName == null || m_ctxtClassName == null || m_credClassName == null) throw new GSSException(GSSException.BAD_MECH); } /** * Checks if this mechanism supports the supplied name oid. * @param nameOid - the oid for name to be checked * in dot notation * @return true if name type is supported, false otherwise */ boolean supportsName(Oid nameOid) { for (int i = 0; i < m_names.length; i++) { if (m_names[i].equals(nameOid)) return (true); } return (false); } /** * Returns the names supported by this mech. */ Oid[] getNames() { return (m_names); } /** * Returns the oid for this mechanism. */ Oid getOid() { return (m_oid); } /** * Returns an instance of the class implementing the GSSCredSpi * interface for this mechanism. */ GSSCredSpi getCredInstance() throws GSSException { try { if (m_credClass == null) { //create the class object m_credClass = Class.forName(m_credClassName); } return ((GSSCredSpi)m_credClass.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns an instance of the class implementing the GSSCtxtSpi * interface for this mechanism. */ GSSCtxtSpi getCtxtInstance () throws GSSException { try { if (m_ctxtClass == null) { //create the class object m_ctxtClass = Class.forName(m_ctxtClassName); } return ((GSSCtxtSpi)m_ctxtClass.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns an instance of the class implementing the JGSSNameSpi * interface for this mechanism. */ GSSNameSpi getNameInstance() throws GSSException { try { if (m_nameClass == null) { //create the class object m_credClass = Class.forName(m_nameClassName); } return ((GSSNameSpi)m_credClass.newInstance()); } catch (Exception e) { throw new GSSException(GSSException.UNAVAILABLE); } } /** * Returns the provider for this mechanism. * * @return p - provider for this mechanism. */ Provider getProvider() { return (m_myP); } /** * Returns a provider value for the given key. * Both alias and oid is attempted to get the value. * @param provider to query * @param mechanism oid to be queried * @param key for the value to retrieve (JGSS.Mech. is prepended to it) * @return the value from the provider for the give mechanism and key */ private static String getProvValue (Provider p, String mechOid, String key) { String aStr; if ((aStr = p.getProperty("JGSS.Mech." + mechOid + "." + key)) != null) { return (aStr); } if ((aStr = oidStrToAlias(mechOid)) == null) return null; return (p.getProperty("JGSS.Mech." + aStr + "." + key)); } /** * Returns the alias name for the passed in mechanism oid. * @param mechanism oid in dot notation * @return alias name for the oid; null if not found */ private static String oidStrToAlias(String mechOid) { return M_oidAlias.getProperty(mechOid); } /** * Returns the oid string for the given alias. * @return oid str in dot notation for the supplied alias name; * null if it does net exist */ private static String aliasToOidStr(String mechAlias) { return M_oidAlias.getProperty(mechAlias); } /** * Updates the oid <--> alias mapping. * If the mapping already exists, it is *not* replaced. */ private static synchronized void updateOidAlias(Provider p, String mechOid) { //check if mapping already exists if (M_oidAlias.getProperty(mechOid) != null) return; String aStr = p.getProperty("JGSS.Mech." + mechOid + ".Alias"); if (aStr != null) { M_oidAlias.put(mechOid, aStr); M_oidAlias.put(aStr, mechOid); } } /** * Queries if this is a JGSS provider implementing the * specified oid. */ static boolean implementsMech(Provider p, String oid) { String [] mechs = getMechsForProvider(p); if (mechs == null) return (false); for (int i = 0; i < mechs.length; i++) { if (mechs[i].equals(oid)) return (true); } return (false); } /** * Creates MechInfo objects for all the mechs this * provider supports. */ static MechInfo[] getInfoForAllMechs(Provider p) { String mechsStr = p.getProperty("JGSS.Mechs"); //does this provider even support JGSS ? if (mechsStr == null) return (null); StringTokenizer st = new StringTokenizer(mechsStr, ":"); MechInfo[] mInfo = new MechInfo[st.countTokens()]; for (int i = 0; i < mInfo.length; i++) { try { mInfo[i] = new MechInfo(p, st.nextToken()); } catch (GSSException e) { } } return (mInfo); } /** * Queries the provider for all the mechanisms it offers * @return mechs - the mechanism oids this provider offers */ static String[] getMechsForProvider(Provider p) { String aStr; if ((aStr = p.getProperty("JGSS.Mechs")) != null ) { //get the supported mechs - there may be more then one StringTokenizer st = new StringTokenizer(aStr,":"); String[] res = new String[st.countTokens()]; for (int i = 0; i < res.length; i++) res[i] = st.nextToken(); return (res); } return (null); } /** * Returns string with mechanism information. */ public String toString() { StringBuffer aBuf = new StringBuffer(100); aBuf.append("Mechanism oid:\t").append(m_oid); aBuf.append("\nMechanism alias:\t").append( oidStrToAlias(m_oid.toString())); aBuf.append("\nMy provider: "); if (m_myP == null) aBuf.append("null"); else aBuf.append(m_myP.getInfo()); aBuf.append("\nSupported Names:\t"); for(int i = 0; i < m_names.length; i++) aBuf.append(m_names[i].toString()).append(" "); aBuf.append("\nName Class:\t").append(m_nameClassName); aBuf.append("\nCred Class:\t").append(m_credClassName); aBuf.append("\nCtxt Class:\t").append(m_ctxtClassName); return (aBuf.toString()); } //instance variables private Oid m_oid; //oid for this mech private Oid []m_names; //oids for names supported by the mech private String m_nameClassName; //name of the name class private String m_ctxtClassName; //name of the ctxt class private String m_credClassName; //name of the credential class private Provider m_myP; //provider for this mech private Class m_nameClass; //class implementing name private Class m_credClass; //class implementing cred private Class m_ctxtClass; //class implementing ctxt //class variables private static Properties M_oidAlias; //oid <-> alias mapping static { M_oidAlias = new Properties(); } } /* * Package private class that stores Oid -> MechInfo mapping for jgss * Only loaded mechanisms are in this table. */ class MechTable { /** * Hide constructor */ private MechTable() { } /** * Returns mechanism info for the specified oid. null if * it does not exit. */ static MechInfo getMechInfo(Oid oid) { return ((MechInfo)M_table.get(oid)); } /** * Puts the mapping for a mechanism into the table. * If the mechanism is already in the table, it is not * updated. Returns boolean indicating if the mechanism * information was stored. */ static boolean putMechInfo(MechInfo aMech) { if (M_table.containsKey(aMech.getOid())) return (false); M_table.put(aMech.getOid(), aMech); return (true); } //private table storing the mapping private static Hashtable M_table; static { M_table = new Hashtable(13); } } //end of Class MechTable yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSName.java000066400000000000000000000474321356275373100232470ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.util.Vector; import java.util.Enumeration; /** * An object of this class encapsulates a single GSS-API principal entity. * Different name formats and their definitions are identified with * universal Object Identifiers (Oids). The format of the names can be * derived based on the unique oid of each name type. *

* JGSS distinguishes between the following name representations: *

*
RFC 2078 *
This class implements the following RFC 2078 functions: * *
* @see Oid */ public class GSSName { /** * Name type used to indicate a host-based service name form. It * is used to represent services associated with host computers. * This name form is constructed using two elements, "service" and * "hostname", as follows: service@hostname *
* Values for the "service" element are registered with the IANA. * It represents the following value: *

{ 1(iso), 3(org), 6(dod), 1(internet), 5(security), * 6(nametypes), 2(gss-host-based-services) } */ public static final Oid NT_HOSTBASED_SERVICE; /** * Name type used to indicate a named user on a local system. It * represents the following value: *

* { iso(1) member-body(2) United States(840) mit(113554) * infosys(1) gssapi(2) generic(1) user_name(1) } */ public static final Oid NT_USER_NAME; /** * Name type used to indicate a numeric user identifier corresponding * to a user on a local system. (e.g. Uid). It represents the * following value: *

* { iso(1) member-body(2) United States(840) mit(113554) infosys(1) * gssapi(2) generic(1) machine_uid_name(2) } */ public static final Oid NT_MACHINE_UID_NAME; /** * Name type used to indicate a string of digits representing the * numeric user identifier of a user on a local system. It * represents the following value: *

* { iso(1) member-body(2) United States(840) mit(113554) infosys(1) * gssapi(2) generic(1) string_uid_name(3) } */ public static final Oid NT_STRING_UID_NAME; /** * Name type used to represent an Anonymous identity. It represents * the following value: *

* { 1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes), * 3(gss-anonymous-name) } */ public static final Oid NT_ANONYMOUS; /** * Name type used to indicate an exported name produced by the * export method. It represents the following value: *

* { 1(iso), 3(org), 6(dod), 1(internet), 5(security), 6(nametypes), * 4(gss-api-exported-name) } */ public static final Oid NT_EXPORT_NAME; //initialize the oid objects static { try { NT_HOSTBASED_SERVICE = new Oid("1.3.6.1.5.6.2"); NT_USER_NAME = new Oid("1.2.840.113554.1.2.1.1"); NT_MACHINE_UID_NAME = new Oid("1.2.840.113554.1.2.1.2"); NT_STRING_UID_NAME = new Oid("1.2.840.113554.1.2.1.3"); NT_ANONYMOUS = new Oid("1.3.6.1.5.6.3"); NT_EXPORT_NAME = new Oid("1.3.6.1.5.6.4"); } catch (GSSException e) { //because we are initializeing statics, we can //only throw a standard runtime exception throw new NumberFormatException(); } } /** * Converts a contiguous string name to a GSSName object * of the specified type. The nameStr parameter is * interpreted based on the type specified. * In general, the GSSName object created will not be an MN; * the exception to this is if the type parameter indicates * NT_EXPORT_NAME. *

*

RFC 2078
equivalent to gss_import_name
* @param nameStr the name to create * @param type an oid specifying the name type */ public GSSName(String nameStr, Oid type) { m_nameStr = nameStr; m_nameType = type; } /** * Creates a new GSSName object from the specified type. It * is envisioned that this constructor will be called with * buffers returned from GSSName.export() or for name types * that aren't represented by printable strings. *
RFC 2078 *
equivalent to gss_import_name
* @param name buffer containing name * @param type an Oid specifying the name type * @exception GSSException with possible major codes of * BAD_NAMETYPE, BAD_NAME, or FAILURE. * @see GSSName#GSSName(String,Oid) * @see GSSName#GSSName(byte[],Oid,Oid) * @see #export */ public GSSName(byte[] name, Oid type) throws GSSException { m_nameType = type; m_nameBytes = new byte[name.length]; System.arraycopy(name, 0, m_nameBytes, 0, name.length); //check if export name, which means we can load it right now if (type.equals(NT_EXPORT_NAME)) { if (name[0] != 0x04 && name[1] != 0x01) throw new GSSException(GSSException.BAD_NAME); Oid mechOid = new Oid(name, 2); GSSNameSpi mn = GSSManager.getNameInstance(mechOid); mn.init(name, type); addMechName(mn); } } /** * Creates a new GSSName object of the specified type. * This constructor takes an additional mechanism oid parameter * which allows the creation of a mechanism name in one step. *

*

RFC 2078
equivalent to gss_import_name * followed by gss_canonicalize_name
* @param nameStr the name to create * @param nameType an oid specifying the name type * @param mechType the oid of the mechanism to create this name for * @exception GSSException with possible major codes of * BAD_NAMETYPE, BAD_NAME, or FAILURE. * @see GSSName#GSSName(String,Oid) */ public GSSName(String nameStr, Oid nameType, Oid mechType) throws GSSException { m_nameStr = nameStr; m_nameType = nameType; GSSNameSpi mn = GSSManager.getNameInstance(mechType); mn.init(nameStr, nameType); addMechName(mn); } /** * Creates a new GSSName object from the specified type. It * is envisioned that this constructor will be called with * buffers returned from GSSName.export() or for name types * that aren't represented by printable strings. This constructor * takes an additional parameter for the mechanism oid. *
RFC 2078
* equivalent to gss_import_name followed by gss_canonicalize_name *
* @param name buffer containing name * @param nameType an Oid specifying the name type * @param mechType an Oid for the mechanism to create this name for * @exception GSSException with possible major codes of * BAD_NAMETYPE, BAD_NAME, or FAILURE. * @see GSSName#GSSName(String,Oid) * @see GSSName#GSSName(name,Oid) * @see #export */ public GSSName(byte[] name, Oid nameType, Oid mechType) throws GSSException { m_nameType = nameType; m_nameBytes = new byte[name.length]; System.arraycopy(name, 0, m_nameBytes, 0, name.length); GSSNameSpi mn = GSSManager.getNameInstance(mechType); mn.init(name, nameType); addMechName(mn); } /** * Package private constructor used by the clone method and * the credential object. - WE must make sure we set the name type * oid. */ GSSName() { } /** * Package private constructor used by canonicalize name * and the context object. Sets the specified mechanism name. */ GSSName(GSSNameSpi mechName) { addMechName(mechName); m_nameType = mechName.getNameType(); } /** * Compares this name with the specified GSSName for equality. * If either of the names has type NT_ANONYMOUS, this call will * return false. *
RFC 2078 *
equivalent to gss_compare_name
* @param another the GSSName object to be compared * @return true if they both names refer to the same entity, false * otherwise * @overrides equals in class Object */ public boolean equals(Object another) { if ( !(another instanceof GSSName)) return (false); try { return (equals((GSSName)another)); } catch (GSSException e) { return false; } } /** * A variation of equals method which may throw a GSSException * when the names cannot be compared. If either of the names * represents an anonymous entity, the method will return false. *
RFC 2078 *
equivalent to gss_compare_name
* @param another GSSName object to be compared * @return true if they both names refer to the same entity, false * otherwise * @exception GSSException with possible major codes of * BAD_NAMETYPE, BAD_NAME, FAILURE */ public boolean equals(GSSName another) throws GSSException { //check if anonymous name if (isAnonymousName() || another.isAnonymousName()) return (false); if (m_mechNames.size() != another.m_mechNames.size()) return false; if (m_mechNames.size() < 1) { //check if the external names match if (! m_nameType.equals(another.m_nameType)) return false; if (m_nameStr != null && another.m_nameStr != null) return (m_nameStr.equals(another.m_nameStr)); if (m_nameBytes != null && another.m_nameBytes != null) return (m_nameBytes.equals(another.m_nameBytes)); return false; } //we have some mechanism names, each name must be over same //mechs and the names must equal GSSNameSpi mechName1, mechName2; for (Enumeration e = m_mechNames.elements(); e.hasMoreElements();) { mechName1 = (GSSNameSpi)e.nextElement(); if ((mechName2 = another.getMechName(mechName1.getMech())) == null) return false; if (! mechName1.equals(mechName2)) return false; } //went through all the names and they equal, so must be same name return (true); } /** * Creates a new name which is guaranteed to be mechanism specific (MN). *
RFC 2078 *
equivalent to gss_canonicalize_name
* @param mechOid oid of the mechanism for which the name should be * canonicalized * @return a mechanism specific internal name (MN) * @exception GSSException with possible major codes of * BAD_MECH, BAD_NAMETYPE. */ public GSSName canonicalize(Oid mechOid) throws GSSException { //check if we already contain the mechanism name GSSNameSpi mechName = getMechName(mechOid); if (mechName != null) { if (isMechName()) return (this); //need to create new name only for this mechanism return (new GSSName((GSSNameSpi)mechName.clone())); } //we don't already have it, so create it if (m_nameStr != null) return (new GSSName(m_nameStr, m_nameType, mechOid)); else return (new GSSName(m_nameBytes, m_nameType, mechOid)); } /** * Returns a flat name representation for this GSSName object. The * name must be in MN format before making this call. The name is * prefixed with a mechanism independent header as specified in * RFC 2078. The returned buffer can be passed into a GSSName * constructor with GSSName.EXPORT_NAME as the name type. *
RFC 2078 *
equivalent to gss_export_name
* @return a byte array representing the name * @exception GSSException with possible major codes of NAME_NOT_MN, * BAD_NAME, BAD_NAMETYPE, FAILURE. * @see #canonicalize */ public byte[] export() throws GSSException { //check if we have a mechanism specific name if (!isMechName()) throw new GSSException(GSSException.NAME_NOT_MN); return (getMechName(null).export()); } /** * Returns a string representation of the GSSName object. * To retrieve the printed name format call getStringNameType. * @return a String representation for this GSSName * @overrides java.lang.Object#toString * @see #getStringNameType **/ public String toString() { if (isMechName()) return (getMechName(null).toString()); if (m_nameStr != null) return (m_nameStr); if (m_mechNames.size() > 0) return (getMechName(null).toString()); //name must in byte format return ("Unknown name"); } /** * Returns the name type for the printed name. *
RFC 2078 *
equivalent to name_type parameter in gss_display_name
* @return Oid for the name type as printed with toString() * @exception GSSException when the name can't be printed * @see #toString */ public Oid getStringNameType() throws GSSException { if (isMechName()) return (getMechName(null).getStringNameType()); if (m_nameStr != null) return (m_nameType); if (m_mechNames.size() > 0) return (getMechName(null).getStringNameType()); throw new GSSException(GSSException.BAD_NAME); } /** * Creates a duplicate of this object. *
RFC 2078 *
equivalent to gss_duplicate_name
* @return a copy of this object * @exception CloneNotSupportedException may be thrown */ public Object clone() throws CloneNotSupportedException { GSSName newName; try { if (m_nameStr != null) newName = new GSSName(m_nameStr, m_nameType); else if (m_nameBytes != null) newName = new GSSName(m_nameBytes, m_nameType); else newName = new GSSName(); for (Enumeration e = m_mechNames.elements(); e.hasMoreElements(); ) newName.addMechName((GSSNameSpi) ((GSSNameSpi)e.nextElement()).clone()); } catch (Exception e) { throw new CloneNotSupportedException(); } return (newName); } /** * Tests if this is an Anonymous name object. * @return boolean indicating if this in an anonymous name */ public boolean isAnonymousName() { if (m_nameType.equals(NT_ANONYMOUS)) return (true); if (m_mechNames.size() > 0) return (getMechName(null).isAnonymousName()); return false; } /** * Package private method to add a mechanism name to * the name. Used by the credential object. * */ void addMechName(GSSNameSpi mechName) { m_mechNames.addElement(mechName); } /** * Tests if this is a mechanism name. * Mechanism name is defined as having only one mechanism * name element. * @return boolean indicating if this is a MN */ private boolean isMechName() { return (m_mechNames.size() == 1); } /** * Retrieves a mechanism specific name for the specified oid. * If the name is not found, null is returned. null oid can be * used to retrieve the first mechanism name. * * @param Oid for the mechanism name to retrieve * @return GSSNameSpi for the requested mechanism or null if not found */ GSSNameSpi getMechName(Oid mechOid) { if (mechOid == null) { if (m_mechNames.size() < 1) return (null); return ((GSSNameSpi)m_mechNames.firstElement()); } for (Enumeration e = m_mechNames.elements(); e.hasMoreElements(); ) { GSSNameSpi mechName = (GSSNameSpi)e.nextElement(); if (mechName.getMech().equals(mechOid)) return (mechName); } return (null); } /** * Returns the mechanism specific name. If this name does not * already contain it, it is created. * @param mechOid oid of the mechanism for which the name should be * canonicalized * @return a mechanism specific internal name * @exception GSSException with possible major codes of * BAD_MECH, BAD_NAMETYPE. */ GSSNameSpi canonicalizeInPlace(Oid mechOid) throws GSSException { //check if we already contain the mechanism name GSSNameSpi mechName = getMechName(mechOid); if (mechName != null) return (mechName); //we don't already have it, so create it mechName = GSSManager.getNameInstance(mechOid); if (m_nameStr != null) mechName.init(m_nameStr, m_nameType); else mechName.init(m_nameBytes, m_nameType); addMechName(mechName); return (mechName); } //instance variables //we use a vector because GSSCredential.getName() must return //all the credential names in mechanism format Vector m_mechNames = new Vector(3,2); Oid m_nameType; String m_nameStr; byte [] m_nameBytes; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/GSSNameSpi.java000066400000000000000000000113011356275373100237050ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; /** * This class represents a mechanism specific name element. One or * more instances of this class are contained in an instance of * a GSSName object. Each GSSNameSpi object represents at most 1 * mechanism specific name element. */ public interface GSSNameSpi { /** * Initializer for the GSSNameSpi object using a byte array. * * @param byte[] name bytes which is to be interpreted based * on the nameType * @param nameType - oid representing the type of name supplied * @exception GSSException The major codes can be BAD_NAMETYPE, * BAD_NAME, and FAILURE. * @see #init(String,Oid) */ public void init(byte[] externalName, Oid nameType) throws GSSException; /** * Initializer for the GSSNameSpi object using a String. * * @param name string which is to be interpreted based * on the nameType * @param nameType - oid representing the type of name supplied * @exception GSSException The major codes can be BAD_NAMETYPE, * BAD_NAME, and FAILURE. * @see #init(String,Oid) */ public void init(String name, Oid nameType) throws GSSException; /** * Equal method for the GSSNameSpi objects. * If either name denotes an anonymous principal, the call should * return false. * * @param name to be compared with * @returns true if they both refer to the same entity, else false * @exception GSSException with major codes of BAD_NAMETYPE, * BAD_NAME, FAILURE */ public boolean equals(GSSNameSpi name) throws GSSException; /** * Returns a flat name representation for this object. The name * format is defined in RFC 2078. * * @return the flat name representation for this object * @exception GSSException with major codes NAME_NOT_MN, BAD_NAME, * BAD_NAME, FAILURE. */ public byte[] export() throws GSSException; /** * Get the mechanism type that this NameElement corresponds to. * * @return the Oid of the mechanism type */ public Oid getMech(); /** * Returns the name type oid for this name. * * @return the name type oid for this name */ public Oid getNameType(); /** * Returns a string representation for this name. The printed * name type can be obtained by calling getStringNameType(). * * @return string form of this name * @see #getStringNameType() * @overrides Object#toString */ public String toString(); /** * Returns the oid describing the format of the printable name. * * @return the Oid for the format of the printed name */ public Oid getStringNameType(); /** * Produces a copy of this object. */ public Object clone(); /** * Indicates if this name object represents an Anonymous name. */ public boolean isAnonymousName(); } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/MessageProp.java000066400000000000000000000143721356275373100242340ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; /** * This class conveys information about the per-message security * services requested/provided through the GSSContext class in the * wrap and getMIC methods. It allows the caller to specify * the desired per-message Quality of Protection (QOP) and * privacy state. Upon return from these calls, this object indicates * the actual applied QOP and confidentiality state. * * Instances of this class are also used by the unwrap and verifyMIC * methods to obtain the message protection applied by the peer. The * QOP indicates the algorithm used to protect the message. The * privacy flag indicates if message privacy has been applied. Methods * are also provided to query for supplementary status information * for the processed token. * * @see GSSContext#wrap * @see GSSContext#unwrap * @see GSSContext#getMIC * @see GSSContext#verifyMIC */ public class MessageProp { private boolean m_privacyState; private int m_qop; private boolean m_dupToken; private boolean m_oldToken; private boolean m_unseqToken; private boolean m_gapToken; /** * Default constructor for the class. QOP is set to 0 and * confidentiality to false. */ public MessageProp () { m_qop = 0; m_privacyState = false; resetStatusValues(); } /** * Constructor allowing the setting of the qop and * the privacy state. * * @param qop the qop value for the message * @param privState indicates privacy request/applied state */ public MessageProp(int qop, boolean privState) { m_qop = qop; m_privacyState = privState; resetStatusValues(); } /** * Retrieves the QOP value. * * @return the QOP value */ public int getQOP() { return (m_qop); } /** * Retrieves the privacy state. * * @return true indicates privacy has been applied */ public boolean getPrivacy() { return (m_privacyState); } /** * Sets the QOP value. * * @param QOP value to store. */ public void setQOP(int qopVal) { m_qop = qopVal; } /** * Sets the privacy state. * * @param privacy value to store. */ public void setPrivacy(boolean privState) { m_privacyState = privState; } /** * Method to signal supplementary information. * Returns true if this is a duplicate of an earlier token. */ public boolean isDuplicateToken() { return (m_dupToken); } /** * Method to signal supplementary information. * Returns true if the token's validity period has expired. */ public boolean isOldToken() { return (m_oldToken); } /** * Method to signal supplementary information. * Returns true if a later token has already been processed. */ public boolean isUnseqToken() { return (m_unseqToken); } /** * Method to signal supplementary information. * Returns true if an expected per-message token was not * received. */ public boolean isGapToken() { return (m_gapToken); } /* * The following methods are to set the supplementary * status values. These should be JGSS private, but * the mechanism packages will need access to them. */ /** * Used by mechanism packages to set supplementary status value. * Indicates that an expected per-message token was * not received. */ public void setGapTokenStatus() { m_gapToken = true; } /** * Used by mechanism packages to set supplementary status value. * Indicates this is a duplicate of an earlier token. */ public void setDuplicateTokenStatus() { m_dupToken = true; } /** * Used by mechanism packages to set supplementary status value. * Indicates that the token's validity period has expired. */ public void setOldTokenState() { m_oldToken = true; } /** * Used by mechanism packages to set supplementary status value. * Indicates that a later token has already been processed. */ public void setUnseqTokenStatus() { m_unseqToken = true; } /** * Resets the supplementary status values to false. */ void resetStatusValues() { m_dupToken = false; m_oldToken = false; m_unseqToken = false; m_gapToken = false; } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/Oid.java000066400000000000000000000222521356275373100225160ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; /** * This class represents Universal Object Identifiers (Oids) and * their associated operations. *

* Oids are hierarchically globally-interpretable identifiers * used within the GSS-API framework to identify mechanisms and * name formats. The structure and encoding of Oids is defined * in ISOIEC-8824 and ISOIEC-8825. For example the Oid * representation of Kerberos V5 mechanism is 1.2.840.113554.1.2.2 *

RFC 2078 *
This class replaces the following GSS-API functions: * *
*/ public class Oid { /** * Creates an oid object from its DER octets. */ static Oid getFromDEROctets(InputStream is, int len) throws GSSException { return new Oid(DERParser.decodeOidOctets(is, len)); } /** * Creates an oid object from a vector of its integer components. * The vector is not copied. */ private Oid(Vector v) { m_v = v; } /** * Constructs an Oid object from a string representation of its * integer components. Will throw a GSSException if the string * is improperly formatted. * * @param strOid the string in either of these two formats: * "{1 2 3 3}" or "1.2.3.3". * @exception GSSException may be thrown when the * string is incorrectly formatted */ public Oid(String strOid) throws GSSException { m_v = new Vector(8, 3); parseFromStr(strOid); } /** * Constructs an Oid object from its DER encoding. The structure * and encoding of Oids is defined in ISOIEC-8824 and ISOIEC-8825. * * @param derOid stream containing the DER encoded oid * @exception GSSException may be thrown when the DER * encoding does not follow the prescribed format. */ public Oid(InputStream derOid) throws GSSException { m_v = DERParser.decodeOid(derOid); } /** * Constructs an Oid object from its DER encoding. The structure * and encoding of Oids is defined in ISOIEC-8824 and ISOIEC-8825. * * @param data byte array containing the DER encoded oid * @param offset where in the data byte array to start from * @exception GSSException may be thrown when the DER * encoding does not follow the prescribed format. */ public Oid(byte [] data, int offset) throws GSSException { m_v = DERParser.decodeOid(new ByteArrayInputStream(data, offset, data.length - offset)); } /** * Constructs an Oid object from its DER encoding. The structure * and encoding of Oids is defined in ISOIEC-8824 and ISOIEC-8825. * * @param DEROid a byte array containing the DER encoding of the Oid * @exception GSSException may be thrown when the DER * encoding does not follow the prescribed format. * @see Oid#Oid(java.io.InputStream) */ public Oid(byte[] DEROid) throws GSSException { m_v = DERParser.decodeOid(new ByteArrayInputStream(DEROid)); } /** * Returns a string representation of the oid's integer components * in dot separated notation. * @return string representation in the following format: "1.2.3.4.5" * @see #toRFC2078String * @overrides java.lang.Object#toString */ public String toString() { StringBuffer sb = new StringBuffer(50); if (m_v.size() < 1) return (new String("")); for (Enumeration e = m_v.elements(); e.hasMoreElements();) { sb.append(e.nextElement().toString()); if (e.hasMoreElements()) sb.append("."); } return (sb.toString()); } /** * Returns a string representation of the Oid's integer components * in the format specified within RFC 2078. For example { 1 2 3 4 } *
RFC 2078 *
equivalent to gss_oid_to_str
* @return string representation in the following format: { 1 2 3 4 5 } * @see #toString */ public String toRFC2078String() { StringBuffer sb = new StringBuffer(50); if (m_v.size() < 1) return (new String("")); sb.append("{ "); for (Enumeration e = m_v.elements(); e.hasMoreElements(); ) { sb.append(e.nextElement().toString()); sb.append(" "); } sb.append("}"); return (sb.toString()); } /** * Equality test for oid objects. * @param Obj Oid object that has to be compared to this one * @return true if they represent the same Oid, false otherwise * @overrides java.lang.Object#equals */ public boolean equals(Object Obj) { if (! (Obj instanceof Oid)) return (false); //check if both reference the same object if (this == Obj) return (true); Oid anOid = (Oid) Obj; if (m_v.size() != anOid.m_v.size()) return (false); for (Enumeration e1 = m_v.elements(), e2 = anOid.m_v.elements(); e1.hasMoreElements(); ) { if (! e1.nextElement().equals(e2.nextElement())) return (false); } return (true); } /** * Returns the full ASN.1 DER encoding for this oid object. * * @return byte array containing the DER encoding of this oid object. * @exception GSSException may be thrown when the oid can't be encoded */ public byte[] getDER() throws GSSException { if (m_der != null) return (m_der); m_der = DERParser.encodeOid(m_v); return (m_der); } /** * A utility method which takes an array of Oids and checks if * it contains this oid object. *

RFC 2078 *
In the JGSS package Oid sets are represented as arrays of * Oids. This method is equivalent to gss_test_oid_set_member.
* @param An array of Oids to search * @return true if the array contains this object, false otherwise */ public boolean containedIn(Oid[] oids) { for (int i = 0; i < oids.length; i++) { if (oids[i].equals(this)) return (true); } return (false); } /** * Parses in the string encoding of the object. * * @param src string to parse * @exception GSSException when src string is incorrectly formatted **/ private void parseFromStr(String src) throws GSSException { int firstIndex = src.indexOf("{"); try { //skip over the { and } first if (firstIndex != -1) src = src.substring(firstIndex, src.lastIndexOf("}")); StringTokenizer st = new StringTokenizer(src, " ."); while (st.hasMoreTokens()) { m_v.addElement(new Integer(st.nextToken())); } } catch (Exception e) { throw new GSSException(GSSException.FAILURE); } } //Instance variables private Vector m_v; byte [] m_der; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs.properties000066400000000000000000000045321356275373100243560ustar00rootroot00000000000000# # Copyright (c) 1999, 2007 Sun Microsystems, Inc. # All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # -Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # -Redistribution in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Sun Microsystems, Inc. or the names of contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # This software is provided "AS IS," without a warranty of any kind. ALL # EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING # ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR # PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS # SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE # AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE # SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE # LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, # SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED # AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR # INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # # You acknowledge that this software is not designed,licensed or intended # for use in the design, construction, operation or maintenance of any # nuclear facility. # # # # This is the "GSS security machanism plug-in properties file". # # This file provides a way to plug-in a security mechanism into # the java gss-api framework simply by providing the class name of # the plug-in Provider. # # Each entry is of the form: # # gss.provider.= # # # This declares a GSS-API plug-in provider, , which is a subclass # of the java.security.Provider, and specifies its preference order # as the default GSS-API plug-in provider. The order is 1-based; 1 is the # most preferred default gss plug-in, and so on. # # # # Example: # # gss.provider.1=com.sun.gssapi.dummy.Dummy yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/000077500000000000000000000000001356275373100222345ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/dummy/000077500000000000000000000000001356275373100233675ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/dummy/Dummy.java000066400000000000000000000063521356275373100253330ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi.mechs.dummy; import java.security.Provider; import com.sun.gssapi.Oid; import com.sun.gssapi.GSSException; /** * Dummy Mechanism plug in for JGSS * This is the properties object required by the JGSS framework. * All mechanism specific information is defined here. */ public final class Dummy extends Provider { private static String info = "JGSS Dummy Mechanism Provider"; public Dummy() { super("JGSS Dummy Provider 1", 1.0, info); //list mechs supported put("JGSS.Mechs", "1.3.6.1.4.1.42.2.26.1.2"); //configure 1.3.6.1.4.1.42.2.26.1.2 put("JGSS.Mech.1.3.6.1.4.1.42.2.26.1.2.Alias", "dummy"); put("JGSS.Mech.dummy.NAMES", "1.3.6.1.5.6.2:1.2.840.113554.1.2.1.1"); put("JGSS.Mech.dummy.CRED", "com.sun.gssapi.dummy.DummyCred"); put("JGSS.Mech.dummy.CONTEXT", "com.sun.gssapi.dummy.DummyCtxt"); put("JGSS.Mech.dummy.NAME", "com.sun.gssapi.dummy.DummyName"); } /** * Package private method to return the oid of this mech. */ static Oid getMyOid() { return (M_myOid); } /** * Package private method to return the number of tokens * to be used in the context creation exchange. */ static int getNumOfTokExchanges() { return (M_tokNum); } //private variables private static Oid M_myOid; private static final int M_tokNum = 2; static { try { M_myOid = new Oid("1.3.6.1.4.1.42.2.26.1.2"); } catch (GSSException e) { throw new NumberFormatException(); } } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/dummy/DummyCred.java000066400000000000000000000131241356275373100261240ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi.mechs.dummy; import com.sun.gssapi.*; /** * Implements the dummy credential class. */ public class DummyCred implements GSSCredSpi { /** * Standard constructor. */ public DummyCred() { m_freed = false; } /** * Initialization entry point. * * @param name of the credential entity; can be null * meaning a system default * @param Desired lifetime for the credential's ability * to initialize contexts; 0 means use default * @param Desired lifetime for the credential's ability * to accept contexts; 0 means default * @param Credential usage flag. * @exception GSSException may be thrown */ public void init(GSSNameSpi aName, int initLifetime, int acceptLifetime, int usage) throws GSSException { //set the name if (aName == null) m_myName = DummyName.getDefault(); else { //must be a dummy name if (!(aName instanceof DummyName)) throw new GSSException(GSSException.BAD_NAME); m_myName = (DummyName)aName; } //get my lifetime if (initLifetime == 0) m_initLifetime = GSSCredential.INDEFINITE; else m_initLifetime = initLifetime; if (acceptLifetime == 0) m_acceptLifetime = GSSCredential.INDEFINITE; else m_acceptLifetime = acceptLifetime; m_usage = usage; m_freed = false; } /** * Release this mechanism specific credential element. * * @exception GSSException with major codes NO_CRED and FAILURE. */ public void dispose() throws GSSException { m_freed = true; m_myName = null; } /** * Returns the name for the credential. * * @exception GSSException may be thrown */ public GSSNameSpi getName() throws GSSException { //some debugging code if (m_freed) throw new GSSException(GSSException.NO_CRED); return (m_myName); } /** * Returns the remaining context initialization lifetime in * seconds. * * @exception GSSException may be thrown */ public int getInitLifetime() throws GSSException { //check if this is valid if (m_freed) throw new GSSException(GSSException.NO_CRED); //return time based on usage if (getUsage() == GSSCredential.ACCEPT_ONLY) return (0); return (m_initLifetime); } /** * Returns the remaining context acceptance lifetime in * seconds. * * @exception GSSException may be thrown */ public int getAcceptLifetime() throws GSSException { //sanity check if (m_freed) throw new GSSException(GSSException.NO_CRED); //take usage into account if (getUsage() == GSSCredential.INITIATE_ONLY) return (0); return (m_acceptLifetime); } /** * Returns the remaining context lifetime in * seconds. This takes into account the usage property and * returns the minimum remaining. * * @exception GSSException may be thrown */ public int getLifetime() throws GSSException { //sanity check if (m_freed) throw new GSSException(GSSException.NO_CRED); //take usage into account, return minimum remaining time if (getUsage() == GSSCredential.ACCEPT_ONLY) return (m_acceptLifetime); else if (getUsage() == GSSCredential.INITIATE_ONLY) return (m_initLifetime); if (m_initLifetime < m_acceptLifetime) return (m_initLifetime); return (m_acceptLifetime); } /** * Returns the credential usage flag. * * @exception GSSException may be thrown */ public int getUsage() throws GSSException { //sanity check if (m_freed) throw new GSSException(GSSException.NO_CRED); return (m_usage); } /** * Returns the credential mechanism. Since this is a single * credential element only a single oid can be returned. */ public Oid getMechanism() { return (Dummy.getMyOid()); } //instance variables private DummyName m_myName; private int m_usage; private int m_initLifetime; private int m_acceptLifetime; private boolean m_freed; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/dummy/DummyCtxt.m4000066400000000000000000000445351356275373100256020ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi.dummy; import java.io.InputStream; import java.io.OutputStream; import java.io.DataOutputStream; import java.io.BufferedOutputStream; import java.io.IOException; import com.sun.gssapi.*; /** * Implements the dummy Context class GSSCtxtSpi interface * for the dummy mechanism. */ public class DummyCtxt implements GSSCtxtSpi { /** * Standard constructor. */ public DummyCtxt() { m_state = NEW; m_tokCount = Dummy.getNumOfTokExchanges(); m_lifetime = 0; } /** * Sets the context parameters for the initiator side of * the context. */ public void _setInitOptions (GSSCredSpi myCred, GSSNameSpi targName, int desLifetime, int ctxtOptions) throws GSSException { //make sure we are in right state if (m_state != NEW) { throw new GSSException(GSSException.NO_CONTEXT); } //set the target name if (targName == null || ! (targName instanceof DummyName)) throw new GSSException(GSSException.BAD_NAME); m_targName = (DummyName)targName; //get the src name from credential - that's all we have in there if (myCred == null) { m_srcName = DummyName.getDefault(); } else { if (! (myCred instanceof DummyCred)) throw new GSSException(GSSException.DEFECTIVE_CREDENTIAL); //we can do the cast below because we know it is our credential m_srcName = (DummyName)myCred.getName(); } //check for default lifetime request if (desLifetime == 0) m_lifetime = GSSContext.INDEFINITE; else m_lifetime = desLifetime; m_flags = ctxtOptions; m_initiator = true; } /** * Sets the context parameters for the acceptor side * of the context. */ public void _setAcceptOptions (GSSCredSpi myCred) throws GSSException { if (myCred == null) { m_targName = DummyName.getDefault(); m_lifetime = GSSContext.INDEFINITE; } else { if (!(myCred instanceof DummyCred)) throw new GSSException(GSSException.NO_CRED); m_targName = (DummyName)myCred.getName(); m_lifetime = myCred.getAcceptLifetime(); } m_flags = 0; m_initiator = false; } /** * Sets the channel bindings to be used during context * establishment. */ public void _setChannelBinding (ChannelBinding chb) throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Retrieves the mechanism options. * * @return int GSSContext options ORed together */ public int _getOptions () { return (m_flags); } /** * Inquire the remaining lifetime. * * @return the lifetime in seconds. May return reserved * value GSSContext.INDEFINITE for an indefinite lifetime. */ public int _getLifetime () { return (m_lifetime); } /** * Returns the mechanism oid. * * @return the Oid of this context */ public Oid _getMech () { return (Dummy.getMyOid()); } /** * Returns the context initiator name. * * @return initiator name * @exception GSSException */ public GSSNameSpi _getSrcName () throws GSSException { if (m_state != DONE) { throw new GSSException(GSSException.NO_CONTEXT); } return (m_srcName); } /** * Returns the context acceptor. * * @return context acceptor(target) name * @exception GSSException */ public GSSNameSpi _getTargName () throws GSSException { if (m_state != DONE) { throw new GSSException(GSSException.NO_CONTEXT); } return (m_targName); } /** * Returns the delegated credential for the context. This * is an optional feature of contexts which not all * mechanisms will support. A context can be requested to * support credential delegation by using the CRED_DELEG. * This is only valid on the acceptor side of the context. * @return GSSCredSpi object for the delegated credential * @exception GSSException * @see GSSContext#getDelegCredState */ public GSSCredSpi _getDelegCred () throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Tests if this is the initiator side of the context. * * @return boolean indicating if this is initiator (true) * or target (false) */ public boolean _isInitiator () { return (m_initiator); } /** * Tests if the context can be used for per-message service. * Context may allow the calls to the per-message service * functions before being fully established. * * @return boolean indicating if per-message methods can * be called. */ public boolean _isProtReady () { return (m_state == DONE); } /** * Initiator context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. On the * first call it will be ignored. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException */ public int _initSecCtxt (InputStream is, OutputStream os) throws GSSException { boolean needTokenBack = true; boolean sendToken = true; m_tokCount--; if (m_state == NEW) { m_initiator = true; m_state = IN_PROCESS; } else if (m_state == IN_PROCESS) { if (!_isInitiator ()) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } //read the token sendToken = processEstabToken(is); } //determine if we need token back if (!sendToken || m_tokCount < 1) needTokenBack = false; if (sendToken) { //create a token for our peer createEstabOutToken(os, needTokenBack); } if (needTokenBack) { return (GSSContext.CONTINUE_NEEDED); } m_state = DONE; return (GSSContext.COMPLETE); } /** * Acceptor's context establishment call. This method may be * required to be called several times. A CONTINUE_NEEDED return * call indicates that more calls are needed after the next token * is received from the peer. * * @param is contains the token received from the peer. * @param os to which any tokens required to be sent to the peer * will be written. It is responsibility of the caller * to send the token to its peer for processing. * @return integer indicating if more calls are needed. Possible * values are COMPLETE and CONTINUE_NEEDED. * @exception GSSException */ public int _acceptSecCtxt (InputStream is, OutputStream os) throws GSSException { boolean needTokenBack = true; boolean sendToken = true; //we have this but it's not used since the status // code in tokens dictate if we need more m_tokCount--; if (m_state == NEW) { m_initiator = false; m_state = IN_PROCESS; } else if (m_state == IN_PROCESS) { if (_isInitiator ()) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } //read the token sendToken = processEstabToken(is); } //determine if we need token back if (!sendToken || m_tokCount < 1) needTokenBack = false; if (sendToken) { //create a token for our peer createEstabOutToken(os, needTokenBack); } if (needTokenBack) { return (GSSContext.CONTINUE_NEEDED); } m_state = DONE; m_srcName = new DummyName("dummy src name"); return (GSSContext.COMPLETE); } /** * Queries the context for largest data size to accomodate * the specified protection and be <= maxTokSize. * * @param qop the quality of protection that the context will be * asked to provide. * @param confReq a flag indicating whether confidentiality will be * requested or not * @param outputSize the maximum size of the output token * @return the maximum size for the input message that can be * provided to the wrap() method in order to guarantee that these * requirements are met. * @throws GSSException */ public int _getWrapSizeLimit (int qop, boolean confReq, int maxTokSize) throws GSSException { return (maxTokSize); } /** * Provides per-message token encapsulation. * * @param is the user-provided message to be protected * @param os the token to be sent to the peer. It includes * the message from is with the requested protection. * @param msgPro on input it contains the requested qop and * confidentiality state, on output, the applied values * @exception GSSException * @see MessageInfo * @see unwrap */ public void _wrap (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException { if (m_state != DONE) throw new GSSException(GSSException.NO_CONTEXT); try { int length = is.available(); createTokenHeader(os, length + 1); while (length-- > 0) { os.write(is.read()); } os.write(0); } catch (IOException e) { throw new GSSException(GSSException.FAILURE, -1, "io exception in wrap"); } } /** * Retrieves the message token previously encapsulated in the wrap * call. * * @param is the token from the peer * @param os unprotected message data * @param msgProp will contain the applied qop and confidentiality * of the input token * @return int representing the informatory status; this can be * COMPLETE, DUPLICATE_TOKEN, OLD_TOKEN, UNSEQ_TOKEN and GAP_TOKEN. * @exception GSSException * @see MessageInfo * @see wrap */ public void _unwrap (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException { if (m_state != DONE) throw new GSSException(GSSException.NO_CONTEXT); try { int length = processTokenHeader(is); while (length-- > 0) { os.write(is.read()); } msgProp.setPrivacy(true); msgProp.setQOP(0); } catch (IOException e) { throw new GSSException(GSSException.FAILURE, -1, "io exception in unwrap"); } } /** * Applies per-message integrity services. * * @param is the user-provided message * @param os the token to be sent to the peer along with the * message token. The message token is not encapsulated. * @param msgProp on input the desired QOP and output the applied QOP * @exception GSSException */ public void _getMIC (InputStream is, OutputStream os, MessageProp msgProp) throws GSSException { if (m_state != DONE) throw new GSSException(GSSException.NO_CONTEXT); try { String tokenStr = new String("dummy_gss_sign"); createTokenHeader(os, tokenStr.length() + 1); os.write(tokenStr.getBytes()); os.write(0); msgProp.setPrivacy(false); msgProp.setQOP(0); } catch (IOException e) { throw new GSSException(GSSException.FAILURE, -1, "io exception in unwrap"); } } /** * Checks the integrity of the supplied tokens. * This token was previously generated by getMIC. * * @param is token generated by getMIC * @param msgStr the message to check integrity for * @param msgProp will contain the applied QOP and confidentiality * states of the token * @return int informatory status which can be one of COMPLETE, * DUPLICATE_TOKEN, OLD_TOKEN, UNSEQ_TOKEN and GAP_TOKEN. * @exception GSSException */ public void _verifyMIC (InputStream is, InputStream msgStr, MessageProp mProp) throws GSSException { try { int msgLen = processTokenHeader(is); is.skip(msgLen); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } } /** * Produces a token representing this context. After this call * the context will no longer be usable until an import is * performed on the returned token. * * @param os the output token will be written to this stream * @exception GSSException */ public byte [] _export () throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Imports a previously exported context. * * @param Previously exported token * @exception GSSException * @see export */ public void _importSecCtxt (byte []aCtxtToken) throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Releases context resources and terminates the * context between 2 peer. * * @exception GSSException with major codes NO_CONTEXT, FAILURE. */ public void _dispose () throws GSSException { m_state = DELETED; } /** * Create token used during context establishment. */ private void createEstabOutToken(OutputStream os, boolean moreTokens) throws GSSException { try { String msgBody; if (moreTokens) msgBody = Integer.toString(1); else msgBody = Integer.toString(0); /* * the token is composed of: * tag * DER tok length * DER oid * 2 bytes for token type * msg body */ createTokenHeader(os, msgBody.length() + 1); DataOutputStream dos = new DataOutputStream(os); //need to be written as bytes because that is what C version uses dos.writeBytes(msgBody); dos.write(0); //add null char - this is what C dummy wants dos.flush(); } catch (IOException e) { throw new GSSException(GSSException.FAILURE, -1, "createInitOutToken"); } } /** * Processes the peer's context establishment token. */ private boolean processEstabToken(InputStream is) throws GSSException { try { processTokenHeader(is); //get continue/complete code byte []b = new byte[1]; b[0] = (byte)is.read(); int status = Integer.parseInt(new String(b)); is.read(); //null Byte if (status == 1) return (true); return(false); } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN, -1, "processing init token from peer"); } } /** * Checks the token header. * * @return the length of the message remaining */ private int processTokenHeader(InputStream is) throws GSSException, IOException { if (is.read() != 0x60) throw new GSSException(GSSException.DEFECTIVE_TOKEN); //read token length int length = DERParser.readLength(is); Oid tokOid = new Oid(is); if (!tokOid.equals(Dummy.getMyOid())) throw new GSSException(GSSException.BAD_MECH); //read token tag - not used is.read(); is.read(); //return the length of message remaining return (length - 1 - 1 - 10 - 2); } /** * Constructs the token header */ private void createTokenHeader(OutputStream os, int msgBodyLen) throws GSSException { try { /* * the token header is composed of: * tag * DER tok length * DER oid * 0x0 0x0 (token tag) */ byte [] derOid = Dummy.getMyOid().getDER(); int length = derOid.length + msgBodyLen + 2; DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(os)); dos.write(0x60); DERParser.writeLength(dos, length); dos.write(derOid); //now write the token tag - 0x0 - doesn't seem to be used dos.write(0); dos.write(0); dos.flush(); } catch (IOException e) { throw new GSSException(GSSException.FAILURE, -1, "createTokenHeader"); } } //instance variables private DummyName m_srcName; private DummyName m_targName; private int m_tokCount; private int m_state; private int m_flags; private int m_lifetime; private boolean m_initiator; private static final int NEW = 1; private static final int IN_PROCESS = 2; private static final int DONE = 3; private static final int DELETED = 4; } /** * This is a package private class used to decode/encode ASN.1 DER * length. */ class DERParser { /** * Returns the DER encoded length from the InputStream. */ static int readLength(InputStream is) throws GSSException { int length, tmp; //get the length of Oid - check if short form try { if (((tmp = is.read()) & 0x080) == 0) length = tmp; else { //must be long form tmp &= 0x7f; for (length = 0; tmp > 0; tmp--) { length <<= 8; length += (0xff & is.read()); } } } catch (IOException e) { throw new GSSException(GSSException.DEFECTIVE_TOKEN); } return (length); } /** * Encodes DER length. */ static void writeLength(OutputStream os, int length) throws IOException { //encode the length - for all practical purposes, the length //should always be less then 0x80 (128) if (length < 0x80) os.write(length); else if (length < 0x100) { os.write(0x081); os.write(length); } else if (length < 0x80000) { os.write(0x082); os.write(length >> 8); os.write(length & 0xff); } else if (length < 0x1000000) { os.write(0x083); os.write(length >> 16); os.write((length >> 8) & 0xff); os.write(length & 0xff); } else { os.write(0x084); os.write(length >>> 24); os.write((length >> 16) & 0xff); os.write((length >> 8) & 0xff); os.write(length & 0xff); } } } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/mechs/dummy/DummyName.java000066400000000000000000000126541356275373100261360ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.gssapi.mechs.dummy; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.UnknownHostException; import com.sun.gssapi.*; /** * Implements the GSSNameSpi for the dummy mechanism. */ public class DummyName implements GSSNameSpi { /** * Returns the default name for the dummy mechanism. * It is the username@localDomain. */ static DummyName getDefault() { StringBuffer res = new StringBuffer(System.getProperty("user.name", "unknown")); res.append("@"); try { res.append(InetAddress.getLocalHost().getHostName()); } catch (UnknownHostException e) { res.append("unknown"); } return (new DummyName(res.toString())); } /** * Standard constructor - nop. */ public DummyName() { } /** * Creates a dummy name from the specified user name. */ DummyName(String userName) { m_type = GSSName.NT_USER_NAME; m_name = userName; } /** * Initializer for the GSSNameSpi object using a byte array. * * @param byte[] name bytes which is to be interpreted based * on the nameType * @exception GSSException The major codes can be BAD_NAMETYPE, * BAD_NAME, and FAILURE. * @see #init(String,Oid) */ public void init(byte[] externalName, Oid nameType) throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Initializer for the GSSNameSpi object using a String. * * @param name string which is to be interpreted based * on the nameType * @exception GSSException The major codes can be BAD_NAMETYPE, * BAD_NAME, and FAILURE. * @see #init(String,Oid) */ public void init(String name, Oid nameType) throws GSSException { m_name = name; m_type = nameType; } /** * Equal method for the GSSNameSpi objects. * If either name denotes an anonymous principal, the call should * return false. * * @param name to be compared with * @returns true if they both refer to the same entity, else false * @exception GSSException with major codes of BAD_NAMETYPE, * BAD_NAME, FAILURE */ public boolean equals(GSSNameSpi name) throws GSSException { if (!(name instanceof DummyName)) { return (false); } return (m_name.equals(((DummyName)name).m_name)); } /** * Returns a flat name representation for this object. The name * format is defined in RFC 2078. * * @return the flat name representation for this object * @exception GSSException with major codes NAME_NOT_MN, BAD_NAME, * BAD_NAME, FAILURE. */ public byte[] export() throws GSSException { throw new GSSException(GSSException.UNAVAILABLE); } /** * Get the mechanism type that this NameElement corresponds to. * * @return the Oid of the mechanism type */ public Oid getMech() { return (Dummy.getMyOid()); } /** * Returns a string representation for this name. The printed * name type can be obtained by calling getStringNameType(). * * @return string form of this name * @see #getStringNameType() * @overrides Object#toString */ public String toString() { return (m_name); } /** * Returns the name type oid. */ public Oid getNameType() { return (m_type); } /** * Returns the oid describing the format of the printable name. * * @return the Oid for the format of the printed name */ public Oid getStringNameType() { return (m_type); } /** * Produces a copy of this object. */ public Object clone() { return null; } /** * Indicates if this name object represents an Anonymous name. */ public boolean isAnonymousName() { if (m_type.equals(GSSName.NT_ANONYMOUS)) return (true); return (false); } //instance variables private String m_name; private Oid m_type; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/samples/000077500000000000000000000000001356275373100226015ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/samples/GSSClient.java000066400000000000000000000204271356275373100252440ustar00rootroot00000000000000package com.sun.gssapi.samples; /* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ /* * Sample gss-client application. * This will inter-operate with the MIT samples. * * * GSSClient [-port port] [-mech 1.2.3.] host service msg */ import java.io.*; import java.net.*; import com.sun.gssapi.*; class GSSClient { /** * Main method for the GSSClient sample application. * This application in compatible with the MIT sample * applications (gss-server, gss-client). */ public static void main(String args[]) { String serverHost, serverName, message; int port = 4444; if (args.length < 3) { usage(); exit(1); } //set the required command line args serverHost = args[args.length - 3]; serverName = args[args.length - 2]; message = args[args.length - 1]; try { Oid mechOid = GSSManager.getDefaultMech(); //parse the command line options for (int i = 0; i < (args.length - 3); i++) { if (args[i].equals("-port")) { if (i >= (args.length - 4)) { usage(); exit(-1); } port = Integer.parseInt(args[++i]); } else if (args[i].equals("-mech")) { if (i >= (args.length-4)) { usage(); exit(-1); } mechOid = new Oid(args[++i]); } } //connect to the server s = new Socket(serverHost, port); //establish a GSSContext with server GSSContext aCtxt = createCtxt(serverName, mechOid); print("\nContext established\n"); //display context options displayContext(aCtxt); //wrap the message and send it to server sendMsgToPeer(aCtxt, message); //receiving message from server verifyMsgFromPeer(aCtxt, message); //context no longer needed aCtxt.dispose(); exit(0); } catch (IOException e) { print("\n**Communication ERROR**:\t" + e.getMessage()); e.printStackTrace(); exit(-1); } catch (GSSException e) { print("\n**GSSAPI ERROR**:\t" + e.getMessage()); e.printStackTrace(); exit(-1); } } /** * Creates a GSS-API context with the server over the specified * security mechanism. */ private static GSSContext createCtxt(String serverName, Oid mechOid) throws GSSException, IOException { GSSContext aCtxt = new GSSContext( new GSSName(serverName, GSSName.NT_HOSTBASED_SERVICE), mechOid, null, 0); //set context options aCtxt.requestConf(true); aCtxt.requestInteg(true); aCtxt.requestMutualAuth(true); aCtxt.requestReplayDet(true); aCtxt.requestSequenceDet(true); //start the context creation process DataInputStream dis = new DataInputStream(s.getInputStream()); DataOutputStream dos = new DataOutputStream(s.getOutputStream()); byte []inTok = new byte[0]; print("\nCalling init....."); do { byte[] outTok = aCtxt.init(inTok, 0, inTok.length); //send the token if present if (outTok != null) { print("\tSending token to peer (" + outTok.length + " bytes)..."); //MIT apps write length first, then token dos.writeInt(outTok.length); dos.write(outTok, 0, outTok.length); } //check if we should expect more tokens if (aCtxt.isEstablished()) break; //get input token from peer inTok = new byte[dis.readInt()]; print("\tReceiving token from peer (" + inTok.length + " bytes)..."); dis.readFully(inTok, 0, inTok.length); } while (true); return (aCtxt); } /** * Display context information/flags. */ private static void displayContext(GSSContext aCtxt) throws GSSException { //display context information print("Context Information...."); if (aCtxt.getLifetime() == GSSContext.INDEFINITE) print("\tOver mech:\t" + aCtxt.getMech().toString() + " for " + " INDEFINITE seconds"); else print("\tOver mech:\t" + aCtxt.getMech().toString() + " for " + aCtxt.getLifetime() + " seconds"); print("\tInitiator:\t" + aCtxt.getSrcName().toString()); print("\tAcceptor:\t" + aCtxt.getTargName().toString()); if (aCtxt.getDelegCredState()) print("\tDelegated credentials available."); else print("\tNO delegated credentials"); if (aCtxt.getMutualAuthState()) print("\tMutaul Authentication ON"); else print("\tNO mutual authentication performed."); if (aCtxt.getReplayDetState()) print("\tReplay detection ON"); else print("NO replay detection"); if (aCtxt.getSequenceDetState()) print("\tSequence detection ON"); else print("\tNO sequence detection"); if (aCtxt.getAnonymityState()) print("\tAnonymous context"); if (aCtxt.isTransferable()) print("\tContext is transferable"); else print("\tNO context transfer"); if (aCtxt.isProtReady()) print("\tContext protection is ready"); else print("**ERROR wrong state - context established, but isProtReady = false"); if (aCtxt.getConfState()) print("\tConfidentiality available"); else print("\tNO confidentiality services"); if (aCtxt.getIntegState()) print("\tIntegrity available"); else print("\tNO integrity services"); } /** * Sends a wraped message to the server. */ private static void sendMsgToPeer(GSSContext aCtxt, String msg) throws GSSException, IOException { print("\nWrapping message for server..."); MessageProp mInfo = new MessageProp(0, true); byte []tok = aCtxt.wrap(msg.getBytes(), 0, msg.length(), mInfo); DataOutputStream dos = new DataOutputStream(s.getOutputStream()); dos.writeInt(tok.length); dos.write(tok); dos.flush(); } /** * Checks the MIC on a message received from the server. */ private static void verifyMsgFromPeer(GSSContext aCtxt, String msg) throws GSSException, IOException { print("receiving MIC message from server..."); DataInputStream dis = new DataInputStream(s.getInputStream()); int len = dis.readInt(); print("Receiving message from peer (" + len + " bytes)"); MessageProp mInfo = new MessageProp(); aCtxt.verifyMIC(dis, new StringBufferInputStream(msg), mInfo); print("Verified server message protected with QOP = " + mInfo.getQOP()); } /** * Utility method to display application usage string. */ private static void usage() { print("GSSClient [-port port] [-mech 1.2.3.3] serverhost servername message"); } /** * Utility method to display information to the screen. */ private static void print(String msg) { System.out.println(msg); } /** * Utility method to gracefully shut down the connection and * terminate the application. */ private static void exit(int status) { if (s != null) { try { s.close(); } catch (IOException e) {}; } System.exit(status); } //private class variables private static Socket s; } yanfs-yanfs-1.4/src/main/java/com/sun/gssapi/samples/GSSServer.java000066400000000000000000000211511356275373100252670ustar00rootroot00000000000000package com.sun.gssapi.samples; /* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ /* * Sample gss-server application. * This will inter-operate with the MIT samples. * * GSSServer [-port port] [-mech 1.2.3.4.] serviceName */ import java.io.*; import java.net.*; import com.sun.gssapi.*; class GSSServer { /** * Main method to start our sample application. * This is the server end of the MIT like sample * GSS-API applications. */ public static void main(String args[]) { //default MIT port int port = 4444; if (args.length < 1) { usage(); exit(-1); } try { String serviceName = args[args.length-1]; Oid mechOid = GSSManager.getDefaultMech(); //parse the command line options for (int i = 0; i < args.length; i++) { if (args[i].equals("-port")) { if (i >= (args.length - 2)) { usage(); exit(-1); } port = Integer.parseInt(args[++i]); } else if (args[i].equals("-mech")) { if (i >= (args.length-2)) { usage(); exit(-1); } mechOid = new Oid(args[++i]); } } //acquire server credentials print("\nAcquiring credentials as " + serviceName + "..."); GSSCredential server = new GSSCredential(new GSSName(serviceName, GSSName.NT_HOSTBASED_SERVICE), GSSCredential.INDEFINITE, mechOid, GSSCredential.ACCEPT_ONLY); print("\nDumping credential info...\n" + server.toString() + "\n"); s = new ServerSocket(port); while (true) { //wait for connections print("\n\nWaiting for connections on port " + port + "..."); Socket c = s.accept(); print("Accepted connection from " + c.getInetAddress().getHostName()); processClient(server, c); } //catch all errors } catch (IOException e) { print("\n**Communication ERROR**:\t" + e.getMessage()); e.printStackTrace(); exit(-1); } catch (GSSException e) { print("\n**GSSAPI ERROR**:\t" + e.getMessage()); e.printStackTrace(); exit(-1); } } /** * Processes a client connection. * -creates a context * -displays context information * -unwraps a client token * -produces a MIC on client token * -destroy the context */ private static void processClient(GSSCredential server, Socket client) throws GSSException, IOException { //we have a client connected on the socket DataInputStream dis = new DataInputStream(new BufferedInputStream(client.getInputStream())); DataOutputStream dos = new DataOutputStream(client.getOutputStream()); print("\n\nCreating context..."); //MIT apps, first send token length int tokLen = dis.readInt(); print("\tReceiving token from peer (" + tokLen + " bytes)..."); //create acceptor GSS-API context GSSContext aCtxt = new GSSContext(server); //get first token from peer byte []inTok = new byte[tokLen]; dis.readFully(inTok, 0, inTok.length); do { byte []outTok = aCtxt.accept(inTok, 0, inTok.length); //check if we need to send token to peer if (outTok != null) { print("\tSending token to peer..."); //MIT samples write length first, then token dos.writeInt(outTok.length); dos.write(outTok); } //are we done ?? if (aCtxt.isEstablished()) break; //the mechanism expects more tokens inTok = new byte[dis.readInt()]; print("\tReceiving token from peer (" + inTok.length + " bytes)..."); dis.readFully(inTok, 0, inTok.length); } while (true); //context is ready print("\tContext is fully established"); //display context information displayContext(aCtxt); //exchange messages with peer exchangeWithPeer(aCtxt, dis, dos); //no more need for this context aCtxt.dispose(); client.close(); } /** * Displays context informations/characteristics. */ private static void displayContext(GSSContext aCtxt) throws GSSException { //display context information print("\n\nContext Information...."); if (aCtxt.getLifetime() == GSSContext.INDEFINITE) print("\tOver mech:\t" + aCtxt.getMech().toString() + " for " + " INDEFINITE seconds"); else print("\tOver mech:\t" + aCtxt.getMech().toString() + " for " + aCtxt.getLifetime() + " seconds"); print("\tInitiator:\t" + aCtxt.getSrcName().toString()); print("\tAcceptor:\t" + aCtxt.getTargName().toString()); if (aCtxt.getDelegCredState()) print("\tDelegated credentials available."); else print("\tNO delegated credentials"); if (aCtxt.getMutualAuthState()) print("\tMutaul Authentication ON"); else print("\tNO mutual authentication performed."); if (aCtxt.getReplayDetState()) print("\tReplay detraction ON"); else print("\tNO replay detection"); if (aCtxt.getSequenceDetState()) print("\tSequence detection ON"); else print("\tNO sequence detection"); if (aCtxt.getAnonymityState()) print("\tAnonymous context"); if (aCtxt.isTransferable()) print("\tContext is transferable"); else print("\tNO context transfer"); if (aCtxt.isProtReady()) print("\tContext protection is ready"); else print("**ERROR wrong state - context established, but isProtReady = false"); if (aCtxt.getConfState()) print("\tConfidentiality available"); else print("\tNO confidentiality services"); if (aCtxt.getIntegState()) print("\tIntegrity available"); else print("\tNO integrity services"); } /** * Performs exchange with client on a fully established context. */ private static void exchangeWithPeer(GSSContext aCtxt, DataInputStream dis, DataOutputStream dos) throws GSSException, IOException { /* * We have a simple exchange with the client * First it sends us a wrapped message which we * unwrap, and produce a MIC on. This is then sent * back to the client. */ print("\n\nPeer message exchange..."); int len = dis.readInt(); print("\tReceiving message from peer (" + len + " bytes)...."); ByteArrayOutputStream bos = new ByteArrayOutputStream(); MessageProp mInfo = new MessageProp(); aCtxt.unwrap(dis, bos, mInfo); print("\tMessage from peer:\t" + new String(bos.toByteArray())); mInfo.setQOP(0); mInfo.setPrivacy(false); print("\n\tSending MIC to peer."); //now perform a signature on the received data byte []peerTok = bos.toByteArray(); byte []toPeer = aCtxt.getMIC(peerTok, 0, peerTok.length, mInfo); //send token to peer dos.writeInt(toPeer.length); dos.write(toPeer); dos.close(); } /** * Display usage message. */ private static void usage() { print("\nUsage:\tGSSServert [-mech 1.2.34] [-port port] serviceName"); } /** * Utility method to display a string on the console. */ private static void print(String msg) { System.out.println(msg); } /** * Terminates the application, performing socket cleanup. */ private static void exit(int status) { if (s != null) { try { s.close(); } catch (IOException e) {}; } System.exit(status); } //private class variables private static ServerSocket s; } yanfs-yanfs-1.4/src/main/java/com/sun/http/000077500000000000000000000000001356275373100206265ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/http/XFileAccessor.java000066400000000000000000000241221356275373100241640ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.http; import com.sun.xfile.*; import java.net.URL; import java.net.URLConnection; import java.io.*; /** * The XFileAccessor interface is implemented by filesystems that * need to be accessed via the XFile API. * * @author Brent Callaghan * @version 1.0, 04/08/98 * @see com.sun.xfile.XFile */ public class XFileAccessor implements com.sun.xfile.XFileAccessor { XFile xf; URL url; URLConnection urlConn; InputStream iStream; OutputStream oStream; long fp; // file pointer /** * Open this file object * * @param xf the XFile for this file * @param serial true if serial access * @param readOnly true if read only */ public boolean open(XFile xf, boolean serial, boolean readOnly) { if (! serial) return false; this.xf = xf; try { url = new URL(xf.toString()); urlConn = url.openConnection(); urlConn.setDoInput(readOnly); urlConn.setDoOutput(! readOnly); urlConn.connect(); return true; } catch (IOException e) { return false; } } /** * Get the XFile for this Accessor * * @return XFile for this object */ public XFile getXFile() { return xf; } /** * Tests if this XFileAccessor object exists. * * @return true if the file specified by this object * exists; false otherwise. */ public boolean exists() { try { if (iStream == null) iStream = urlConn.getInputStream(); return true; } catch (IOException e) { return false; } } /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this * object; false otherwise. */ public boolean canWrite() { try { if (oStream == null) oStream = urlConn.getOutputStream(); return true; } catch (IOException e) { return false; } } /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ public boolean canRead() { return exists(); } /** * Tests if the file represented by this * object is a "normal" file. *

* A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is * guaranteed to be a normal file. * * @return true if the file specified by this * XFile object exists and is a "normal" * file; false otherwise. */ public boolean isFile() { return true; } /** * Tests if the file represented by this XFileAccessor * object is a directory. * * @return true if this XFileAccessor object * exists and is a directory; false * otherwise. */ public boolean isDirectory() { return false; } /** * Returns the time that the file represented by this * XFile object was last modified. *

* The return value is system dependent and should only be * used to compare with other values returned by last modified. * It should not be interpreted as an absolute time. * * @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ public long lastModified() { return urlConn.getLastModified(); } /** * Returns the length of the file represented by this * XFileAccessor object. * * @return the length, in bytes, of the file specified by * this object, or 0L if the specified * file does not exist. */ public long length() { long len = urlConn.getContentLength(); return len < 0 ? 0 : len; } /** * Creates a file whose pathname is specified by this * XFileAccessor object. * * @return true if the file could be created; * false otherwise. */ public boolean mkfile() { try { if (oStream == null) oStream = urlConn.getOutputStream(); return true; } catch (IOException e) { return false; } } /** * Creates a directory whose pathname is specified by this * XFileAccessor object. * * @return true if the directory could be created; * false otherwise. */ public boolean mkdir() { return false; } /** * Renames the file specified by this XFileAccessor object to * have the pathname given by the XFileAccessor object argument. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ public boolean renameTo(XFile dest) { return false; } /** * Returns a list of the files in the directory specified by * this XFileAccessor object. * * @return an array of file names in the specified directory. * This list does not include the current directory or * the parent directory ("." and * ".." on Unix systems). */ public String[] list() { return new String[0]; } /** * Deletes the file specified by this object. If the target * file to be deleted is a directory, it must be empty for * deletion to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ public boolean delete() { return false; } /** * Reads a subarray as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @return number of bytes read; -1 if EOF * @exception IOException If an I/O error has occurred. */ public int read(byte b[], int off, int len, long foff) throws IOException { int c; if (iStream == null) iStream = urlConn.getInputStream(); if (foff > fp) { iStream.skip(foff - fp); fp = foff; } c = iStream.read(b, off, len); if (c > 0) fp += c; return (c); } /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @exception IOException If an I/O error has occurred. */ public void write(byte b[], int off, int len, long foff) throws IOException { if (oStream == null) oStream = urlConn.getOutputStream(); oStream.write(b, off, len); fp += len; } /** * Forces any buffered output bytes to be written out. *

* * @exception IOException if an I/O error occurs. */ public void flush() throws IOException { if (oStream != null) oStream.flush(); } /** * Close the Streams * * @exception IOException If an I/O error has occurred. */ public void close() throws IOException { if (iStream != null) { iStream.close(); iStream = null; } if (oStream != null) { oStream.close(); oStream = null; } } /** * Returns a string representation of this object. * * @return a string giving the pathname of this object. */ public String toString() { return url.toString(); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/000077500000000000000000000000001356275373100204355ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Buffer.java000066400000000000000000000273401356275373100225170ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; /** * Here we do all the NFS read and write buffering. * * @see Nfs * @see Nfs2 * @see Nfs3 * @author Brent Callaghan */ public class Buffer extends Thread { Nfs nfs; long foffset; byte[] buf; // The buffer itself int bufoff; // Offset into the buffer int buflen; // Bytes in buffer int bufsize; // Size of buffer int minOffset; // First byte written int maxOffset; // Last byte written int status; private int action; boolean eof; IOException e; Error err; long writeVerifier; int syncType; // Various kinds of action private final static int IDLE = 0; private final static int LOAD = 1; private final static int UNLOAD = 2; private final static int EXIT = 3; /* * The initial state of a buffer is EMPTY. * When file data is read into a file it becomes LOADED. * If the buffer contains data that has not yet been written * to the file then it is DIRTY. * The COMMIT state indicates that the data is written but * not yet committed. Once committed, the state returns * to LOADED. */ final static int EMPTY = 0; // Has no data final static int LOADED = 1; // Has file data final static int DIRTY = 2; // Has new data final static int COMMIT = 3; // Not committed public Buffer(Nfs nfs, int foffset, int bufsize) { this.nfs = nfs; this.foffset = foffset; this.bufsize = bufsize; this.buflen = 0; minOffset = bufsize; maxOffset = 0; setDaemon(true); // NFS threads die when app exits try { setName("Buffer-" + (foffset / bufsize)); } catch (Exception e) {}; // non-essential, ignore action = IDLE; start(); } /* * Copy data from a buffer. * We assume the buffer is loaded with data */ synchronized int copyFrom(byte[] buff, int boff, long foffset, int length) throws IOException { /* * May have gotten an async exception * so throw it here. */ if (e != null) throw e; if (err != null) throw err; if (status == EMPTY) throw new IOException("no data"); /* * We may have a partial buffer if the file * has since been extended by a write into * another buffer that is not yet unloaded. * We must make sure that the buffer is complete. */ if (buflen < bufsize) { byte[] nbuf = new byte[bufsize]; // bigger buffer if (buflen > 0) System.arraycopy(buf, bufoff, nbuf, 0, buflen); buflen = bufsize; bufoff = 0; buf = nbuf; } int off = (int) (foffset - this.foffset); int copylen = Math.min(length, buflen - off); copylen = Math.min(copylen, (int) (nfs.length() - foffset)); System.arraycopy(buf, bufoff + off, buff, boff, copylen); return copylen; } /* * Copy data to a buffer. * If the buffer maps to a valid offset of a file then first * make sure data is loaded from the file into the buffer. * Record the range of data modified in the buffer so that * when the buffer is written only the modified range is * written back to the server. */ synchronized int copyTo(byte[] buff, int boff, long foffset, int length) throws IOException { /* * May have gotten an async exception * so throw it here. */ if (e != null) throw e; if (err != null) throw err; int off = (int) (foffset - this.foffset); int copylen = Math.min(length, bufsize - off); /* * If writing less than a full buffer and if * overwriting existing file data, then make * sure the buffer is loaded from the file. */ if (status == EMPTY) { long bufEnd = Math.min(nfs.length(), this.foffset + nfs.wsize); if (this.foffset < nfs.length() && (foffset > this.foffset || foffset + length < bufEnd)) { startLoad(); waitLoaded(); } } /* * May need to extend the size of the buffer */ if (off + copylen > buflen) { byte[] nbuf = new byte[bufsize]; if (buf != null) System.arraycopy(buf, bufoff, nbuf, 0, buflen); buf = nbuf; bufoff = 0; buflen = bufsize; } System.arraycopy(buff, boff, buf, bufoff + off, copylen); status = DIRTY; /* * Record the range of the buffer that's been * modified so that we can write less than * the full buffer if possible. */ if (off < minOffset) minOffset = off; if (off + copylen > maxOffset) maxOffset = off + copylen; return copylen; } /* * Notify the buffer thread that it is to read data */ synchronized void startLoad() { action = LOAD; notifyAll(); } /* * Wait until the buffer thread has finished loading the buffer */ synchronized void waitLoaded() throws IOException { /* * Check for an exception thrown by the async thread * in case the thread died and we block forever * waiting for the buffer state to change. */ if (e != null) throw e; if (err != null) throw err; while (this.status == EMPTY) { try { wait(); } catch (InterruptedException e) {} if (this.e != null) throw this.e; if (err != null) throw err; } } /* * Wait until the buffer thread is finished writing the buffer */ synchronized void waitUnloaded() throws IOException { /* * Check in case async thread threw an * exception and died. */ if (e != null) throw e; if (err != null) throw err; while (action == UNLOAD) { try { wait(); } catch (InterruptedException e) {} if (this.e != null) throw this.e; if (err != null) throw err; } } /* * Notify the buffer thread that it is to write data */ synchronized void startUnload(int sync) { nfs.beginWrite(); action = UNLOAD; syncType = sync; notifyAll(); } /* * Request the buffer thread to exit cleanly */ synchronized void exit() { action = EXIT; notifyAll(); } /* * This is the run method for the buffer thread. * It is started when the buffer is instantiated * and sleeps on the monitor waiting to be woken * up and perform one of two actions: LOAD data * (write) or UNLOAD data (read). */ public void run() { synchronized (this) { try { while (true) { while (action == IDLE) { try { wait(); } catch (InterruptedException e) {} } /* * Thread has been notified - perform the action */ switch (action) { case LOAD: try { nfs.read_otw(this); } catch (IOException e) { if (this.e == null) this.e = e; } status = LOADED; break; case UNLOAD: try { /* * Server may do a short write, so keep * writing until all the bytes have been * written. */ int saveMin = minOffset; while (minOffset < maxOffset) minOffset += nfs.write_otw(this); minOffset = bufsize; maxOffset = 0; } catch (IOException e) { if (this.e == null) this.e = e; } nfs.endWrite(); break; case EXIT: notifyAll(); /* * XXX Dereferencing the buf here should not be * necessary since the entire buffer is dereferenced * from the bufferList in Nfs, however for some reason * the GC is ignoring dereferenced buffers. * Setting buf to null makes sure that the GC collects * the bulk of the memory tied up in a buffer, even * if the Buffer object itself is not reclaimed. */ buf = null; return; } action = IDLE; notifyAll(); } } catch (Error e) { /* * Need to catch errors here, e.g. OutOfMemoryError * and notify threads before this thread dies * otherwise they'll wait forever. */ err = e; notifyAll(); throw e; } } } public String toString() { return (nfs.name + " @ " + foffset + " for " + buflen); } // protected void finalize() throws Throwable { // System.out.println("#### BUFFER FINALIZE " + toString()); // super.finalize(); // } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Fattr.java000066400000000000000000000062011356275373100223570ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import com.sun.rpc.*; /** * * NFS file attributes * * This is essentially a container class that holds * the attributes, but it also has methods to encode * and decode the attributes in an Xdr buffer. * * Note that the time at which the attributes were * retrieved is automatically updated and the cache * time varies according to the frequency of file * modification. * * There are two subclasses: Fattr2 for NFS v2 * attributes and Fattr3 for v3. * * @see Nfs * @see Fattr2 * @see Fattr3 * @author Brent Callaghan */ public abstract class Fattr { long validtime; // time when attrs were new long cachetime; // max cache duration in ms static final int ACMIN = 3 * 1000; // 3 sec - min cache time static final int ACMAX = 60 * 1000; // 1 min - max cache time static final int NOBODY = 60001; // Svr4 UID/GID "nobody" static final int NFS_NOBODY = -2; // NFS UID/GID "nobody" /** * Check if the attributes are "fresh" enough. * * If not, then the caller will likely update * the attributes with an NFS getattr request. * * @returns true if the attributes are valid */ boolean valid() { long timenow = System.currentTimeMillis(); return (timenow <= validtime + cachetime); } abstract void putFattr(Xdr x); abstract void getFattr(Xdr x); } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Fattr2.java000066400000000000000000000113641356275373100224470ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; import java.util.Date; /** * * NFS version 2 file attributes * */ class Fattr2 extends Fattr { int ftype; long mode; long nlink; long uid; long gid; long size; long blocksz; long rdev; long blocks; long fsid; long fileid; long atime; long mtime; long ctime; Fattr2() { } Fattr2 (Xdr x) { this.getFattr(x); } void putFattr(Xdr x) { x.xdr_int(ftype); x.xdr_u_int(mode); x.xdr_u_int(nlink); x.xdr_u_int(uid); x.xdr_u_int(gid); x.xdr_u_int(size); x.xdr_u_int(blocksz); x.xdr_u_int(rdev); x.xdr_u_int(blocks); x.xdr_u_int(fsid); x.xdr_u_int(fileid); x.xdr_u_int(atime / 1000); // sec x.xdr_u_int(atime % 1000); // msec x.xdr_u_int(mtime / 1000); // sec x.xdr_u_int(mtime % 1000); // msec x.xdr_u_int(ctime / 1000); // sec x.xdr_u_int(ctime % 1000); // msec } void getFattr(Xdr x) { long oldmtime = mtime; ftype = x.xdr_int(); mode = x.xdr_u_int(); nlink = x.xdr_u_int(); uid = x.xdr_u_int(); if (uid == NFS_NOBODY) uid = NOBODY; gid = x.xdr_u_int(); if (gid == NFS_NOBODY) gid = NOBODY; size = x.xdr_u_int(); blocksz = x.xdr_u_int(); rdev = x.xdr_u_int(); blocks = x.xdr_u_int(); fsid = x.xdr_u_int(); fileid = x.xdr_u_int(); atime = x.xdr_u_int() * 1000 + x.xdr_u_int(); mtime = x.xdr_u_int() * 1000 + x.xdr_u_int(); ctime = x.xdr_u_int() * 1000 + x.xdr_u_int(); /* * We want the cache time to be short * for files/dirs that change frequently * and long for files/dirs that change * infrequently. So set the cache time to * the delta between file modifications * limited by ACMIN and ACMAX */ long delta = mtime - oldmtime; if (delta > 0) { cachetime = delta; if (cachetime < ACMIN) cachetime = ACMIN; else if (cachetime > ACMAX) cachetime = ACMAX; } validtime = System.currentTimeMillis(); } public String toString() { return ( " ftype = " + ftype + "\n" + " mode = 0" + Long.toOctalString(mode) + "\n" + " nlink = " + nlink + "\n" + " uid = " + uid + "\n" + " gid = " + gid + "\n" + " size = " + size + "\n" + "blocksz = " + blocksz + "\n" + " rdev = 0x" + Long.toHexString(rdev) + "\n" + " blocks = " + blocks + "\n" + " fsid = " + fsid + "\n" + " fileid = " + fileid + "\n" + " atime = " + new Date(atime) + "\n" + " mtime = " + new Date(mtime) + "\n" + " ctime = " + new Date(ctime) ); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Fattr3.java000066400000000000000000000112251356275373100224440ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; import java.util.Date; /** * * NFS version 3 file attributes * */ class Fattr3 extends Fattr { int ftype; long mode; long nlink; long uid; long gid; long size; long used; long rdev; long fsid; long fileid; long atime; long mtime; long ctime; Fattr3() { } Fattr3(Xdr x) { this.getFattr(x); } void putFattr(Xdr x) { x.xdr_int(ftype); x.xdr_u_int(mode); x.xdr_u_int(nlink); x.xdr_u_int(uid); x.xdr_u_int(gid); x.xdr_hyper(size); x.xdr_hyper(used); x.xdr_hyper(rdev); x.xdr_hyper(fsid); x.xdr_hyper(fileid); x.xdr_u_int(atime / 1000); // sec x.xdr_u_int(atime % 1000 * 1000000); // nsec x.xdr_u_int(mtime / 1000); // sec x.xdr_u_int(mtime % 1000 * 1000000); // nsec x.xdr_u_int(ctime / 1000); // sec x.xdr_u_int(ctime % 1000 * 1000000); // nsec } void getFattr(Xdr x) { long oldmtime = mtime; ftype = x.xdr_int(); mode = x.xdr_u_int(); nlink = x.xdr_u_int(); uid = x.xdr_u_int(); if (uid == NFS_NOBODY) uid = NOBODY; gid = x.xdr_u_int(); if (gid == NFS_NOBODY) gid = NOBODY; size = x.xdr_hyper(); used = x.xdr_hyper(); rdev = x.xdr_hyper(); fsid = x.xdr_hyper(); fileid = x.xdr_hyper(); atime = x.xdr_u_int() * 1000 + x.xdr_u_int() / 1000000; mtime = x.xdr_u_int() * 1000 + x.xdr_u_int() / 1000000; ctime = x.xdr_u_int() * 1000 + x.xdr_u_int() / 1000000; /* * We want the cache time to be short * for files/dirs that change frequently * and long for files/dirs that change * infrequently. So set the cache time to * the delta between file modifications * limited by ACMIN and ACMAX */ long delta = mtime - oldmtime; if (delta > 0) { cachetime = delta; if (cachetime < ACMIN) cachetime = ACMIN; else if (cachetime > ACMAX) cachetime = ACMAX; } validtime = System.currentTimeMillis(); } public String toString() { return ( " ftype = " + ftype + "\n" + " mode = 0" + Long.toOctalString(mode) + "\n" + " nlink = " + nlink + "\n" + " uid = " + uid + "\n" + " gid = " + gid + "\n" + " size = " + size + "\n" + " used = " + used + "\n" + " rdev = 0x" + Long.toHexString(rdev) + "\n" + " fsid = " + fsid + "\n" + "fileid = " + fileid + "\n" + " atime = " + new Date(atime) + "\n" + " mtime = " + new Date(mtime) + "\n" + " ctime = " + new Date(ctime) ); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Mount.java000066400000000000000000000153041356275373100224050ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; /** * Handle the mount protocol for NFS versions 2 and 3 * * Note that we transmit an unmount request immediately * after a successful mount request. This avoids having * "mount" entries pile up in the server's /etc/rmtab log. * * @see Nfs * @author Brent Callaghan */ class Mount { private final static int MOUNTPROG = 100005; private final static int MOUNTPROC_MNT = 1; private final static int MOUNTPROC_UMNT = 3; private final static int MOUNTPROC_EXPORT = 5; private final static int FHSIZE = 32; private final static int FHSIZE3 = 64; private final static int ENOENT = 2; private final static int EACCES = 13; String sec_flavor; /** * Get an NFS v2 or v3 file handle * * @param server The NFS server * @param path The file path on the server * @param vers The NFS version * @returns The filehandle as a byte array */ byte[] getFH(String server, String path, int vers) throws java.net.UnknownHostException, IOException { Rpc mnt; Xdr callmsg = new Xdr(1024); int status; byte[] fh; // Use Mount v1 for NFS v2, Mount v3 for NFS v3 mnt = new Rpc(server, 0, MOUNTPROG, vers == 2 ? 1 : 3, "udp", 512); mnt.setCred(new CredUnix(0, 0)); mnt.rpc_header(callmsg, MOUNTPROC_MNT); callmsg.xdr_string(path); Xdr replymsg = mnt.rpc_call(callmsg, 3 * 1000, 3); status = replymsg.xdr_int(); if (status != 0) { /* * If ENOENT is returned and the path didn't * start with a slash then assume it's because * the URL didn't include it (a common mistake). * Add the slash and try again. */ if ((status == ENOENT || status == EACCES) && ! path.startsWith("/")) return getFH(server, "/" + path, vers); throw new IOException("Mount status: " + status); } // Filehandle is different depending on version fh = vers == 2 ? replymsg.xdr_raw(FHSIZE) : replymsg.xdr_bytes(); // Get security flavors if this is MOUNT V3. sec_flavor = null; if (vers == 3) { int numsec = replymsg.xdr_int(); String prefer = NfsSecurity.getPrefer(); while (numsec-- > 0) { String secmode = Integer.toString(replymsg.xdr_int()); if ((prefer != null) && prefer.equals(secmode)) { sec_flavor = prefer; } if ((sec_flavor == null) && NfsSecurity.hasValue(secmode)) { sec_flavor = secmode; } } // while } if (sec_flavor == null) { sec_flavor = NfsSecurity.getDefault(); } /* * Now send an unmount request */ mnt.rpc_header(callmsg, MOUNTPROC_UMNT); callmsg.xdr_string(path); try { mnt.rpc_call(callmsg, 1000, 1); } catch (InterruptedIOException e) { // ignore } return (fh); } /* * get the sec_flavor after a successful getMountInfo() */ String getSec() { return (sec_flavor); } /* * Get the server's export list * */ static String[] getExports(String server) throws java.net.UnknownHostException, IOException { Rpc mnt; Xdr callmsg = new Xdr(255); Xdr replymsg; String[] elist = new String[32]; int i = 0; try { mnt = new Rpc(server, 0, MOUNTPROG, 1, "tcp", 8192); mnt.setCred(new CredUnix(0, 0)); mnt.rpc_header(callmsg, MOUNTPROC_EXPORT); // This RPC proc takes no arguments replymsg = mnt.rpc_call(callmsg, 3 * 1000, 3); } catch (java.net.UnknownHostException e) { throw e; } catch (IOException e) { return new String[0]; // an empty export list } /* * The exports come back as a linked list. * Walk along the list extracting the export names * into an array and ignore the associated groups list. */ while (replymsg.xdr_bool()) { elist[i++] = replymsg.xdr_string(); if (i >= elist.length) { // last elem in array ? String[] tmp = elist; elist = new String[i*2]; // double its size System.arraycopy(tmp, 0, elist, 0, i); } /* * Skip the groups list */ while (replymsg.xdr_bool()) { replymsg.xdr_string(); } } /* * Trim export list to exact size */ if (i < elist.length) { String[] tmp = elist; elist = new String[i]; System.arraycopy(tmp, 0, elist, 0, i); } return elist; } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Nfs.java000066400000000000000000000545521356275373100220410ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; import java.util.Hashtable; import java.util.Vector; /** * * Container class for an NFS object: either a file * or a directory. Herein are common * methods that are not version specific. * * This class holds the file's filehandle, name, * and attributes. If a regular file then data may * be cached in an XDR buffer. If a directory then * the string array for the entries will be cached. * There's also a static hash table that's used to cache * these Nfs objects. * * @see Nfs2 * @see Nfs3 * @see Buffer * @author Brent Callaghan * @author Ricardo Labiaga */ public abstract class Nfs { byte[] fh; Rpc rpc; String name; String[] dircache; String symlink; Buffer[] bufferList; long cacheTime; // Time when object was cached int rsize, wsize; private Object wbLock = new Object(); // write-behind semaphore lock static Hashtable cacheNfs = new Hashtable(); // Some of the filetypes we're dealing with. static final int NFREG = 1; static final int NFDIR = 2; static final int NFLNK = 5; // Flags for asynchronous or synchronous writes private final static int ASYNC = 0; private final static int SYNC = 2; int NRA; // max reads-ahead (set in subclass constructor) int NWB; // max writes-behind (") int NWC; // max writes committed (") int nwb; // current writes-behind int prevReadIndex = -1; // Buffer index of previous read int prevWriteIndex = -1; // Buffer index of previous write int maxIndexRead = 0; // Max file offset read long maxLength = 0; // Size of file // Some important permission bits static final int RBIT = 004; static final int WBIT = 002; /* * The following abstract classes are version-specific * and are implemented in the version subclasses. */ abstract void checkAttr() throws IOException; abstract boolean cacheOK(long t) throws IOException; abstract void getattr() throws IOException; abstract long mtime() throws IOException; abstract long length() throws IOException; abstract boolean exists() throws IOException; abstract boolean canWrite() throws IOException; abstract boolean canRead() throws IOException; abstract boolean isFile() throws IOException; abstract boolean isDirectory() throws IOException; abstract boolean isSymlink() throws IOException; abstract Fattr getAttr() throws IOException; abstract Nfs lookup(String path) throws IOException; abstract String lookupSec() throws IOException; abstract void read_otw(Buffer b) throws IOException; abstract int write_otw(Buffer buf) throws IOException; abstract String[] readdir() throws IOException; abstract String readlink() throws IOException; abstract Nfs create(String name, long mode) throws IOException; abstract Nfs mkdir(String name, long mode) throws IOException; abstract boolean remove(String name) throws IOException; abstract boolean rename(Nfs dstP, String sName, String dName) throws IOException; abstract boolean rmdir(String name) throws IOException; abstract void fsinfo() throws IOException; abstract long commit(int foffset, int length) throws IOException; abstract void invalidate(); /* * The following methods are all NFS version independent. */ /* * Get FileHandle for Nfs Object */ byte[] getFH() { return (fh); } /* * Cache an Nfs object * * @param n the object to be cached */ static void cache_put(Nfs n) { cacheNfs.put(n.rpc.conn.server + ":" + n.name, n); } /* * Retrieve a cached Nfs object * * @param server The server that hosts the object * @param name The pathname of the object * @returns The object - or null if not cached */ static Nfs cache_get(String server, String name) { return ((Nfs)cacheNfs.get(server + ":" + name)); } /* * Remove an Nfs object from the cache * * @param n the object to be removed from cache */ static void cache_remove(Nfs n, String name) { if (n.name.equals(".")) cacheNfs.remove(n.rpc.conn.server + ":" + name); else cacheNfs.remove(n.rpc.conn.server + ":" + n.name + "/" + name); } /** * Read data from the specified file offset * * @param buf The destination buffer * @param boff Offset into the dest buffer * @param length Amount of data to read * @param foffset File offset to begin reading * @exception java.io.IOException * @return actual bytes read */ synchronized int read(byte[] buf, int boff, int length, long foffset) throws IOException { Buffer b = null; int index; int readAhead = 0; int bytesRead = 0; /* * If the file modification time has changed since * the last read then invalidate all cached buffers. */ if (!cacheOK(cacheTime) && bufferList != null) { for (int i = 0; i < bufferList.length; i++) if (i != prevWriteIndex) // don't delete dirty buffers bufferList[i] = null; prevReadIndex = -1; } /* * Check whether we're at EOF */ if (foffset >= length()) return -1; /* * Keep reading until the read request is satisfied. */ while (length > 0) { /* * Check whether we're at EOF */ if (foffset >= length()) break; /* * Make sure an array of buffers exists that's big enough * to for the entire file. */ if (bufferList == null) bufferList = new Buffer[(int) length() / rsize + 1]; /* * Find the block that holds the data */ index = (int) foffset / rsize; if (index > maxIndexRead) maxIndexRead = index; /* * Make sure that previously read buffers are * released. If not, then reading a large file * would quickly run the app out of memory, though * must be careful not to release in-use write buffers. * XXX We should find a way to make better use of * available memory and keep file buffers cached. */ if (index != prevReadIndex) { if (prevReadIndex >= 0 && prevReadIndex != prevWriteIndex) { b = bufferList[prevReadIndex]; if (b.status == b.LOADED) { bufferList[prevReadIndex] = null; b.exit(); } /* * Do read-ahead only for sequential I/O */ if (index == (prevReadIndex + 1) && index >= maxIndexRead) readAhead = NRA; } prevReadIndex = index; } /* * Make sure that the buffer is * are loaded or loading - as well as * any buffers that will likely be needed * i.e. read-ahead buffers. */ for (int n = index; n <= index + readAhead; n++) { if (n >= bufferList.length) break; b = bufferList[n]; if (b == null) { b = new Buffer(this, n * rsize, rsize); b.startLoad(); bufferList[n] = b; } } /* * Now select the buffer and wait until its not busy. */ b = bufferList[index]; try { b.waitLoaded(); } catch (NfsException n) { /* * Check if it's a bogus "EBADRPC" * error from a Digital Unix server. * It implies that the read was too * long. The server should just return * a short read - but until they fix it * we'll handle it here. * Optimistically set the read * size to 8k and try again. */ if (n.error == 72) { // DEC's EBADRPC rsize = 8192; bufferList = new Buffer[(int) length() / rsize + 1]; continue; } throw n; } /* * If the buffer contains less data than requested * and it's not EOF, then assume that we guessed * too big for the server's transfer size. */ int bufflen = b.buflen; if (bufflen < rsize && !b.eof) { rsize = bufflen; bufferList = null; prevReadIndex = -1; prevWriteIndex = -1; continue; // Try again with new rsize } /* * Copy data from the file buffer into the application buffer. */ int cc = b.copyFrom(buf, boff, foffset, length); boff += cc; foffset += cc; length -= cc; bytesRead += cc; } return (bytesRead); } /* * These two methods implement a semaphore to prevent the client from * generating an huge number of write-behind threads that could * overload the server. * * These methods synchronize on wbLock rather than the * class monitor otherwise there's a risk of deadlock * through Nfs.write() -> Buffer.startUnload() -> Nfs.beginWrite() */ void beginWrite() { synchronized (wbLock) { while (nwb >= NWB) { try { wbLock.wait(); } catch (InterruptedException e) {} } nwb++; } } void endWrite() { synchronized (wbLock) { nwb--; wbLock.notify(); } } /** * Write data to a file at a specified offset. * * @param buf The data to write * @param boff Offset into the data buffer * @param length Amount of data to write * @param foffset File offset to begin writing at * @exception java.io.IOException */ synchronized void write(byte buf[], int boff, int length, long foffset) throws IOException { /* * If the write size is not set then call FSINFO * to set it. We would prefer not to make this call * since it adds an extra turnaround, but the alternative * is to guess at the write size by trying a large write * and see how many bytes the server writes. If we're doing * async write-behind it'll take complex code to recover * from a series of partial writes that would wreak havoc with * any write gathering that the server might be doing. So * it's likely safer just to have the server tell us its * preferred write size as the protocol intended. */ if (wsize == 0) fsinfo(); /* * If we haven't read the file yet then there may * be no buffer list. Allocate one that will hold * all of the existing file blocks, or if it's a newly * created file, assume an initial size of 50 blocks. */ if (bufferList == null) { long fileSize = Math.max(length(), 50 * wsize); bufferList = new Buffer[(int) fileSize / wsize + 1]; } /* * Keep writing data to the server in buffer-size chunks * until the write request is satisfied. If the write * is a short one into an existing buffer then no data * will be written at all. This is good, it's much more * efficient to write larger amounts of data to the server. * * We get further improvement in write throughput by writing * buffers asynchronously in a buffer thread. This allows the * application to continue filling a new buffer while previous * buffers are written. * * This method takes advantage of the ability of NFS version 3 * to perform safe, asynchronous writes which significantly * increase write throughput. */ while (length > 0) { int index = (int) foffset / wsize; /* * If writing into a new buffer * start writing out the previous one. */ if (index != prevWriteIndex) { if (prevWriteIndex >= 0) { bufferList[prevWriteIndex].startUnload(ASYNC); checkCommit(false); } prevWriteIndex = index; } /* * If trying to write to a buffer off the end of * the current buffer list, then double the size * of the buffer list. */ if (index >= bufferList.length) { Buffer[] tlist = new Buffer[bufferList.length * 2]; for (int i = 0; i < bufferList.length; i++) tlist[i] = bufferList[i]; bufferList = tlist; } /* * Check if there's a buffer allocated */ Buffer b = bufferList[index]; if (b == null) { b = new Buffer(this, index * wsize, wsize); bufferList[index] = b; } /* * Copy data from the application buffer to the file buffer. */ int cc = b.copyTo(buf, boff, foffset, length); boff += cc; foffset += cc; length -= cc; /* * Need to record max file offset here in case * the app calls length() before the data has * been written out and recorded in the file attrs. */ if (foffset > maxLength) maxLength = foffset; } // end while } /* * Check the buffer list for buffers that should be released. * Buffers must be released otherwise the entire file will * become cached and we risk running out of memory. * * The same scan also checks for buffers that are pending * commit. If it's a v2 server then there will be none, * but if v3 and there are more than NWC of these then * send a COMMIT request. Until these buffers are committed * they cannot be released. The scan records the range of * buffers pending commit for the benefit of the COMMIT * request which requires an offset and range. * * This method is called with flushing set to true when * the file is being closed. In this case the code must * write the current buffer and wait for all write operations * to complete. */ void checkCommit(boolean flushing) throws IOException { int minIndex = Integer.MAX_VALUE; int maxIndex = 0; int nwc = 0; /* * Determine the first and last buffers in * the buffer list that are waiting commit. * Then we know the byte range to be committed. * * Also, release any LOADED buffers. */ for (int i = 0; i < bufferList.length; i++) { Buffer b = bufferList[i]; if (b != null) { if (flushing) b.waitUnloaded(); if (b.status == b.LOADED) { /* * Don't throw away the "current" buffer */ if (i == prevReadIndex || i == prevWriteIndex) continue; bufferList[i] = null; b.exit(); } else if (b.status == b.COMMIT) { nwc++; if (i < minIndex) minIndex = i; if (i > maxIndex) maxIndex = i; } } } /* * If flushing write the "current" buffer if it is dirty. * Here we catch writes to files no bigger than one * buffer. It's better to do a single sync write than * do an async write followed by a commit for a single * buffer. */ if (flushing) { Buffer b = bufferList[prevWriteIndex]; if (b != null) { if (b.status == b.DIRTY) { if (nwc == 0) { // just one - do it sync b.startUnload(SYNC); b.waitUnloaded(); } else { // more than one - do it async b.startUnload(ASYNC); b.waitUnloaded(); // Record the commit range if (prevWriteIndex < minIndex) minIndex = prevWriteIndex; if (prevWriteIndex > maxIndex) maxIndex = prevWriteIndex; } } } } /* * If writing to a v3 server then there may * be some buffers pending commit. * If the commit is successful the buffers can * be released. */ if (nwc > 0 && (flushing || nwc >= NWC)) { int commitOffset = minIndex * rsize + bufferList[minIndex].minOffset; int commitLength = (maxIndex * rsize + bufferList[maxIndex].maxOffset) - commitOffset; long verf = commit(commitOffset, commitLength); /* * Check the write verifiers of the buffers * in the commit range. If each verifier * matches then the buffer data are safe * and we can release the buffer. * If the verifier does not match its possible * that the server lost the data so rewrite * the buffer. */ for (int i = minIndex; i <= maxIndex; i++) { Buffer b = bufferList[i]; if (b == null) continue; if (flushing) b.waitUnloaded(); if (b.status == b.COMMIT) { /* * Can now release committed buffers with * matching verifiers iff they're not "current" */ if (b.writeVerifier == verf) { if (i == prevReadIndex || i == prevWriteIndex) { b.status = b.LOADED; continue; } bufferList[i] = null; // release buffer b.exit(); } else { /* * Have to rewrite. * * If flushing then do sync-writes because * we can't return until the data are safe. * Otherwise, we just fire off another async * write and have it committed later. */ if (flushing) { b.startUnload(SYNC); b.waitUnloaded(); } else { b.startUnload(ASYNC); } } } } // end for } } /** * Flush any buffered writes to the file. This must be * called after any series of writes to guarantee that the * data reach the server. * @exception java.io.IOException if writes failed for some reason, e.g. * if server ran out of disk space. */ synchronized public void flush() throws IOException { if (prevWriteIndex >= 0) // if no writes then don't bother checkCommit(true); } /** * Close the file by flushing data and * deallocating buffers. * @exception java.io.IOException if failure during flushing. */ synchronized public void close() throws IOException { int n = 0; if (bufferList == null) return; flush(); // unwritten data for (int i = 0; i < bufferList.length; i++) { if (bufferList[i] != null) { Buffer b = bufferList[i]; bufferList[i] = null; b.exit(); } } prevReadIndex = -1; prevWriteIndex = -1; } /* * Make sure that pending writes are flushed if the app * neglected to call flush(). */ protected void finalize() throws Throwable { close(); super.finalize(); } public String toString() { try { if (isSymlink()) { if (symlink != null) return "\"" + name + "\": symlink -> \"" + symlink + "\""; else return "\"" + name + "\": symlink"; } if (isDirectory()) { String s = "\":" + name + "\" directory"; if (dircache != null) return s + "(" + dircache.length + " entries)"; else return s; } // Must be a regular file return "\"" + name + "\": file (" + length() + " bytes)"; } catch (IOException e) { return e.getMessage(); } } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Nfs2.java000066400000000000000000000557071356275373100221260ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; /** * This class contains the methods specific to * NFS version 2. * * @see Nfs * @see Nfs3 * @see Fattr * @author Brent Callaghan * @author Ricardo Labiaga */ public class Nfs2 extends Nfs { Fattr2 attr; /* * NFS version 2 procedure numbers */ private final static int NFSPROC2_NULL = 0; private final static int NFSPROC2_GETATTR = 1; private final static int NFSPROC2_SETATTR = 2; private final static int NFSPROC2_LOOKUP = 4; private final static int NFSPROC2_READLINK = 5; private final static int NFSPROC2_READ = 6; private final static int NFSPROC2_WRITE = 8; private final static int NFSPROC2_CREATE = 9; private final static int NFSPROC2_REMOVE = 10; private final static int NFSPROC2_RENAME = 11; private final static int NFSPROC2_LINK = 12; private final static int NFSPROC2_SYMLINK = 13; private final static int NFSPROC2_MKDIR = 14; private final static int NFSPROC2_RMDIR = 15; private final static int NFSPROC2_READDIR = 16; private final static int NFSPROC2_STATFS = 17; private final static int NFS_OK = 0; private final static int RWSIZE = 8192; // optimal read/write size private final static int FHSIZE = 32; // file handle size int nwb; // current writes-behind /** * Construct a new NFS version 2 object (file or directory) * * @param rpc Rpc object for the server * @param fh File handle for the object * @param name Name of the file/dir * @param attr File attributes for the object */ public Nfs2(Rpc rpc, byte[] fh, String name, Fattr2 attr) { this.rpc = rpc; this.fh = fh; if (name.startsWith("./")) // normalize for cache lookup name = name.substring(2); this.name = name; this.attr = attr == null ? new Fattr2() : attr; this.rsize = RWSIZE; NRA = 2; // Max reads-ahead NWB = 8; // Max writes-behind } void getattr() throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC2_GETATTR); call.xdr_raw(fh); Xdr reply; try { reply = rpc.rpc_call(call, 2 * 1000, 2); } catch (IOException e) { // don't let a mere getattr hang // the app if the server is down. return; } int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); attr.getFattr(reply); } void checkAttr() throws IOException { if (! attr.valid()) getattr(); } boolean cacheOK(long t) throws IOException { checkAttr(); return t == attr.mtime; } void invalidate() { attr.validtime = 0; } /* * Get the file modification time * @return the time in milliseconds */ long mtime() throws IOException { checkAttr(); return attr.mtime; } /* * Get the file size in bytes. * * Note that the size may be greater than that * shown in the attributes if the file is being written. * * @return file size */ long length() throws IOException { checkAttr(); return maxLength > attr.size ? maxLength : attr.size; } /* * Verify if file exists * @return true if file exists */ boolean exists() throws IOException { checkAttr(); return true; } private boolean check_access(long mode) { boolean found = false; long uid = NfsConnect.getCred().getUid(); long gid = NfsConnect.getCred().getGid(); int gids[] = NfsConnect.getCred().getGids(); /* * Access check is based on only * one of owner, group, public. * If not owner, then check group. * If not a member of the group, * then check public access. */ mode <<= 6; if (uid != attr.uid) { mode >>= 3; if (gid != attr.gid) { // check group list int gidsLength = 0; if (gids != null) gidsLength = gids.length; for (int i = 0; i < gidsLength; i++) if (found = ((long)gids[i] == attr.gid)) break; if (!found) { // not in group list, check "other" field mode >>= 3; } } } return (attr.mode & mode) == mode; } /* * Verify if file can be created/updated * @return true if file can be created/updated */ boolean canWrite() throws IOException { checkAttr(); return check_access(WBIT); } /* * Verify if file can be read * @return true if file can be read */ boolean canRead() throws IOException { checkAttr(); return check_access(RBIT); } /* * Verify if this is a file * @return true if a file */ boolean isFile() throws IOException { checkAttr(); return attr.ftype == NFREG; } /* * Verify if this is a directory * @return true if a directory */ boolean isDirectory() throws IOException { checkAttr(); return attr.ftype == NFDIR; } /* * Verify if this is a symbolic link * @return true if a symbolic link */ boolean isSymlink() throws IOException { checkAttr(); return attr.ftype == NFLNK; } /* * @return file attributes */ Fattr getAttr() throws IOException { checkAttr(); return (Fattr)attr; } /* * Lookup a name in a directory * * If its a symbolic link - follow it * * @param name Name of entry in directory * @returns Nfs object * @exception java.io.IOException */ Nfs lookup(String name) throws IOException { byte[] newfh; Fattr2 newattrs; Nfs nfs; String pathname; /* For multi-component lookup, the name would already be * filled in when object is created and * thus name passed in will be null. */ if (name == null) { pathname = this.name; name = this.name; } else { /* Single component case */ if (this.name == null) pathname = name; else pathname = this.name + "/" + name; } /* * First check the cache to see * if we already have this file/dir */ nfs = cache_get(rpc.conn.server, pathname); if (nfs != null && nfs.cacheOK(cacheTime)) { // If a symbolic link then follow it if (((Nfs2)nfs).attr.ftype == NFLNK) nfs = NfsConnect.followLink(nfs); return nfs; } Xdr call = new Xdr(rsize + 512); Xdr reply = null; /* * If needed, give one try to get the security information * from the server. */ for (int sec_tries = 1; sec_tries >= 0; sec_tries--) { rpc.rpc_header(call, NFSPROC2_LOOKUP); call.xdr_raw(fh); call.xdr_string(name); try { reply = rpc.rpc_call(call, 5 * 1000, 0); break; } catch (MsgRejectedException e) { /* * Check if this lookup is using public fh. * If so and if the call receives an AUTH_TOOWEAK error, * lookupSec() is called to get the security flavor * information from the server by using the WebNFS * security negotiation protocol (supported in Solaris 8). */ boolean is_v2pubfh = true; for (int i = 0; i < 32; i++) { if (fh[i] != (byte) 0) { is_v2pubfh = false; break; } } if (is_v2pubfh && e.why == MsgRejectedException.AUTH_TOOWEAK) { String secKey = lookupSec(); if (secKey != null && NfsSecurity.getMech(secKey) != null) { rpc.setCred(new CredGss("nfs", NfsSecurity.getMech(secKey), NfsSecurity.getService(secKey), NfsSecurity.getQop(secKey))); continue; } else if (secKey != null && secKey.equals("1")) { rpc.setCred(new CredUnix()); continue; } } throw e; } catch (IOException e) { throw e; } } // for int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); newfh = reply.xdr_raw(FHSIZE); newattrs = new Fattr2(reply); nfs = new Nfs2(rpc, newfh, pathname, newattrs); cache_put(nfs); // If a symbolic link then follow it if (((Nfs2)nfs).attr.ftype == NFLNK) nfs = NfsConnect.followLink(nfs); return nfs; } /* * lookupSec() uses the WebNFS security negotiation protocol to * get nfs flavor numbers required by the nfs server. * * If the server fails to return the security numbers, the client * will use a default security mode specified in the * nfssec.properties file. * * If the server successfully returns a list of security modes, * the client will use the preferred security mode that matches * any security number found in the list, otherwise, it * will use the first security number from the list that the * client supports. * * Null string is returned if the client does not support any * security numbers that the server requests. * * Here is an example of the WebNFS security negotiation protocol: * * Suppose the server shares /export/home as follows: * * share -o sec=sec_1:sec_2:sec_3 /export/secure * * Here is how to READ a file from server:/export/secure: * * Client Server * ------ ------ * * LOOKUP 0x0, foo, "path" * -----------> * <----------- * AUTH_TOOWEAK * * LOOKUP 0x0, foo, 0x81, , "path" * -----------> * <----------- * FH = {...,sec_1, ..., sec_3} * LOOKUP 0x0, foo, "path" * use a selected sec flavor (sec_x) * -----------> * <----------- * FH = 0x01 * READ 0x01, sec_x, offset=0 for 32k * -----------> * <----------- * * Here is the contents of the FH returned from the server for the * "0x81" V2 LOOKUP request: * * 1 2 3 4 32 * +---+---+---+---+---+---+---+---+ +---+---+---+---+ +---+ * | l | s | | | sec_1 |...| sec_n |...| | * +---+---+---+---+---+---+---+---+ +---+---+---+---+ +---+ * * where l is the length : 4 * n (bytes) * s is status indicating whether there are more sec flavors * (1 is yes, 0 is no) that require the client to perform * another 0x81 LOOKUP request. Client uses * to indicate the offset of the flavor number (sec_index + n) * */ public String lookupSec() throws IOException { int sec_index = 1; boolean more = false; String secmode, first_secmode = null; Xdr call = new Xdr(rsize + 512); do { rpc.rpc_header(call, NFSPROC2_LOOKUP); call.xdr_raw(new byte[32]); // v2 public file handle // send "0x81pathname" over the wire int len = name.getBytes().length + 2; byte[] b = new byte[len]; b[0] = (byte) 0x81; b[1] = (byte) sec_index; System.arraycopy(name.getBytes(), 0, b, 2, name.getBytes().length); call.xdr_bytes(b); Xdr reply = rpc.rpc_call(call, 5 * 1000, 3); int status = reply.xdr_int(); // If the server does not support the MClookup security // negotiation, simply use the default security flavor. if (status != NFS_OK) { return NfsSecurity.getDefault(); } byte[] s = reply.xdr_raw(4); int numsec = ((int) s[0])/4; // 4 is sizeof (int) if (s[1] == (byte) 0) { more = false; } else { more = true; sec_index = sec_index + numsec; } String prefer = NfsSecurity.getPrefer(); while (numsec-- > 0) { secmode = Integer.toString(reply.xdr_int()); if ((prefer != null) && prefer.equals(secmode)) { return prefer; } if ((first_secmode == null) && NfsSecurity.hasValue(secmode)) { first_secmode = secmode; } } } while (more); return first_secmode; } /* * Read data from a file into a buffer * */ void read_otw(Buffer buf) throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC2_READ); call.xdr_raw(fh); call.xdr_u_int(buf.foffset); call.xdr_u_int(rsize); call.xdr_u_int(rsize); // totalcount (unused) Xdr reply = rpc.rpc_call(call, 1 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); attr.getFattr(reply); int bytesread = reply.xdr_int(); buf.eof = buf.foffset + rsize >= attr.size; buf.buf = reply.xdr_buf(); buf.bufoff = reply.xdr_offset(); buf.buflen = bytesread; cacheTime = attr.mtime; } /* * Write data from a file into a buffer * */ int write_otw(Buffer buf) throws IOException { Xdr call = new Xdr(wsize + 512); int fileOffset = (int) buf.foffset + buf.minOffset; int writeLength = buf.maxOffset - buf.minOffset; rpc.rpc_header(call, NFSPROC2_WRITE); call.xdr_raw(fh); call.xdr_u_int(fileOffset); // beginoffset - not used call.xdr_u_int(fileOffset); call.xdr_u_int(writeLength); // totalcount - not used call.xdr_bytes(buf.buf, buf.bufoff + buf.minOffset, writeLength); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); attr.getFattr(reply); buf.status = buf.LOADED; buf.writeVerifier = 0; cacheTime = attr.mtime; return writeLength; } /* * Read a directory * * Returns an array of names. */ String[] readdir() throws IOException { long cookie = 0; boolean eof = false; String[] s = new String[32]; String ename; int i = 0; /* * If we already have the directory entries * cached then return them. */ if (dircache != null && cacheOK(cacheTime)) return dircache; Xdr call = new Xdr(rsize + 512); while (!eof) { rpc.rpc_header(call, NFSPROC2_READDIR); call.xdr_raw(fh); call.xdr_u_int(cookie); call.xdr_u_int(4096); // number of directory bytes Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); /* * Get directory entries */ while (reply.xdr_bool()) { reply.xdr_u_int(); // skip fileid ename = reply.xdr_string(); // filename cookie = reply.xdr_u_int(); if (ename.equals(".") || ename.equals("..")) // ignore continue; s[i++] = ename; if (i >= s.length) { // last elem in array ? String[] tmp = s; s = new String[i*2]; // double its size System.arraycopy(tmp, 0, s, 0, i); } } eof = reply.xdr_bool(); // end of directory } /* * Trim array to exact size */ if (i < s.length) { String[] tmp = s; s = new String[i]; System.arraycopy(tmp, 0, s, 0, i); } dircache = s; cacheTime = attr.mtime; return s; } /* * Read a symbolic link * * Returns the text in the symbolic link */ String readlink() throws IOException { /* * If we've already read the symlink * then return the cached text. */ if (symlink != null && cacheOK(cacheTime)) return symlink; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC2_READLINK); call.xdr_raw(fh); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); symlink = reply.xdr_string(); cacheTime = attr.mtime; return symlink; } /* * Create a file * * @param name Name of file * @param mode UNIX style mode * @returns true if successful * @exception java.io.IOException */ Nfs create(String name, long mode) throws IOException { return create_otw(NFSPROC2_CREATE, name, mode); } /* * Create a directory * * @param name name of directory * @param mode UNIX style mode * @returns true if successful * @exception java.io.IOException */ Nfs mkdir(String name, long mode) throws IOException { return create_otw(NFSPROC2_MKDIR, name, mode); } /* * Create Nfs Object over-the-wire * * @param nfsOp NFS operation * @param mode UNIX style mode * @returns true if successful * @exception java.io.IOException */ private Nfs create_otw(int nfsOp, String name, long mode) throws IOException { long currTime = System.currentTimeMillis(); byte[] newfh; Fattr2 newattrs; Nfs nfs; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, nfsOp); call.xdr_raw(fh); call.xdr_string(name); call.xdr_u_int(mode); call.xdr_u_int(NfsConnect.getCred().getUid()); // owner call.xdr_u_int(NfsConnect.getCred().getGid()); // group call.xdr_u_int(0); // size call.xdr_u_int(currTime / 1000); // atime seconds call.xdr_u_int(currTime % 1000); // atime mseconds call.xdr_u_int(currTime / 1000); // mtime seconds call.xdr_u_int(currTime % 1000); // mtime mseconds Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); /* * Cache the new NFS Object */ newfh = reply.xdr_raw(FHSIZE); newattrs = new Fattr2(reply); String pathname = this.name + "/" + name; nfs = new Nfs2(rpc, newfh, pathname, newattrs); cache_put(nfs); dircache = null; return nfs; } /* * Get Filesystem Information * */ void fsinfo() throws IOException { wsize = RWSIZE; } /* * Commit writes - not implemented in v2 */ long commit(int foffset, int length) throws IOException { return 0; } /** * Remove file * * Returns true if the file was removed */ boolean remove(String name) throws IOException { return remove_otw(NFSPROC2_REMOVE, name); } /** * Remove directory * * @returns true if the directory could be deleted * @exception java.io.IOException */ boolean rmdir(String name) throws IOException { return remove_otw(NFSPROC2_RMDIR, name); } /* * Remove Nfs Object * * @param nfsOp over-the-wire operation * @param nfsP Nfs object of Parent directory * @param name Name of file/dir to be deleted. * @return true if the Nfs Object could be deleted * @exception java.io.IOException */ private boolean remove_otw(int nfsOp, String name) throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, nfsOp); call.xdr_raw(fh); call.xdr_string(name); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); cache_remove(this, name); // Remove Nfs object from cache dircache = null; return true; } /* * Rename file * * @param srcP Nfs obj of parent of src * @param dstP Nfs obj of parent of dst * @param sName src Name. * @param dName destination filename. May be 'path/filename' or simply * 'filename' * @returns true if the file/directory was renamed * @exception java.io.IOException */ boolean rename(Nfs dstP, String sName, String dName) throws IOException{ Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC2_RENAME); call.xdr_raw(fh); // Source dir filehandle call.xdr_string(sName); // Source filename call.xdr_raw(dstP.getFH()); // Dest dir filehandle call.xdr_string(dName); // Dest filename Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); cache_remove(this, sName); // Remove Nfs object from cache dircache = null; dstP.dircache = null; return true; } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/Nfs3.java000066400000000000000000001030351356275373100221130ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; /** * This class contains the methods specific to * NFS version 3. * * @see Nfs * @see Nfs2 * @see Fattr * @author Brent Callaghan * @author Ricardo Labiaga */ class Nfs3 extends Nfs { Fattr3 attr; int accessBits = -1; // Cache access bits long accessTime; // Time when accessBits was cached /* * NFS version 3 procedure numbers */ private final static int NFSPROC3_NULL = 0; private final static int NFSPROC3_GETATTR = 1; private final static int NFSPROC3_SETATTR = 2; private final static int NFSPROC3_LOOKUP = 3; private final static int NFSPROC3_ACCESS = 4; private final static int NFSPROC3_READLINK = 5; private final static int NFSPROC3_READ = 6; private final static int NFSPROC3_WRITE = 7; private final static int NFSPROC3_CREATE = 8; private final static int NFSPROC3_MKDIR = 9; private final static int NFSPROC3_SYMLINK = 10; private final static int NFSPROC3_MKNOD = 11; private final static int NFSPROC3_REMOVE = 12; private final static int NFSPROC3_RMDIR = 13; private final static int NFSPROC3_RENAME = 14; private final static int NFSPROC3_LINK = 15; private final static int NFSPROC3_READDIR = 16; private final static int NFSPROC3_READDIRPLUS = 17; private final static int NFSPROC3_FSSTAT = 18; private final static int NFSPROC3_FSINFO = 19; private final static int NFSPROC3_PATHCONF = 20; private final static int NFSPROC3_COMMIT = 21; private final static int NFS_OK = 0; private final static int NFS3ERR_NOTSUPP = 10004; private final static int RWSIZE = 32768; private final static int DIRCOUNT = 1024; private final static int MAXBSIZE = 8192; /* * Used to set time in create and mkdir */ private final static int DONT_CHANGE = 0; private final static int SERVER_TIME = 1; private final static int CLIENT_TIME = 2; /* * ACCESS bits */ private final static int ACCESS3_READ = 0x0001; private final static int ACCESS3_LOOKUP = 0x0002; private final static int ACCESS3_MODIFY = 0x0004; private final static int ACCESS3_EXTEND = 0x0008; private final static int ACCESS3_DELETE = 0x0010; private final static int ACCESS3_EXECUTE = 0x0020; /* * Types of create or mkdir */ private final static int UNCHECKED = 0; private final static int GUARDED = 1; private final static int EXCLUSIVE = 2; /* * Types of write */ private final static int UNSTABLE = 0; private final static int DATA_SYNC = 1; private final static int FILE_SYNC = 2; int nra; // current reads-ahead int nwb; // current writes-behind int prevWriteIndex = -1; Nfs3(Rpc rpc, byte[] fh, String name, Fattr3 attr) { this.rpc = rpc; this.fh = fh; if (name.startsWith("./")) // normalize for cache lookup name = name.substring(2); this.name = name; this.attr = attr == null ? new Fattr3() : attr; this.rsize = RWSIZE; NRA = 1; // Max reads-ahead NWB = 4; // Max writes-behind NWC = 10; // Max writes committed } void getattr() throws IOException { Xdr reply; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_GETATTR); call.xdr_bytes(fh); try { reply = rpc.rpc_call(call, 2 * 1000, 2); } catch (IOException e) { // don't let a mere getattr hang // the app if the server is down. return; } int status = reply.xdr_int(); if (status != NFS_OK) throw new NfsException(status); attr.getFattr(reply); } void checkAttr() throws IOException { if (! attr.valid()) getattr(); } boolean cacheOK(long t) throws IOException { checkAttr(); return t == attr.mtime; } void invalidate() { attr.validtime = 0; } /* * Get the file modification time * @return the time in milliseconds */ long mtime() throws IOException { checkAttr(); return attr.mtime; } /* * Get the file size in bytes. * * Note that the size may be greater than that * shown in the attributes if the file is being written. * * @return file size */ long length() throws IOException { checkAttr(); return maxLength > attr.size ? maxLength : attr.size; } /* * Verify if file exists * @return true if file exists */ boolean exists() throws IOException { checkAttr(); return true; } /* * Check access permission to file or directory */ private boolean check_access(int mode) throws IOException { int rBits = ACCESS3_READ; int wBits = ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE; /* * Get access bits from the server if * they're not already cached. */ if (accessBits < 0 || !cacheOK(accessTime)) { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_ACCESS); call.xdr_bytes(fh); call.xdr_int(rBits | wBits); Xdr reply = rpc.rpc_call(call, 5 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post-op attrs attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); accessBits = reply.xdr_int(); accessTime = attr.mtime; } if ((mode & RBIT) != 0) return (accessBits & rBits) != 0; if ((mode & WBIT) != 0) return (accessBits & wBits) != 0; return true; } /* * Verify if file can be created/updated * @return true if file can be created/updated */ boolean canWrite() throws IOException { return check_access(WBIT); } /* * Verify if file can be read * @return true if file can be read */ boolean canRead() throws IOException { return check_access(RBIT); } /* * Verify if this is a file (not a directory) * @return true if a file */ boolean isFile() throws IOException { checkAttr(); return attr.ftype == NFREG; } /* * Verify if this is a directory (not a file) * @return true if a directory */ boolean isDirectory() throws IOException { checkAttr(); return attr.ftype == NFDIR; } /* * Verify if this is a symbolic link * @return true if a symbolic link */ boolean isSymlink() throws IOException { checkAttr(); return attr.ftype == NFLNK; } /* * @return file attributes */ Fattr getAttr() throws IOException { checkAttr(); return (Fattr)attr; } /* * Lookup a name in a directory * * If its a symbolic link - follow it * * @param name Name of entry in directory * @returns Nfs object * @exception java.io.IOException */ Nfs lookup(String name) throws IOException { byte[] newFh; Fattr3 newattrs = null; Nfs nfs; String pathname; /* For multi-component lookup, the name would already be * filled in when object is created and * thus name passed in will be null. */ if (name == null) { pathname = this.name; name = this.name; } else { /* Single component case */ if (this.name == null) pathname = name; else pathname = this.name + "/" + name; } /* * First check the cache to see * if we already have this file/dir */ nfs = cache_get(rpc.conn.server, pathname); if (nfs != null && nfs.cacheOK(cacheTime)) { // If a symbolic link then follow it if (((Nfs3)nfs).attr.ftype == NFLNK) nfs = NfsConnect.followLink(nfs); return nfs; } Xdr call = new Xdr(rsize + 512); Xdr reply = null; /* * If needed, give one try to get the security information * from the server. */ for (int sec_tries = 1; sec_tries >= 0; sec_tries--) { rpc.rpc_header(call, NFSPROC3_LOOKUP); call.xdr_bytes(fh); call.xdr_string(name); try { reply = rpc.rpc_call(call, 5 * 1000, 0); break; } catch (MsgRejectedException e) { if (fh.length == 0 && e.why == MsgRejectedException.AUTH_TOOWEAK) { String secKey = lookupSec(); if (secKey != null && NfsSecurity.getMech(secKey) != null) { rpc.setCred(new CredGss("nfs", NfsSecurity.getMech(secKey), NfsSecurity.getService(secKey), NfsSecurity.getQop(secKey))); continue; } else if (secKey != null && secKey.equals("1")) { rpc.setCred(new CredUnix()); continue; } } throw e; } catch (IOException e) { throw e; } } // for int status = reply.xdr_int(); if (status != NFS_OK) { if (reply.xdr_bool()) attr.getFattr(reply); throw new NfsException(status); } newFh = reply.xdr_bytes(); if (reply.xdr_bool()) newattrs = new Fattr3(reply); if (reply.xdr_bool()) attr.getFattr(reply); nfs = new Nfs3(rpc, newFh, pathname, newattrs); cache_put(nfs); // If a symbolic link then follow it if (((Nfs3)nfs).attr.ftype == NFLNK) nfs = NfsConnect.followLink(nfs); return nfs; } /* * lookupSec() uses the WebNFS security negotiation protocol to * to get nfs security flavor numbers from the server. * * Null string is returned if the server fails to return any * security flavor numbers. * * If the server successfully returns a list of security modes, * the client will use the preferred security mode that matches * any security number found in the list, otherwise, it * will use the first security number from the list that the * client supports. * * Null string is returned if the client does not support any * security numbers that the server requests. * * Here is an example of the WebNFS security negotiation protocol: * * Suppose the server shares /export/home as follows: * * share -o sec=sec_1:sec_2:sec_3 /export/secure * * Here is how to READ a file from server:/export/secure: * * Client Server * ------ ------ * * LOOKUP 0x0, foo, "path" * -----------> * <----------- * AUTH_TOOWEAK * * LOOKUP 0x0, foo, 0x81, , "path" * -----------> * <----------- * FH = {...,sec_1, ..., sec_3} * LOOKUP 0x0, foo, "path" * use a selected sec flavor (sec_x) * -----------> * <----------- * FH = 0x01 * READ 0x01, sec_x, offset=0 for 32k * -----------> * <----------- * * Here is the contents of the FH returned from the server for the * "0x81" V3 LOOKUP request: * * 1 4 * +--+--+--+--+ * | len | * +--+--+--+--+ * up to 64 * +--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+ * |s | | | | sec_1 | sec_2 | ... | sec_n | * +--+--+--+--+--+--+--+--+--+--+--+--+ +--+--+--+--+ * * len = 4 * (n+1), where n is the number of security flavors * sent in the current overloaded filehandle. * * the status s indicates whether there are more security * mechanisms (1 means yes, 0 means no) that require the client * to perform another 0x81 LOOKUP to get them. Client uses * to indicate the offset of the flavor number * (sec_index + n). * * Three bytes are padded after s. * */ public String lookupSec() throws IOException { int sec_index = 1; boolean more = false; String secmode, first_secmode = null; Xdr call = new Xdr(rsize + 512); do { rpc.rpc_header(call, NFSPROC3_LOOKUP); call.xdr_bytes(new byte[0]); // v3 public file handle // send "0x81/sec_inext/pathname" over the wire int len = name.getBytes().length + 2; byte[] b = new byte[len]; b[0] = (byte) 0x81; b[1] = (byte) sec_index; System.arraycopy(name.getBytes(), 0, b, 2, name.getBytes().length); call.xdr_bytes(b); Xdr reply = rpc.rpc_call(call, 5 * 1000, 3); int status = reply.xdr_int(); // If the server does not support the MClookup security // negotiation, return null. if (status != NFS_OK) { return null; } int numsec = reply.xdr_int()/4 - 1; byte[] s = reply.xdr_raw(1); if (s[0] == (byte) 0) { more = false; } else { more = true; sec_index = sec_index + numsec; } String prefer = NfsSecurity.getPrefer(); while (numsec-- > 0) { secmode = Integer.toString(reply.xdr_int()); if ((prefer != null) && prefer.equals(secmode)) { return prefer; } if ((first_secmode == null) && NfsSecurity.hasValue(secmode)) { first_secmode = secmode; } } } while (more); return first_secmode; } /* * Read a buffer from a file */ void read_otw(Buffer buf) throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_READ); call.xdr_bytes(fh); call.xdr_hyper(buf.foffset); call.xdr_int(rsize); Xdr reply = rpc.rpc_call(call, 1 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post-op attrs attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); int bytesread = reply.xdr_int(); buf.eof = reply.xdr_bool(); if (bytesread != reply.xdr_u_int()) throw new NfsException(NfsException.NFSERR_TOOSMALL); buf.buf = reply.xdr_buf(); buf.bufoff = reply.xdr_offset(); buf.buflen = bytesread; cacheTime = attr.mtime; } /* * Write a buffer */ int write_otw(Buffer buf) throws IOException { Xdr call = new Xdr(wsize + 512); rpc.rpc_header(call, NFSPROC3_WRITE); call.xdr_bytes(fh); call.xdr_hyper(buf.foffset + buf.minOffset); call.xdr_u_int(buf.maxOffset - buf.minOffset); call.xdr_int(buf.syncType); call.xdr_bytes(buf.buf, buf.bufoff + buf.minOffset, buf.maxOffset - buf.minOffset); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); /* * wcc_data */ // XXX if pre_op_attr show file changed then // should invalidate cached non-dirty blocks. if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) { // post_op_attr attr.getFattr(reply); cacheTime = attr.mtime; } if (status != NFS_OK) throw new NfsException(status); int bytesWritten = reply.xdr_int(); if (reply.xdr_int() == FILE_SYNC) // stable_how buf.status = buf.LOADED; else buf.status = buf.COMMIT; buf.writeVerifier = reply.xdr_hyper(); // writeverf3 return bytesWritten; } /* * Read a directory including entry filehandles and attributes. * * Entries are cached as Nfs objects - preempting any need * for lookups within the directory - entries need be validated * only with getattr. * * XXX Large directories or a file tree walk * XXX could run us out of memory because of * XXX the aggressive caching. * */ String[] readdir() throws IOException { long cookie = 0; long cookieverf = 0; boolean eof = false; String[] s = new String[32]; int i = 0; Fattr3 eattr; byte[] efh; String ename; String pathname; /* * If we already have the directory entries * cached then return them. */ if (dircache != null) { if (cacheOK(cacheTime)) return dircache; dircache = null; return readdir_old(); } Xdr call = new Xdr(rsize + 512); while (!eof) { rpc.rpc_header(call, NFSPROC3_READDIRPLUS); call.xdr_bytes(fh); call.xdr_hyper(cookie); call.xdr_hyper(cookieverf); call.xdr_u_int(DIRCOUNT); // number of directory bytes call.xdr_u_int(MAXBSIZE); // max number of directory bytes Xdr reply = rpc.rpc_call(call, 3 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post-op dir attrs attr.getFattr(reply); /* * Some implementations don't support readdirplus * so fall back to the old readdir if necessary. */ if (status == NFS3ERR_NOTSUPP) return readdir_old(); if (status != NFS_OK) throw new NfsException(status); cookieverf = reply.xdr_hyper(); /* * Get directory entries */ while (reply.xdr_bool()) { reply.xdr_hyper(); // skip fileid ename = reply.xdr_string(); // entry filename cookie = reply.xdr_hyper(); eattr = null; efh = null; if (reply.xdr_bool()) // entry attrs eattr = new Fattr3(reply); if (reply.xdr_bool()) // entry filehandle efh = reply.xdr_bytes(); if (ename.equals(".") || ename.equals("..")) // ignore entry continue; s[i++] = ename; if (i >= s.length) { // last elem in array ? String[] tmp = s; s = new String[i*2]; // double its size System.arraycopy(tmp, 0, s, 0, i); } /* * If we have both filehandle and attrs * then stash the entry object in the cache */ if (efh != null && eattr != null) { if (this.name == null) pathname = ename; else pathname = this.name + "/" + ename; cache_put(new Nfs3(rpc, efh, pathname, eattr)); } } eof = reply.xdr_bool(); // end of directory } /* * Trim array to exact size */ if (i < s.length) { String[] tmp = s; s = new String[i]; System.arraycopy(tmp, 0, s, 0, i); } dircache = s; cacheTime = attr.mtime; return s; } /** * Read a directory with just names and fileids * * @returns byte array of directory entries * @exception java.io.IOException */ String[] readdir_old() throws IOException { long cookie = 0; long cookieverf = 0; boolean eof = false; String ename; String[] s = new String[32]; int i = 0; /* * If we already have the directory entries * cached then return them. */ if (dircache != null && cacheOK(cacheTime)) return (dircache); Xdr call = new Xdr(rsize + 512); while (!eof) { rpc.rpc_header(call, NFSPROC3_READDIR); call.xdr_bytes(fh); call.xdr_hyper(cookie); call.xdr_hyper(cookieverf); call.xdr_u_int(MAXBSIZE); // number of directory bytes Xdr reply = rpc.rpc_call(call, 3 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post-op dir attrs attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); cookieverf = reply.xdr_hyper(); /* * Get directory entries */ while (reply.xdr_bool()) { reply.xdr_hyper(); // skip fileid ename = reply.xdr_string(); // filename if (! ename.equals(".") && ! ename.equals("..")) s[i++] = ename; if (i >= s.length) { // last elem in array ? String[] tmp = s; s = new String[i*2]; // double its size System.arraycopy(tmp, 0, s, 0, i); } cookie = reply.xdr_hyper(); } eof = reply.xdr_bool(); // end of directory } if (i == 0) return (null); /* * Trim array to exact size */ if (i < s.length) { String[] tmp = s; s = new String[i]; System.arraycopy(tmp, 0, s, 0, i); } dircache = s; cacheTime = attr.mtime; return (s); } /* * Read a symbolic link * */ String readlink() throws IOException { /* * If we've already read the symlink * then return the cached text. */ if (symlink != null && cacheOK(cacheTime)) return symlink; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_READLINK); call.xdr_bytes(fh); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post-op attr attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); symlink = reply.xdr_string(); cacheTime = attr.mtime; return symlink; } /* * Create a file * */ Nfs create(String name, long mode) throws IOException { byte[] newFh = null; Fattr3 newattrs = null; Nfs nfs; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_CREATE); call.xdr_bytes(fh); call.xdr_string(name); call.xdr_int(UNCHECKED); // sattr3 call.xdr_bool(true); // mode3 call.xdr_u_int(mode); call.xdr_bool(true); // uid3 call.xdr_u_int(NfsConnect.getCred().getUid()); call.xdr_bool(true); // gid3 call.xdr_u_int(NfsConnect.getCred().getGid()); call.xdr_bool(true); // size3 call.xdr_hyper(0); call.xdr_int(SERVER_TIME); // atime call.xdr_int(SERVER_TIME); // mtime Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) { /* * CREATE3resfail */ // wcc_data // XXX If this were an exlusive create, then we // should check whether the directory was modified, // in such case, the file may have been created by another // client. if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); throw new NfsException(status); } /* * CREATE3resok */ if (reply.xdr_bool()) // post_op_fh3 newFh = reply.xdr_bytes(); if (reply.xdr_bool()) // post_op_attr newattrs = new Fattr3(reply); /* * wcc_data */ if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); if (newFh != null && newattrs != null) { String pathname = this.name + "/" + name; nfs = new Nfs3(rpc, newFh, pathname, newattrs); cache_put(nfs); } else nfs = null; return nfs; } /* * Create a directory * * @param name name of directory to create * @returns true if successful, false otherwise */ Nfs mkdir(String name, long mode) throws IOException { byte[] newFh = null; Fattr3 newattrs = null; Nfs nfs = null; Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_MKDIR); call.xdr_bytes(fh); call.xdr_string(name); // sattr3 call.xdr_bool(true); // mode3 call.xdr_u_int(mode); call.xdr_bool(true); // uid3 call.xdr_u_int(NfsConnect.getCred().getUid()); call.xdr_bool(true); // gid3 call.xdr_u_int(NfsConnect.getCred().getGid()); call.xdr_bool(true); // size3 call.xdr_hyper(0); call.xdr_int(SERVER_TIME); // atime call.xdr_int(SERVER_TIME); // mtime Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (status != NFS_OK) { /* * MKDIR3resfail */ // wcc_data if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); throw new NfsException(status); } /* * MKDIR3resok */ if (reply.xdr_bool()) // post_op_fh3 newFh = reply.xdr_bytes(); if (reply.xdr_bool()) // post_op_attr newattrs = new Fattr3(reply); /* * wcc_data */ if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); if (newFh != null && newattrs != null) { String pathname = this.name + "/" + name; nfs = new Nfs3(rpc, newFh, pathname, newattrs); cache_put(nfs); } dircache = null; return nfs; } /* * Get Filesystem Information * */ void fsinfo() throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_FSINFO); call.xdr_bytes(fh); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); reply.xdr_u_int(); // rtmax reply.xdr_u_int(); // rtpref reply.xdr_u_int(); // rtmult reply.xdr_u_int(); // wtmax: maximum write size wsize = reply.xdr_int(); // wtpref: preferred write size /* * More attributes follow but we don't * Need them so we don't XDR decode them. */ //reply.xdr_hyper(); // maxfilesize //reply.xdr_u_int(); // seconds //reply.xdr_u_int(); // nseconds //reply.xdr_u_int(); // properties } /* * Commit previous async writes to stable storage */ long commit(int foffset, int length) throws IOException { Xdr call = new Xdr(wsize + 512); rpc.rpc_header(call, NFSPROC3_COMMIT); call.xdr_bytes(fh); call.xdr_hyper(foffset); call.xdr_u_int(length); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); /* * wcc_data */ // XXX if pre_op_attr show file changed then // should invalidate cached non-dirty blocks. if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3; reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); return reply.xdr_hyper(); // return verifier } /* * Remove file * * @returns true if the file was removed */ boolean remove(String name) throws IOException { return remove_otw(NFSPROC3_REMOVE, name); } /** * Remove directory * * @returns true if the directory could be deleted * @exception java.io.IOException */ boolean rmdir(String name) throws IOException { return remove_otw(NFSPROC3_RMDIR, name); } /* * Remove Nfs Object over-the-wire * @param NfsOperation over-the-wire operation * @param NfsP Nfs object of Parent directory * @param name Name of file to delete (for Mount protocol, the * name will not be filled out for this Nfs object) * @returns true if the Nfs Object was deleted */ private boolean remove_otw(int NfsOperation, String name) throws IOException { Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NfsOperation); call.xdr_bytes(fh); call.xdr_string(name); Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); /* * wcc_data */ // should check whether the directory was modified, // in such case, the file may have been deleted by another // client. if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3 reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) // post_op_attr attr.getFattr(reply); if (status != NFS_OK) throw new NfsException(status); // Remove Nfs object from cache cache_remove(this, name); dircache = null; return true; } /* * Rename file * @param srcP Nfs obj of parent of src * @param dstP Nfs obj of parent of dst * @param sName src Name. * @param dName destination filename. May be 'path/filename' or simply * 'filename' * @returns true if the file/directory was renamed */ boolean rename(Nfs dstP, String sName, String dName) throws IOException{ Xdr call = new Xdr(rsize + 512); rpc.rpc_header(call, NFSPROC3_RENAME); call.xdr_bytes(fh); // Source dir filehandle call.xdr_string(sName); // Source filename call.xdr_bytes(dstP.getFH()); // Dest dir filehandle call.xdr_string(dName); // Dest filename Xdr reply = rpc.rpc_call(call, 2 * 1000, 0); int status = reply.xdr_int(); /* * wcc_data - fromdir_wcc */ if (reply.xdr_bool()) { // pre_op_attr reply.xdr_hyper(); // size3 reply.xdr_u_int(); // mtime reply.xdr_u_int(); reply.xdr_u_int(); // ctime reply.xdr_u_int(); } if (reply.xdr_bool()) attr.getFattr(reply); /* * Don't bother getting wcc_data for destDir since we have * no method to update its attributes. */ if (status != NFS_OK) throw new NfsException(status); cache_remove(this, sName); // Remove Nfs object from cache dircache = null; dstP.dircache = null; return true; } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/NfsConnect.java000066400000000000000000000327251356275373100233510ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; import java.util.Hashtable; /** * * Connect to an NFS server and return an * Nfs file object. * * @see Nfs * @see Nfs2 * @see Nfs3 * @author Brent Callaghan */ public class NfsConnect { private static byte[] pubfh2 = new byte[32]; // v2 public filehandle private static byte[] pubfh3 = new byte[0]; // v3 public filehandle private static Hashtable cacheNfsConnect = new Hashtable(); static final int NFS_PORT = 2049; static final int NFS_PROG = 100003; static final int MAXBUF = 32768 + 512; // Max size of NFS reply String server; int port; int version; String proto; boolean pub; static CredUnix cred = new CredUnix(); static RpcHandler rhandler; static String sec_flavor; NfsConnect(String server, int port, int version, String proto, boolean pub) { this.server = server; this.port = port; this.version = version; this.proto = proto; this.pub = pub; } /** * Return an Nfs object given an NFS URL * * This code will also obtain testing options * if present in the URL and use them to set specific * configurations. * * @param url NFS URL * @returns The Nfs object */ static Nfs connect(String urlstr) throws IOException { NfsURL url = new NfsURL(urlstr); String server = url.getHost(); int port = url.getPort(); String path = url.getFile(); int version = url.getVersion(); String proto = url.getProto(); boolean pub = url.getPub(); NfsConnect n = null; if (server == null) throw new java.net.UnknownHostException(); if (version == 0 && proto == null && pub) // no testing options n = NfsConnect.cache_get(server); if (n == null) return (connect(server, path, port, version, proto, pub)); else return (connect(server, path, n.port, n.version, n.proto, n.pub)); } /** * Return an Nfs object given a server and pathname * * We're not fussy about NFS version or whether TCP * or UDP is used. * * @param server The server that hosts the object * @param name The pathname of the object * @returns The object */ static Nfs connect(String server, int port, String path) throws IOException { NfsConnect n = NfsConnect.cache_get(server); if (n == null) return (connect(server, path, port, 0, null, true)); else return (connect(server, path, n.port, n.version, n.proto, n.pub)); } /** * Return an Nfs object given a server, pathname, version, and protocol * * Try to obtain the filehandle for the object via a public filehandle * otherwise fall back to the mount protocol. * * @param server The server that hosts the object * @param name The pathname of the object * @param vers The version of NFS to be used. If zero then * prefer v3 over v2. * @param proto The transport protocol to be used: "tcp" or "udp." * If this is null then prefer TCP over UDP. * @param pub Boolean Public filehandle support. */ static Nfs connect(String server, String path, int port, int vers, String proto, boolean pub) throws IOException { if (port == 0) port = NFS_PORT; if (path == null || path.length() == 0) path = "."; /* * Check first if we already have the file/dir cached */ Nfs nfs = Nfs.cache_get(server, path); if (nfs != null) { nfs.getattr(); // for close-to-open consistency if (nfs.isSymlink()) return followLink(nfs); return (nfs); } /* * First set up a connection using the specified proto. * If neither "tcp" or "udp" is specified, then try * "tcp" and fall back to "udp" if that fails. * * Note that we check to see if there's an existing * connection to the server and use that if available. */ Connection conn; if (proto == null) { conn = Connection.getCache(server, port, "tcp"); if (conn == null) conn = Connection.getCache(server, port, "udp"); if (conn == null) { // no cached connections try { conn = new ConnectSocket(server, port, MAXBUF); Connection.putCache(conn); proto = "tcp"; } catch (java.net.UnknownHostException e) { throw e; // don't catch as an IOException } catch (IOException e) { conn = new ConnectDatagram(server, port, MAXBUF); Connection.putCache(conn); proto = "udp"; } } } else if (proto.equals("tcp")) { conn = Connection.getCache(server, port, "tcp"); if (conn == null) { conn = new ConnectSocket(server, port, MAXBUF); Connection.putCache(conn); } } else if (proto.equals("udp")) { conn = Connection.getCache(server, port, "udp"); if (conn == null) { conn = new ConnectDatagram(server, port, MAXBUF); Connection.putCache(conn); } } else { throw new IOException("Unknown protocol: " + proto); } /* * Try using the public filehandle */ if (pub) { try { switch (vers) { case 0: try { nfs = tryNfs(conn, pubfh3, path, 3, false); vers = 3; } catch (MsgAcceptedException e) { if (e.error != e.PROG_MISMATCH) throw e; vers = 2; nfs = tryNfs(conn, pubfh2, path, 2, false); } break; case 2: nfs = tryNfs(conn, pubfh2, path, 2, false); break; case 3: nfs = tryNfs(conn, pubfh3, path, 3, false); break; } } catch (MsgAcceptedException e) { if (e.error != e.GARBAGE_ARGS) throw e; // Not WebNFS but which version of NFS ? Assume 3 if (vers == 0) vers = 3; } catch (NfsException e) { if (e.error != e.NFSERR_STALE && e.error != e.NFSERR_BADHANDLE) throw e; if (vers == 0) vers = 3; // if we get here then server must be v3 } if (nfs != null) { // public fh worked NfsConnect.cache_put(new NfsConnect(server, port, vers, proto, true)); return (nfs); } } /* * Server doesn't accept public filehandles * Resort to using the MOUNT protocol */ if (path.equals(".")) path = "/"; Mount m = new Mount(); byte[] fh = m.getFH(server, path, vers); sec_flavor = m.getSec(); NfsConnect.cache_put(new NfsConnect(server, port, vers, proto, false)); return (tryNfs(conn, fh, path, vers, true)); } private static Nfs tryNfs(Connection conn, byte[] pubfh, String path, int vers, boolean mount) throws IOException { Nfs pubnfs; Rpc rpc = new Rpc(conn, NFS_PROG, vers); /* * Use the default security flavor. */ String defaultSec = NfsSecurity.getDefault(); if (defaultSec.equals("1")){ // AUTH_SYS rpc.setCred(cred); } else { if (NfsSecurity.getMech(defaultSec) != null) { // if there is a mechOid, use RPCSEC_GSS rpc.setCred(new CredGss("nfs", NfsSecurity.getMech(defaultSec), NfsSecurity.getService(defaultSec), NfsSecurity.getQop(defaultSec))); } else { // not RPCSEC_GSS; use AUTH_SYS for now rpc.setCred(cred); } } rpc.setRpcHandler(rhandler); if (vers == 2) pubnfs = new Nfs2(rpc, pubfh, path, null); else pubnfs = new Nfs3(rpc, pubfh, path, null); if (path.equals("/.")) // special path for testing return pubnfs; if (mount) { if (NfsSecurity.getMech(sec_flavor) != null) { rpc.setCred(new CredGss("nfs", NfsSecurity.getMech(sec_flavor), NfsSecurity.getService(sec_flavor), NfsSecurity.getQop(sec_flavor))); } pubnfs.getattr(); Nfs.cache_put(pubnfs); return (pubnfs); } /* The path passed to lookup will be null since it * has been filled in when object has been created. */ return (pubnfs.lookup(null)); } /* * Given a symbolic link - read its text * find the NFS object it refers to. * * XXX needs to contain a loop (max 30x) to follow * chains of symlinks properly. */ static Nfs followLink(Nfs link) throws IOException { String base = link.name; String text = link.readlink(); String server = link.rpc.conn.server; int port = link.rpc.conn.port; String newpath; if (text.startsWith("nfs://")) { // NFS URL NfsURL url = new NfsURL(text); server = url.getHost(); port = url.getPort(); newpath = url.getFile(); } else if (text.startsWith("/")) { // absolute path newpath = text; } else { /* * Combine base path with relative path * according to rules in RFCs 1808 & 2054 * * e.g. /a/b/c + x = /a/b/x * /a/b/c + /y = /z * /a/b/c + ../z = /a/z */ int head = 0; int tail = base.lastIndexOf('/'); int len = text.length(); while (text.regionMatches(head, "..", 0, len - head) || text.startsWith("../", head)) { head += 3; if (head >= len) break; tail = base.lastIndexOf('/', tail - 1); } if (head > len) head = len; if (tail < 0) tail = 0; else tail++; newpath = base.substring(0, tail) + text.substring(head); } try { return (NfsConnect.connect(server, port, newpath)); } catch (IOException e) { System.err.println(e + ": symbolic link: " + base + " -> " + text); return (link); } } /** * Cache an NfsConnect object * * @param n the object to be cached */ private static void cache_put(NfsConnect n) { cacheNfsConnect.put(n.server, n); } /** * Retrieve a cached NfsConnect object * * @param server The server that hosts the object * @returns The object - or null if not cached */ private static NfsConnect cache_get(String server) { return ((NfsConnect)cacheNfsConnect.get(server)); } /** * Get the credential as a Unix cred * * @returns The credential stored for Nfs operations */ public static CredUnix getCred() { return (cred); } /** * Set the timeout handler */ public static void setRpcHandler(RpcHandler r) { rhandler = r; } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/NfsException.java000066400000000000000000000130261356275373100237070ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; /** * This exception is thrown whenever an NFS error occurs. */ public class NfsException extends java.io.IOException { int error; /* * We're fortunate that NFS v2 and v3 * share the same error codes */ public static final int NFS_OK = 0; public static final int NFSERR_PERM = 1; public static final int NFSERR_NOENT = 2; public static final int NFSERR_IO = 5; public static final int NFSERR_NXIO = 6; public static final int NFSERR_ACCES = 13; public static final int NFSERR_EXIST = 17; public static final int NFSERR_XDEV = 18; public static final int NFSERR_NODEV = 19; public static final int NFSERR_NOTDIR = 20; public static final int NFSERR_ISDIR = 21; public static final int NFSERR_INVAL = 22; public static final int NFSERR_FBIG = 27; public static final int NFSERR_NOSPC = 28; public static final int NFSERR_ROFS = 30; public static final int NFSERR_MLINK = 31; public static final int NFSERR_NAMETOOLONG = 63; public static final int NFSERR_NOTEMPTY = 66; public static final int NFSERR_DQUOT = 69; public static final int NFSERR_STALE = 70; public static final int NFSERR_REMOTE = 71; public static final int NFSERR_BADHANDLE = 10001; public static final int NFSERR_NOT_SYNC = 10002; public static final int NFSERR_BAD_COOKIE = 10003; public static final int NFSERR_NOTSUPP = 10004; public static final int NFSERR_TOOSMALL = 10005; public static final int NFSERR_SERVERFAULT = 10006; public static final int NFSERR_BADTYPE = 10007; public static final int NFSERR_JUKEBOX = 10008; /** * Create a new NfsException * * @param NFS error number for this error */ public NfsException(int error) { super("NFS error: " + error); this.error = error; } public String toString() { switch (error) { case NFS_OK: return ("OK"); case NFSERR_PERM: return ("Not owner"); case NFSERR_NOENT: return ("No such file or directory"); case NFSERR_IO: return ("I/O error"); case NFSERR_NXIO: return ("No such device or address"); case NFSERR_ACCES: return ("Permission denied"); case NFSERR_EXIST: return ("File exists"); case NFSERR_XDEV: return ("Attempted cross-device link"); case NFSERR_NODEV: return ("No such device"); case NFSERR_NOTDIR: return ("Not a directory"); case NFSERR_ISDIR: return ("Is a directory"); case NFSERR_INVAL: return ("Invalid argument"); case NFSERR_FBIG: return ("File too large"); case NFSERR_NOSPC: return ("No space left on device"); case NFSERR_ROFS: return ("Read-only file system"); case NFSERR_MLINK: return ("Too many links"); case NFSERR_NAMETOOLONG: return ("File name too long"); case NFSERR_NOTEMPTY: return ("Directory not empty"); case NFSERR_DQUOT: return ("Disk quota exceeded"); case NFSERR_STALE: return ("Stale NFS file handle"); case NFSERR_REMOTE: return ("Too many levels of remote in path"); case NFSERR_BADHANDLE: return ("Illegal NFS file handle"); case NFSERR_NOT_SYNC: return ("Update sync mismatch"); case NFSERR_BAD_COOKIE: return ("Readdir cookie is stale"); case NFSERR_NOTSUPP: return ("Operation not supported"); case NFSERR_TOOSMALL: return ("Buffer/request too small"); case NFSERR_SERVERFAULT: return ("Server fault"); case NFSERR_BADTYPE: return ("Bad type"); case NFSERR_JUKEBOX: return ("Jukebox error: try later"); } return ("Unknown NFS error: " + error); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/NfsHandler.java000066400000000000000000000070031356275373100233240ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.rpc.*; /** * This handler is implemented by the NFS application * if it wishes to be notifed of retransmissions. * A good example is an NFS client that displays * "NFS Server not responding" and "NFS server OK" */ public abstract class NfsHandler extends RpcHandler { /** * Called when an NFS request has timed out * * The RPC code will retransmit NFS requests * until the server responds. The initial * retransmission timeout is set by the NFS * code and increases exponentially with * each retransmission until an upper bound * of 30 seconds is reached, e.g. timeouts * will be 1, 2, 4, 8, 16, 30, 30, ... sec. *

* An instance of the NfsHandler class is * registered with the setHandler method of * the NFS XFileExtensionAccessor. * * @param server The name of the server to which the * request was sent. * @param retries The number of times the request has * been retransmitted. After the first timeout * retries will be zero. * @param wait Total time since first call in milliseconds * (cumulative value of all retransmission timeouts). * @return false if retransmissions are to continue. * If the method returns true, the RPC layer will * abort the retransmissions and return an * InterruptedIOException to the application. */ public abstract boolean timeout(String server, int retries, int wait); /** * Called when a server reply is recieved after a timeout. * * @param server The name of the server that returned * the reply. */ public abstract void ok(String server); } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/NfsSecurity.java000066400000000000000000000146661356275373100235730ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import java.util.*; import com.sun.rpc.*; /** * NfsSecurity is a static class. It reads in the com.sun.properties.nfssec * properties file and provides the vehicle to retrieve properties values * which are the (mechanism, service, qop) mappings for the NFS security pseudo * flavor numbers. * * @author Lin Ling */ public final class NfsSecurity { static ResourceBundle props; static String secName, secMode, mech; static int service, qop; static { initialize(); } private static void initialize() { try { props = ResourceBundle.getBundle("com.sun.nfs.nfssec"); } catch (MissingResourceException e) { props = null; } } /* * Parse the string value using ":" as the delimiter. * * nfsSecName:mechanismOID:service:qualityProtection * * (e.g. dummyp:1.3.6.1.4.1.42.2.26.1.2:privacy:0) * */ private static void parseValue(String value) { StringTokenizer parser = new StringTokenizer(value, ":\n\r"); secName = parser.nextToken(); try { mech = parser.nextToken(); } catch (NoSuchElementException e) { // non-RPCSEC_GSS flavors mech = null; service = 0; qop = 0; return; } String serviceString = parser.nextToken(); if (serviceString.equals("none")) service = Cred.SVC_NONE; else if (serviceString.equals("integrity")) service = Cred.SVC_INTEGRITY; else if (serviceString.equals("privacy")) service = Cred.SVC_PRIVACY; else service = Cred.SVC_PRIVACY; // just use privacy service qop = Integer.parseInt(parser.nextToken()); } /** * Does the key have a value defined in the nfssec.properties file? * (i.e. is key=value defined in the properties list?) * * @param key the key to be searched * @returns true or false */ public static boolean hasValue(String key) { if (props == null) return false; try { props.getString(key); return true; } catch (MissingResourceException e) { return false; } } /** * Get the default security flavor number if it is specified in the * nfssec.properties file, otherwise, simply return "1" for AUTH_SYS. */ public static String getDefault() { if (props == null) return "1"; try { return props.getString("default"); } catch (MissingResourceException e) { return "1"; } } /** * Get the preferred nfs security flavor number if it is specified * in the nfssec.properties file, otherwise, return null. */ public static String getPrefer() { if (props == null) return null; try { return props.getString("prefer"); } catch (MissingResourceException e) { return null; } } /** * getName will get the NFS security flavor name from the first token * in the value. * * key=nfsSecName:mechOid:service:qop * ^^^^^^^^^^ * * @param key the key to be searched * @returns NFS Security flavor name */ public static String getName(String key) { if (key.equals(secMode)) { return secName; } parseValue(props.getString(key)); secMode = key; return secName; } /** * getMech will get the security mechanism OID string from the second token * in the value. * * key=nfsSecName:mechOid:service:qop * ^^^^^^^ * * @param key the key to be searched * @returns security mechansim OID string */ public static String getMech(String key) { if (key.equals(secMode)) { return mech; } parseValue(props.getString(key)); secMode = key; return mech; } /** * getService will get the security service type from the third token * in the value. * * key=nfsSecName:mechOid:service:qop * ^^^^^^^ * * @param key the key to be searched * @returns one of (none, integrity, privacy); if the third token * in the value does not have the expected data, simply * returns the privacy service number. */ public static int getService(String key) { if (key.equals(secMode)) { return service; } parseValue(props.getString(key)); secMode = key; return service; } /** * getQop will get the Quality of Protection number from the fourth token * in the value. * * key=nfsSecName:mechOid:service:qop * ^^^ * * @param key the key to be searched * @returns qop number; 0 means the mechanism-specific default qop */ public static int getQop(String key) { if (key.equals(secMode)) { return qop; } parseValue(props.getString(key)); secMode = key; return qop; } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/NfsURL.java000066400000000000000000000137071356275373100224210ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.net.MalformedURLException; /** * This is just a dumb URL parser class. * I wrote it because I got fed up with the * JDK URL class calling NFS URL's "invalid" * simply because the Handler wasn't installed. * * This URL parser also handles undocumented * testing options inserted in the URL in the * port field. The following sequence of option * letters may appear before or after the port * number, or alone if the port number is not * given. * vn - NFS version, e.g. "v3" * u - Force UDP - normally TCP is preferred * t - Force TDP - don't fall back to UDP * m - Force Mount protocol. Normally public filehandle * is preferred * * Option ordering is not important. * * Example: * nfs://server:123v2um/path * * Use port 123 with NFS v2 over UDP and Mount protocol * * nfs://server:m/path * * Use default port, prefer V3/TCP but use Mount protocol * * @author Brent Callaghan */ public class NfsURL { private String url; private String protocol; private String host; private String location; private int port; private String file; /* * Undocumented testing options */ private int version; private String proto; private boolean pub = true; public NfsURL(String url) throws MalformedURLException { int p, q, r; url = url.trim(); // remove leading & trailing spaces this.url = url; int end = url.length(); p = url.indexOf(':'); if (p < 0) throw new MalformedURLException("colon expected"); protocol = url.substring(0, p); p++; // skip colon if (url.regionMatches(p, "//", 0, 2)) { // have hostname p += 2; q = url.indexOf('/', p); if (q < 0) q = end; location = url.substring(0, q); r = url.indexOf(':', p); if (r > 0 && r < q) { byte[] opts = url.substring(r + 1, q).toLowerCase().getBytes(); for (int i = 0; i < opts.length; i++) { if (opts[i] >= '0' && opts[i] <= '9') { port = (port * 10) + (opts[i] - '0'); } else { switch (opts[i]) { case 'v': // NFS version version = opts[++i] - '0'; break; case 't': // Force TCP only proto = "tcp"; break; case 'u': // Force UDP only proto = "udp"; break; case 'w': // Force WebNFS only pub = true; break; case 'm': // Force MOUNT protocol only pub = false; break; default: throw new MalformedURLException( "invalid port number"); } } } } else { r = q; // no port } if (p < r) host = url.substring(p, r); } else { q = p; } if (q < end) file = url.substring(q + 1, end); } public String getProtocol() { return (protocol); } public String getLocation() { return (location); } public String getHost() { return (host); } public int getPort() { return (port); } public String getFile() { return (file); } /* * Undocumented options for testing */ int getVersion() { return (version); } String getProto() { return (proto); } boolean getPub() { return (pub); } public String toString() { String s = getProtocol() + ":"; if (host != null) s += "//" + host; if (port > 0) s += ":" + port; if (file != null) s += "/" + file; return (s); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/XFileAccessor.java000066400000000000000000000250761356275373100240040ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import com.sun.xfile.*; import java.io.*; import java.net.*; /** * The XFileAccessor interface is implemented by filesystems that * need to be accessed via the XFile API. * * @author Brent Callaghan * @version 1.0, 04/08/98 * @see com.sun.xfile.XFile */ public class XFileAccessor implements com.sun.xfile.XFileAccessor { XFile xf; boolean serial; boolean readOnly; Nfs nfs; /** * Open this NFS object * * @param xf the XFile object * @param serial true if serial access * @param readOnly true if read only */ public boolean open(XFile xf, boolean serial, boolean readOnly) { this.xf = xf; try { nfs = NfsConnect.connect(xf.getAbsolutePath()); return true; } catch (IOException e) { return false; } } public XFile getXFile() { return xf; } protected Nfs getParent(XFile xf) throws IOException { XFile xfp = new XFile(xf.getParent()); XFileAccessor nfsx = new XFileAccessor(); nfsx.open(xfp, serial, readOnly); return nfsx.getNfs(); } protected Nfs getNfs() { return nfs; } /** * Tests if this XFileAccessor object exists. * * @return true if the file specified by this object * exists; false otherwise. */ public boolean exists() { try { return nfs.exists(); } catch (Exception e) { return false; } } /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this * object; false otherwise. */ public boolean canWrite() { try { return nfs.canWrite(); } catch (IOException e) { return false; } } /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ public boolean canRead() { try { return nfs.canRead(); } catch (IOException e) { return false; } } /** * Tests if the file represented by this * object is a "normal" nfs. *

* A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is * guaranteed to be a normal nfs. * * @return true if the file specified by this * XFile object exists and is a "normal" * file; false otherwise. */ public boolean isFile() { try { return nfs.isFile(); } catch (IOException e) { return false; } } /** * Tests if the file represented by this XFileAccessor * object is a directory. * * @return true if this XFileAccessor object * exists and is a directory; false * otherwise. */ public boolean isDirectory() { try { return nfs.isDirectory(); } catch (IOException e) { return false; } } /** * Returns the time that the file represented by this * XFile object was last modified. *

* The return value is system dependent and should only be * used to compare with other values returned by last modified. * It should not be interpreted as an absolute time. * * @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ public long lastModified() { try { return nfs.mtime(); } catch (IOException e) { return 0L; } } /** * Returns the length of the file represented by this * XFileAccessor object. * * @return the length, in bytes, of the file specified by * this object, or 0L if the specified * file does not exist. */ public long length() { try { return nfs.length(); } catch (IOException e) { return 0L; } } /** * Creates a file whose pathname is specified by this * XFileAccessor object. * * @return true if the file could be created; * false otherwise. */ public boolean mkfile() { try { nfs = getParent(xf).create(xf.getName(), (long)0666); return true; } catch (Exception e) { return false; } } /** * Creates a directory whose pathname is specified by this * XFileAccessor object. * * @return true if the directory could be created; * false otherwise. */ public boolean mkdir() { try { nfs = getParent(xf).mkdir(xf.getName(), (long)0777); return true; } catch (Exception e) { return false; } } /** * Renames the file specified by this XFileAccessor object to * have the pathname given by the XFileAccessor object argument. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ public boolean renameTo(XFile dest) { try { Nfs sParent = getParent(xf); Nfs dParent = getParent(dest); return sParent.rename(dParent, xf.getName(), dest.getName()); } catch (Exception e) { return false; } } /** * Returns a list of the files in the directory specified by * this XFileAccessor object. * * @return an array of file names in the specified directory. * This list does not include the current directory or * the parent directory ("." and * ".." on Unix systems). */ public String[] list() { try { return nfs.readdir(); } catch (IOException e) { return null; } } /** * Deletes the file specified by this object. If the target * file to be deleted is a directory, it must be empty for * deletion to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ public boolean delete() { boolean ok; try { if (isFile()) ok = getParent(xf).remove(xf.getName()); else ok = getParent(xf).rmdir(xf.getName()); // Purge cached attrs & filehandle if (ok) { nfs.invalidate(); nfs = null; } return ok; } catch (Exception e) { return false; } } /** * Reads a subarray as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @exception java.io.IOException If an I/O error has occurred. */ public int read(byte b[], int off, int len, long foff) throws IOException { int c = nfs.read(b, off, len, foff); return c; } /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @exception java.io.IOException If an I/O error has occurred. */ public void write(byte b[], int off, int len, long foff) throws IOException { nfs.write(b, off, len, foff); } /** * Forces any buffered output bytes to be written out. *

* * @exception java.io.IOException if an I/O error occurs. */ public void flush() throws IOException { nfs.flush(); } /** * Close the file * * Since NFS has no concept of file close, we just * flush any buffered data. * * @exception java.io.IOException If an I/O error has occurred. */ public void close() throws IOException { nfs.close(); } /** * Returns a string representation of this object. * * @return a string giving the pathname of this object. */ public String toString() { return nfs.toString(); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/XFileExtensionAccessor.java000066400000000000000000000126551356275373100257000ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; import java.io.*; import com.sun.xfile.*; public class XFileExtensionAccessor extends com.sun.xfile.XFileExtensionAccessor { XFile xf; public XFileExtensionAccessor(XFile xf) { super(xf); if (! xf.getFileSystemName().equals("nfs")) throw new IllegalArgumentException("Invalid argument"); this.xf = xf; } /** * Sets the user's RPC credential from Login name and password. * * Every NFS request includes a "credential" that identifies the user. * An AUTH_SYS credential includes the user's UID and GID values. * These are determined from the user's login name (and password) * by the PCNFSD service that must be available on a local server. * Once the credential is set, it is assigned globally to all * future NFS XFile objects. *

* If this method is not called, a default credential is assigned * with a UID and GID of "nobody". * * @param host The name of the host that runs the PCNFSD service. * This does not have to be an NFS server. * @param username The user's login name. * @param password The user's password. * This is obscured before transmission to the PCNFSD server. * @return true if the login succeeded, false otherwise. */ public boolean loginPCNFSD(String host, String username, String password) { return NfsConnect.getCred().fetchCred(host, username, password); } /** * Sets the user's RPC credential to "nobody" */ public void logoutPCNFSD() { NfsConnect.getCred().setCred(); } /** * Sets the user's RPC credential to a known uid/gid. * * Assumes that the calling application has already * authenticated the user and has obtained to uid/gid * itself. *

* Note: This credential setting method exposes an * inherent security hole in RPC AUTH_SYS authentication. * The server trusts the client to authenticate the * user before setting the UID and GID values. It is * possible for a malicious client to allow the UID and/or * group ids to be set to allow unauthorized access to * other user's files on the server. *

* Servers can avoid this security hole by exporting NFS * filesystem securely - requiring clients to use secure * Diffie-Hellman or Kerberos credentials. * *

* If this method is not called, a default credential is assigned * with a UID and GID of "nobody". * * @param uid The user-ID. * @param gid The group-ID. * @param gids The group-ID list. */ public void loginUGID(int uid, int gid, int[] gids) { NfsConnect.getCred().setCred(uid, gid, gids); } /** * Sets the user's RPC credential to "nobody" */ public void logoutUGID() { NfsConnect.getCred().setCred(); } /** * Assigns an NfsHandler class that allows * the application to receive RPC timeout * notifications. The handler is used for all * NFS files accessed by the application. * The default handler can be restored by * passing a null handler argument. * * @param handler An instance of the NfsHandler class. */ public void setNfsHandler(NfsHandler handler) { NfsConnect.setRpcHandler(handler); } /** * Get server's export list */ public String[] getExports() throws java.net.UnknownHostException, IOException { return new Mount().getExports(new NfsURL(xf.toString()).getHost()); } } yanfs-yanfs-1.4/src/main/java/com/sun/nfs/nfsXFileExtensionAccessor.java000066400000000000000000000042621356275373100264020ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.nfs; /** * This is a compatibility stub for the NFS XFileExtensionAccessor * * @see com.sun.nfs.XFileExtensionAccessor * @deprecated The more generic XFileExtensionAccessor class * should be used instead. */ public class nfsXFileExtensionAccessor extends com.sun.nfs.XFileExtensionAccessor { public nfsXFileExtensionAccessor(com.sun.xfile.XFile xf) { super(xf); } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/000077500000000000000000000000001356275373100204335ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/rpc/ConnectDatagram.java000066400000000000000000000100441356275373100243270ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * Sets up a UDP connection to the server. * Since UDP is really connectionless, we * don't really have a connection, so perhaps * describing this as an association * is more accurate. * * This class lets us transmit and receive buffers * of data to a port on a remote server. * * @see Connection * @author Brent Callaghan */ public class ConnectDatagram extends Connection { DatagramSocket ds; DatagramPacket dp; InetAddress addr; /** * Construct a new connection to a specified server and port. * @param server The hostname of the server * @param port The port number on the server * @param maxSize The maximum size in bytes of the received message * @exception IOException if the server does not exist */ public ConnectDatagram (String server, int port, int maxSize) throws IOException { super(server, port, "udp", maxSize); ds = new DatagramSocket(); addr = InetAddress.getByName(server); start(); } void sendOne(Xdr x) throws IOException { /* * The interrupt call here is to break the listener * thread from its socket read. For some unknown * reason a datagram socket read blocks threads * attempting to send. The interrupt unblocks the * listener briefly so we can do the send. * * The blocking problem appears to be fixed as * of JDK 1.1.6, so the interrupt is skipped removed. */ //interrupt(); ds.send(new DatagramPacket(x.xdr_buf(), x.xdr_offset(), addr, port)); } void receiveOne(Xdr x, int timeout) throws IOException { ds.setSoTimeout(timeout); dp = new DatagramPacket(x.xdr_buf(), x.xdr_buf().length); ds.receive(dp); } InetAddress getPeer() { return dp.getAddress(); } /* * No connection to drop. */ void dropConnection() { } /* * No connection to check */ void checkConnection() { } protected void finalize() throws Throwable { if (ds != null) { ds.close(); ds = null; } super.finalize(); } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/ConnectSocket.java000066400000000000000000000226721356275373100240510ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; import java.net.Socket; import java.net.InetAddress; /** * Sets up a TCP connection to the server. * * This class lets us transmit and receive buffers * of data to a port on a remote server. * It also handles reconnection of broken TCP links. * * @see Connection * @author Brent Callaghan */ public class ConnectSocket extends Connection { static final int LAST_FRAG = 0x80000000; static final int SIZE_MASK = 0x7fffffff; static final int MTUSZ = 1460 - 4; // good for Ethernet private OutputStream outs; private InputStream ins; private Socket sock; Xdr rcv_mark = new Xdr(4); /** * Construct a new connection to a specified server and port. * * @param server The hostname of the server * @param port The port number on the server * @param maxSize The maximum size of the received reply * @exception IOException if the connection cannot be made */ public ConnectSocket (String server, int port, int maxSize) throws IOException { super(server, port, "tcp", maxSize); doConnect(); start(); // the listener } private void doConnect() throws IOException { if (server == null) throw new java.net.UnknownHostException("null host"); sock = new Socket(server, port); sock.setTcpNoDelay(true); ins = sock.getInputStream(); outs = sock.getOutputStream(); } private void doClose() throws IOException { if (ins != null) { ins.close(); ins = null; } if (outs != null) { outs.close(); outs = null; } if (sock != null) { sock.close(); sock = null; } } void sendOne(Xdr x) throws IOException { int recsize; int lastbit = 0; int bufsiz = x.xdr_offset(); int save; /* * Use the connection only if unlocked. * Otherwise we risk attempting a sendOne() * while it's being reconnected. We also * need to protect threads from a concurrent * sendOne that may interleave record data. */ synchronized (this) { /* * The XDR buffer needs to be transmitted on the * socket outputstream in MTUSZ records. In RPC * over TCP each of these records begins with a * 32 bit record mark which comprises a byte * count for the record and a LAST_FRAG bit which * is set on the last record. * * You'll notice that the code goes through some * hoops to prepend this record mark on each of * the records transmitted from the XDR buffer * WITHOUT COPYING THE DATA. * Notice that there's a 4 octet space inserted at * the front of the buffer for the first record * mark by the code that builds the RPC header. * Space is taken from the buffer for subsequent * record marks and the data in this space is * saved and restored after the record is sent, * so hopefully we leave things as they were * when we're done. * * BTW: this code originally wrote the record * mark to the OutputStream separately, but the * JVM doesn't seem to be doing Nagle and the * record mark sailed off in its own tiny TCP * segment separate from the rest of the record, * which wasn't what I had in mind. */ for (int off = 4; off < bufsiz; off += recsize) { /* * Insert the record mark */ recsize = bufsiz - off; if (recsize > MTUSZ) recsize = MTUSZ; if ((off + recsize) >= bufsiz) lastbit = LAST_FRAG; x.xdr_offset(off-4); save = x.xdr_int(); x.xdr_offset(off-4); x.xdr_int(lastbit | recsize); /* * then send the record data */ outs.write(x.xdr_buf(), off-4, recsize+4); outs.flush(); x.xdr_offset(off-4); x.xdr_int(save); } x.xdr_offset(bufsiz); // restore XDR offset } } void receiveOne(Xdr x, int timeout) throws IOException { int off; int rcount; boolean lastfrag = false; long recsize; sock.setSoTimeout(timeout); try { for (off = 0; !lastfrag; off += recsize) { /* * Read the record mark */ if (ins.read(rcv_mark.xdr_buf()) != 4) throw new IOException("TCP record mark: lost connection"); rcv_mark.xdr_offset(0); recsize = rcv_mark.xdr_u_int(); lastfrag = (recsize & LAST_FRAG) != 0; recsize &= SIZE_MASK; /* * then read the record data */ for (int i = 0; i < recsize; i += rcount) { rcount = ins.read(x.xdr_buf(), off + i, (int) recsize - i); if (rcount < 0) throw new IOException("TCP data: lost connection"); } } x.xdr_size(off); } catch (java.io.InterruptedIOException e) { throw e; } catch (IOException e) { /* * Assume something bad happened to the connection. * Close the connection and attempt to reconnect. */ reconnect(); throw e; } } /* * Get the address of the caller. * This is needed when we get a reply from * and RPC to a broadcast address. */ InetAddress getPeer() { return sock.getInetAddress(); } /* * This method is called when it is suspected that * the connection has been broken. It keeps retrying * connection attempts until it is successful. */ void reconnect() { System.err.println("Lost connection to " + server + " - attempting to reconnect"); /* * Lock the connection while we're messing * with it so that another thread can't * attempt a sendOne() on it. */ synchronized (this) { while (true) { try { doClose(); // make sure we're at a known state doConnect(); break; // success } catch (IOException e) { /* * Wait here for 5 sec so's we don't * overwhelm the server with connection requests. */ try { java.lang.Thread.sleep(5000); } catch (java.lang.InterruptedException i) { } } } } System.err.println("Reconnected to " + server); } /* * The listener calls this after an idle timeout. * Be kind to the server and drop the connection. */ void dropConnection() { try { doClose(); } catch (IOException e) {}; } /* * Check to make sure that the connection is up. * If not, then reconnect and resume the listener. */ void checkConnection() { if (sock != null) return; reconnect(); } protected void finalize() throws Throwable { doClose(); super.finalize(); } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/Connection.java000066400000000000000000000176041356275373100234050ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; import java.util.Hashtable; import java.net.InetAddress; /** * Sets up a connection to the server using * either UDP or TCP as determined by the * subclass. * * This class also handles the connection caching. * * @see ConnectSocket * @see ConnectDatagram * @author Brent Callaghan */ public abstract class Connection extends Thread { static Hashtable connections = new Hashtable(); public String server; public int port; String proto; Hashtable waiters = new Hashtable(); static final int IDLETIME = 300 * 1000; // idle connection after 5 min int xid; // transaction id Xdr reply; int maxSize; // size of reply Xdr buffer Error err; // might get thrown by the thread /** * Construct a new connection to a specified server * and port using protocol proto with a * reply buffer of size maxsize. * * @param server The hostname of the server * @param port The port number on the server */ public Connection (String server, int port, String proto, int maxSize) { this.server = server; this.port = port; this.proto = proto; this.maxSize = maxSize; setName("Listener-" + server); setDaemon(true); } /** * Get a cached connection for the specified server, port and protocol * * @param server The hostname of the server * @param port The port number on the server * @param proto The connection type: "tcp" or "udp" * @returns null If there is no cached connection */ public static Connection getCache(String server, int port, String proto) { Connection conn = (Connection) connections.get( server + ":" + port + ":" + proto); return conn; } /** * Stash a new connection in the cache * * @param The connection to be cached */ public static void putCache(Connection conn) { connections.put(conn.server + ":" + conn.port + ":" + conn.proto, conn); } abstract void sendOne(Xdr call) throws IOException; abstract void receiveOne(Xdr reply, int timeout) throws IOException; abstract InetAddress getPeer(); abstract void dropConnection(); abstract void checkConnection(); /** * Return information about the connection * * @returns server, port number and protocol info. */ public String toString() { return (server + ":" + port + ":" + proto); } private boolean running; synchronized void suspendListener() { running = false; while (!running) { try { wait(); } catch (InterruptedException e) {} } } synchronized void resumeListener() { running = true; notifyAll(); } synchronized Xdr send(Xdr call, int timeout) throws IOException { checkConnection(); resumeListener(); sendOne(call); waiters.put(new Integer(call.xid), new Integer(timeout)); /* * Now sleep until the listener thread posts * my XID and notifies me - or I time out. */ while (xid != call.xid) { long t = System.currentTimeMillis(); if (err != null) throw err; try { wait(timeout); } catch (InterruptedException e) {} if (err != null) throw err; timeout -= (System.currentTimeMillis() - t); if (timeout <= 0) { waiters.remove(new Integer(call.xid)); throw new InterruptedIOException(); // timed out } } /* * My reply has come in. */ xid = 0; waiters.remove(new Integer(call.xid)); notifyAll(); // wake the listener return reply; } /* * This is the code for the listener thread. * It blocks in a receive waiting for an RPC * reply to come in, then delivers it to the * appropriate thread. */ public void run() { try { while (true) { synchronized (this) { while (xid != 0) { try { wait(); } catch (InterruptedException e) {} } } reply = new Xdr(maxSize); /* * The listener thread now blocks reading * from the socket until either a packet * comes in - or it gets an idle timeout. */ try { receiveOne(reply, IDLETIME); } catch (InterruptedIOException e) { /* * Got an idle timeout. If there's * no threads waiting then drop the * connection and suspend. */ if (waiters.isEmpty()) dropConnection(); suspendListener(); } catch (IOException e) { continue; } /* * Have received an Xdr buffer. * Extract the xid and check the hashtable * to see if there's thread waiting for that reply. * If there is, then notify the thread. If not * then ignore the reply (its thread may * have timed out and gone away). */ synchronized (this) { xid = reply.xdr_int(); if (waiters.containsKey(new Integer(xid))) notifyAll(); else xid = 0; // ignore it } } } catch (Error e) { /* * Need to catch errors here, e.g. OutOfMemoryError * and notify threads before this listener thread dies * otherwise they'll wait forever. */ this.err = e; synchronized (this) { notifyAll(); } throw e; } } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/Cred.java000066400000000000000000000057741356275373100221700ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; /** * RPC Credentials * * Extended by each credential class */ public abstract class Cred { // service types: authentication, integrity and privacy public static final int SVC_NONE = 1; public static final int SVC_INTEGRITY = 2; public static final int SVC_PRIVACY = 3; /** * Put creds into an XDR buffer */ abstract void putCred(Xdr x) throws RpcException; /** * Get creds from an XDR buffer */ abstract void getCred(Xdr x); /** * Initiate a security context with peers */ abstract void init(Connection conn, int prog, int vers) throws RpcException; /** * Refresh the cred */ abstract boolean refresh(Connection conn, int prog, int vers); /** * Encrypt an XDR buffer */ abstract void wrap(Xdr x, byte[] arg) throws RpcException; /** * Descrypt an XDR buffer */ abstract int unwrap(Xdr x) throws RpcException; /** * Validate the response verifier from server */ abstract void validate(byte[] verifier, int verifiee) throws RpcException; /** * Destroy the cred data and its security context with the server */ abstract void destroy(Rpc rpc) throws RpcException; } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/CredGss.java000066400000000000000000000416651356275373100226440ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; import com.sun.gssapi.*; /** * The credential class for the RPCSEC_GSS security flavor. * * @see Cred * @author Lin Ling * */ public class CredGss extends Cred { /* * These are the data needed for setting up RPCSEC_GSS dialog. */ public int serviceType; // authenticate, integrity or privacy Oid mechOid; int qop; String serviceName; // e.g. "nfs" is a service name int seq_num_out; // sequence number in the out going request int seq_window; int control; // RPCSEC_GSS_INIT or RPCSEC_GSS_DATA ...etc GSSContext gssCtx; // context object for gss operations byte[] ctx_handle; // context handle for the security context public static final int RPCSEC_GSS = 6; public static final int RPCSEC_GSS_DATA = 0; public static final int RPCSEC_GSS_INIT = 1; public static final int RPCSEC_GSS_CONTINUE_INIT = 2; public static final int RPCSEC_GSS_DESTROY = 3; public static final int RPCSEC_GSS_VERS_1 = 1; private static final int RPCGSS_MAXSZ = 1024; private static final int PROC_NULL = 0; /** * Constructor creates an instance of RPCSEC_GSS credential with * given service name, mechanism, service type and qop number. * * @param svcName the target service name * @param mech the string format of mech oid; e.g. "1.2.3.4.5" * @param svcType none, integrity or privacy * @param qop_num the number of quality protection */ public CredGss(String svcName, String mech, int svcType, int qop_num) throws IOException { try { mechOid = new Oid(mech); } catch (GSSException e) { throw new IOException ("can not construct CredGss object"); } serviceName = svcName; serviceType = svcType; qop = qop_num; seq_num_out = 0; ctx_handle = null; gssCtx = null; control = RPCSEC_GSS_INIT; } /** * Constructor creates an instance of RPCSEC_GSS credential with * given service name, mechanism, service type and qop number. * * @param svcName the target service name * @param mech the GSS Oid object of the mech * @param svcType none, integrity or privacy * @param qop_num the number of quality protection */ public CredGss(String svcName, Oid mech, int svcType, int qop_num) { mechOid = mech; serviceName = svcName; serviceType = svcType; qop = qop_num; seq_num_out = 0; ctx_handle = null; gssCtx = null; control = RPCSEC_GSS_INIT; } /** * Put RPCSEC_GSS cred/verf into an XDR buffer * * @param xdr buffer */ synchronized void putCred(Xdr x) throws RpcException { MessageProp mInfo = new MessageProp(qop, false); /* * Marshalling the cred field */ x.xdr_int(RPCSEC_GSS); /* * For every data request (including retransmit) * use a different sequence number. */ if (control == RPCSEC_GSS_DATA || control == RPCSEC_GSS_DESTROY) seq_num_out++; /* * If a context is established, encode the context handle. * otherwise, encode a 0 length field. */ if (ctx_handle != null) { // length = 20 + ctx_handle.length x.xdr_int(20 + ctx_handle.length); x.xdr_int(RPCSEC_GSS_VERS_1); x.xdr_int(control); x.xdr_int(seq_num_out); x.xdr_int(serviceType); x.xdr_bytes(ctx_handle); } else { // length = 20 x.xdr_int(20); x.xdr_int(RPCSEC_GSS_VERS_1); x.xdr_int(control); x.xdr_int(seq_num_out); x.xdr_int(serviceType); x.xdr_int(0); } /* * Marshalling the verifier field */ if (gssCtx != null) { // Checksum the header data upto cred field. try { byte[] headerMIC = gssCtx.getMIC(x.xdr_buf(), 0, x.xdr_offset(), mInfo); x.xdr_int(RPCSEC_GSS); x.xdr_bytes(headerMIC); } catch (GSSException e) { throw new RpcException("can not checksum the header"); } } else { // if context is not established yet, use null verifier x.xdr_int(CredNone.AUTH_NONE); x.xdr_int(0); } x.xdr_wrap_offset(x.xdr_offset()); if (control == RPCSEC_GSS_DATA && serviceType != SVC_NONE) { x.xdr_int(seq_num_out); } } public void getCred(Xdr x) { // No-Op } /* * Send rpcsec_gss init control requests. Retry if time out. * * This routine is similar to rpc.rpc_call() but is customized for the * rpcsec_gss init sec context handshakes. * * For init control requests, when it needs to do a refresh, it does * not need to retry the original init call after the cred is refreshed. * (upon a successful refresh, a context is established) * Use this routine instead of rpc_call() to avoid confusion. */ private Xdr rpc_send(Rpc rpc, Xdr call, int timeout, int retries) throws RpcException, IOException { Xdr reply = null; if (retries == 0) { retries = Integer.MAX_VALUE; //retry forever } for (int c = 0; c < retries; c++) { /* * This is for init control requests, not a data request. * No argument for wrapping. */ try { reply = rpc.rpc_call_one(call, null, timeout); break; // reply received OK } catch (RpcException e) { throw e; } catch (IOException e) { // probably a timeout. retry continue; } } if (reply == null) // reached retry limit throw new InterruptedIOException(); return reply; } /** * Init a security context using the given connection instance. * * @param conn The connection to the server * @param prog The program number of the rpc service * @param vers The version number of the rpc service */ synchronized void init(Connection conn, int prog, int vers) throws RpcException { byte[] inTok = new byte[0]; Rpc secRpc; Xdr secCall, secReply; CredGss initCred; int major = 0, minor = 0; try { GSSContext ctx = new GSSContext(new GSSName(serviceName, GSSName.NT_HOSTBASED_SERVICE), mechOid, null, 0); // set context options ctx.requestConf(true); ctx.requestInteg(true); ctx.requestMutualAuth(true); ctx.requestReplayDet(true); ctx.requestSequenceDet(true); initCred = new CredGss(serviceName, mechOid, serviceType, qop); secRpc = new Rpc(conn, prog, vers, initCred); secCall = new Xdr(RPCGSS_MAXSZ); /* * gss token exchange semantics: * * (1 token) * Client Server * init stat = complete * token length > 0 ---> token --> accept stat = complete * token.len = 0 * * (2 tokens) * Client Server * init stat = cont * token.length > 0 ---> token ---> accept stat = complete * token.len > 0 * <--- token <--- * init stat = complete * token.length = 0 * * (3 tokens) * Client Server * init stat = cont * token.length > 0 ---> token ---> accept stat = cont * token.length > 0 * <--- token <--- * init stat = complete * token.length > 0 ---> token ---> accept stat = complete * token.length = 0 */ initCred.control = RPCSEC_GSS_INIT; int num_refresh = 2; do { byte[] outTok = ctx.init(inTok, 0, inTok.length); if (outTok != null) { secRpc.rpc_header(secCall, PROC_NULL); secCall.xdr_bytes(outTok); try { secReply = rpc_send(secRpc, secCall, 30 * 1000, 5); } catch (MsgRejectedException e) { if (num_refresh > 0 && (e.why == MsgRejectedException.RPCSEC_GSS_NOCRED || e.why == MsgRejectedException.RPCSEC_GSS_FAILED)) { // reset the parameters and retry (refresh) inTok = new byte[0]; ctx = new GSSContext(new GSSName(serviceName, GSSName.NT_HOSTBASED_SERVICE), mechOid, null, 0); ctx.requestConf(true); ctx.requestInteg(true); ctx.requestMutualAuth(true); ctx.requestReplayDet(true); ctx.requestSequenceDet(true); initCred.gssCtx = null; initCred.ctx_handle = null; initCred.control = RPCSEC_GSS_INIT; num_refresh--; continue; } else { throw e; } } catch (RpcException e) { throw e; } // decode the result and get the context id this.ctx_handle = secReply.xdr_bytes(); major = secReply.xdr_int(); minor = secReply.xdr_int(); if (major != GSSContext.COMPLETE && major != GSSContext.CONTINUE_NEEDED) { throw new RpcException("cred.init server failed"); } this.seq_window = secReply.xdr_int(); inTok = secReply.xdr_bytes(); // token from the server if (!ctx.isEstablished() && inTok == null) { throw new RpcException("cred.init:bad token"); } } else if (major == GSSContext.CONTINUE_NEEDED) { // no more token, but server is waiting for one throw new RpcException("cred.init:server needs token"); } initCred.control = RPCSEC_GSS_CONTINUE_INIT; initCred.ctx_handle = ctx_handle; } while (!ctx.isEstablished()); this.gssCtx = ctx; this.control = RPCSEC_GSS_DATA; } catch (IOException e) { throw new RpcException("cred.init: io errors "); } catch (GSSException e) { throw new RpcException("cred.init: gss errors"); } } /** * Refresh the RPCSEC_GSS credential. * Nulled context and ctx_handle and re-try init sec context. * * @param conn The connection to the server * @param prog The program number of the rpc service * @param vers The version number of the rpc service * @return true if success */ synchronized boolean refresh(Connection conn, int prog, int vers) { // If no context has established, don't try to recreate it. if (ctx_handle == null) { return false; } gssCtx = null; ctx_handle = null; try { init(conn, prog, vers); return true; } catch (RpcException e) { return false; } } /** * Use this cred object to encrypt the given xdr buffer. * * @param call xdr buffer * @param arg the rpc argument to be encrypted * @return the xdr buffer with the encrypted data */ synchronized void wrap(Xdr call, byte[] arg) throws RpcException { byte[] argTok; MessageProp mInfo = new MessageProp(qop, false); if (control != RPCSEC_GSS_DATA) { return; } try { switch (serviceType) { case SVC_NONE: break; case SVC_INTEGRITY: argTok = gssCtx.getMIC(arg, 0, arg.length, mInfo); call.xdr_offset(call.xdr_wrap_offset()); call.xdr_bytes(arg); call.xdr_bytes(argTok); break; case SVC_PRIVACY: mInfo.setPrivacy(true); argTok = gssCtx.wrap(arg, 0, arg.length, mInfo); call.xdr_offset(call.xdr_wrap_offset()); call.xdr_bytes(argTok); break; } } catch (GSSException e) { throw new RpcException("wrap: Can not wrap RPC arg"); } } /** * Use this cred object to decrypt the given xdr buffer. * * @param reply xdr buffer * @return the xdr buffer with the unencrypted data */ synchronized int unwrap(Xdr reply) throws RpcException { int result_off, result_len, verify_off, csum_len, seq_num_in = 0; byte[] result; MessageProp mInfo = new MessageProp(); if (control != RPCSEC_GSS_DATA) { return 0; } result_off = reply.xdr_offset(); switch (serviceType) { case SVC_NONE: return 0; case SVC_INTEGRITY: result_len = reply.xdr_int(); if (result_len <= 4) // length of (seq num + rpc arg) is 0 or 4 return 0; verify_off = reply.xdr_offset(); // offset of (seq num + rpc arg) seq_num_in = reply.xdr_int(); /* * When server is slow, it is possible that client will * receive packets in different order. Seqence window should be * the maximum number of client requests that maybe outstanding * for this context. The this.seq_window is set to the sequence * window length supported by the server for this context. */ if ((seq_num_in < (seq_num_out - seq_window)) || (seq_num_in > seq_num_out)) { throw new RpcException("unwrap: bad sequence number"); } result = reply.xdr_raw(result_len - 4); // 4-length of seq num csum_len = reply.xdr_int(); try { gssCtx.verifyMIC(reply.xdr_buf(), reply.xdr_offset(), csum_len, reply.xdr_buf(), verify_off, result_len, mInfo); } catch (GSSException e) { throw new RpcException("unwrap: gss_verifyMIC failed"); } if (mInfo.getQOP() != qop) { throw new RpcException("unwrap: unexpected qop"); } reply.xdr_offset(result_off); reply.xdr_raw(result); reply.xdr_offset(result_off); break; case SVC_PRIVACY: result_len = reply.xdr_int(); if (result_len == 0) return 0; try { result = gssCtx.unwrap(reply.xdr_buf(), reply.xdr_offset(), result_len, mInfo); } catch (GSSException e) { throw new RpcException("unwrap: gss_unwrap failed"); } if (mInfo.getQOP() != qop) { throw new RpcException("unwrap: unexpected qop"); } reply.xdr_offset(result_off); reply.xdr_raw(result); reply.xdr_offset(result_off); seq_num_in = reply.xdr_int(); if ((seq_num_in < (seq_num_out - seq_window)) || (seq_num_in > seq_num_out)) { throw new RpcException("unwrap: bad sequence number"); } break; } return seq_num_in; } /** * Validate RPC response verifier from server. The response verifier * is the checksum of the request sequence number. * * @param snumber the sequence number * @param token the verifier */ synchronized void validate(byte[] token, int snumber) throws RpcException { if (control != RPCSEC_GSS_DATA) return; MessageProp mInfo = new MessageProp(); // create a buffer for the sequence number in the net order byte[] msg = new byte[4]; msg[0] = (byte)(snumber >>> 24); msg[1] = (byte)(snumber >> 16); msg[2] = (byte)(snumber >> 8); msg[3] = (byte)snumber; try { gssCtx.verifyMIC(token, 0, token.length, msg, 0, msg.length, mInfo); } catch (GSSException e) { throw new RpcException("CredGss: validate failed"); } } /** * Delete the RPC credential data and destroy its security * context with the server. * * @param rpc delete the security context of this Rpc object */ synchronized void destroy(Rpc rpc) throws RpcException { if (gssCtx != null) { try { Xdr secCall = new Xdr(RPCGSS_MAXSZ); control = CredGss.RPCSEC_GSS_DESTROY; rpc.rpc_header(secCall, PROC_NULL); rpc.rpc_call(secCall, 30 * 1000, 5); gssCtx.dispose(); mechOid = null; gssCtx = null; ctx_handle = null; } catch (IOException e) { } catch (GSSException e) { /* * If the request to destroy the context fails for some * reason, the client need not take any special action. * The server must be prepared to deal with situations * where clients never inform the server to maintain * a context. */ return; } } } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/CredNone.java000066400000000000000000000056161356275373100230030ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; /** * This is the "NONE" credential, i.e. no credential * It's the default credential for RPC unless set * to something else. */ public class CredNone extends Cred { static final int AUTH_NONE = 0; /** * Put "no" creds into an XDR buffer */ void putCred(Xdr x) { x.xdr_int(AUTH_NONE); x.xdr_int(0); // no cred data x.xdr_int(0); // no verifier x.xdr_int(0); // no verifier } /** * Get "no" creds from an XDR buffer */ void getCred(Xdr x) { x.xdr_int(); // assume it's AUTH_NONE x.xdr_int(); // cred length == 0 x.xdr_int(); // no verifier x.xdr_int(); // no verifier } void init(Connection conn, int prog, int vers) { // No-op } boolean refresh(Connection conn, int prog, int vers) { // No-op return true; } void wrap(Xdr x, byte[] arg) { // No-op } int unwrap(Xdr x) { // No-op return 0; } void validate(byte[] verifier, int verifiee) { // No-op } void destroy(Rpc rpc) { // No-op } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/CredUnix.java000066400000000000000000000217561356275373100230320ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; /** * The Unix credential. Contains information specific * to Unix users and NFS: uid/gid/grplist */ public class CredUnix extends Cred { /* * These are the data normally * found in a Unix credential. */ private int uid; private int gid; private int[] gids; /* * These are additional info provided by * version 2 of PCNFSD. */ private String home; private int def_umask; public int status; /* * Default credential values */ static final int AUTH_UNIX = 1; static final int UID_NOBODY = 60001; static final int GID_NOBODY = 60001; /* * Constants for PCNFSD protocol */ private static final int PCNFSDPROG = 150001; private static final int PCNFSD_AUTH = 1; private static final int PCNFSD2_AUTH = 13; private static final int MAXREPLY = 512; static final int AUTH_RES_OK = 0; static final int AUTH_RES_FAKE = 1; static final int AUTH_RES_FAIL = 2; private Xdr cr = new Xdr(64); /** * Constructor creates an instance of * Unix credential with given uid/gid */ public CredUnix(int uid, int gid) { this.uid = uid; this.gid = gid;; } /** * Constructor creates an instance of * Unix credential and sets default uid/gid * to "nobody". */ public CredUnix() { this(UID_NOBODY, GID_NOBODY); } /** * Put Unix creds into an XDR buffer * * @param xdr buffer */ synchronized void putCred(Xdr x) { x.xdr_int(AUTH_UNIX); cr.xdr_offset(0); cr.xdr_int((int) (System.currentTimeMillis()/1000)); cr.xdr_string("javaclient"); cr.xdr_int(uid); cr.xdr_int(gid); if (gids == null) cr.xdr_int(0); else { cr.xdr_int(gids.length); for (int i = 0; i < gids.length; i++) cr.xdr_int(gids[i]); } x.xdr_bytes(cr); x.xdr_int(0); // no verifier x.xdr_int(0); // no verifier } /** * Get Unix creds from an XDR buffer * * @param xdr buffer */ void getCred(Xdr x) { x.xdr_int(); // assume it's AUTH_UNIX x.xdr_int(); // cred length x.xdr_int(); // timestamp x.xdr_string(); // hostname uid = x.xdr_int(); gid = x.xdr_int(); int count = x.xdr_int(); if (count > 0) { gids = new int[count]; for (int i = 0; i < count; i++) gids[i] = x.xdr_int(); } x.xdr_int(); // no verifier x.xdr_int(); // no verifier } /** * Given a username and passwd, obtain Unix creds * from the named server. This is not necessarily * an NFS server. * * If we fail then the creds are unaffected. * * @param server Name of the pcnfsd server that will return the creds. * @param username the login name of the user. * @param passwd of the user. * */ public boolean fetchCred(String server, String username, String passwd) { username = disguise(username); passwd = disguise(passwd); try { try { return (callV2(server, username, passwd)); } catch (MsgAcceptedException e) { if (e.error != e.PROG_MISMATCH) return false; return (callV1(server, username, passwd)); } } catch (IOException e) { return false; } } /** * Set the cred back to the default: nobody/nobody */ public void setCred() { uid = UID_NOBODY; gid = GID_NOBODY; gids = null; } /** * Set the uid, gid */ public void setCred(int uid, int gid, int[] gids) { this.uid = uid; this.gid = gid; this.gids = gids; } /* * Disguise the string so that it's not * obvious to a casual snooper. */ private String disguise(String s) { byte[] b = s.getBytes(); for (int i = 0; i < b.length; i++) b[i] = (byte)((b[i] & 0x7f) ^ 0x5b); return (new String(b)); } /** * Get the Unix user id for the user * @return uid */ public int getUid() { return uid; } /** * Get the Unix group id for the user * @return gid */ public int getGid() { return gid; } /** * Get the Unix group list for the user * @return gids */ public int[] getGids() { return gids; } /** * Get the user's home directory path * @return pathname of home directory. */ public String getHome() { return home; } /** * Get the user's home Unix umask * @return umask */ public int getUmask() { return def_umask; } private boolean callV1(String server, String username, String passwd) throws java.net.UnknownHostException, IOException { Rpc pc = new Rpc(server, 0, PCNFSDPROG, 1, "udp", MAXREPLY); Xdr call = new Xdr(MAXREPLY); pc.rpc_header(call, PCNFSD_AUTH); call.xdr_string(username); call.xdr_string(passwd); Xdr reply = pc.rpc_call(call, 10 * 1000, 2); status = reply.xdr_int(); if (status == AUTH_RES_FAIL) return false; uid = reply.xdr_int(); gid = reply.xdr_int(); gids = null; home = null; def_umask = 0; return true; } private boolean callV2(String server, String username, String passwd) throws java.net.UnknownHostException, IOException { Rpc pc = new Rpc(server, 0, PCNFSDPROG, 2, "udp", MAXREPLY); Xdr call = new Xdr(MAXREPLY); pc.rpc_header(call, PCNFSD2_AUTH); call.xdr_string("(anyhost)"); // XXX should be hostname call.xdr_string(username); call.xdr_string(passwd); call.xdr_string("Java client"); // comment Xdr reply = pc.rpc_call(call, 10 * 1000, 2); status = reply.xdr_int(); if (status == AUTH_RES_FAIL) return false; uid = reply.xdr_int(); gid = reply.xdr_int(); gids = new int[reply.xdr_int()]; for (int i = 0; i < gids.length; i++) gids[i] = reply.xdr_int(); home = reply.xdr_string(); def_umask = reply.xdr_int(); return true; } public String toString() { String s = "AUTH_UNIX:\n uid=" + uid + ",gid=" + gid + "\n"; if (gids != null) { s += " gids="; for (int i = 0; i < gids.length; i++) s += gids[i] + " "; } if (home != null) s += "\n home=" + home; if (def_umask != 0) s += "\n umask=0" + Long.toOctalString(def_umask); return s; } public void init(Connection conn, int prog, int vers) { // No-op } public boolean refresh(Connection conn, int prog, int vers) { // No-op return true; } public void wrap(Xdr x, byte[] arg) { // No-op } public int unwrap(Xdr x) { // No-op return 0; } public void validate(byte[] verifier, int verifiee) { // No-op } public void destroy(Rpc rpc) { // No-op } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/MsgAcceptedException.java000066400000000000000000000066321356275373100253430ustar00rootroot00000000000000/* * Copyright (c) 1997, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; /** * * Handle the RPC "message accepted" class of errors. * * Note that some of the errors also convey low and high * version information. * * @see RpcException * @author Brent Callaghan */ public class MsgAcceptedException extends RpcException { int lo, hi; public static final int PROG_UNAVAIL = 1; public static final int PROG_MISMATCH = 2; public static final int PROC_UNAVAIL = 3; public static final int GARBAGE_ARGS = 4; public static final int SYSTEM_ERR = 5; /* * Construct a new Exception for the specified RPC accepted error * @param error The RPC error number */ public MsgAcceptedException(int error) { super(error); } /* * Construct a new RPC error with the given low and high parameters * @param error The RPC error number * @param lo The low version number * @param hi The high version number */ public MsgAcceptedException(int error, int lo, int hi) { super(error); this.lo = lo; this.hi = hi; } public String toString() { switch (error) { case PROG_UNAVAIL: return "Program unavailable"; case PROG_MISMATCH: return "Program number mismatch: " + "low=" + lo + ",high=" + hi; case PROC_UNAVAIL: return "Procedure Unavailable: " + "low=" + lo + ",high=" + hi; case GARBAGE_ARGS: return "Garbage Arguments"; case SYSTEM_ERR: return "System error"; default: return "Unknown RPC Error = " + error; } } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/MsgRejectedException.java000066400000000000000000000114221356275373100253510ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; /** * * Handle the RPC "message rejected" class of errors. * * Note that some of the errors also convey low and high * version information or an authentication sub-error. * * @see RpcException * @author Brent Callaghan */ public class MsgRejectedException extends RpcException { public static final int RPC_MISMATCH = 0; public static final int AUTH_ERROR = 1; public static final int AUTH_BADCRED = 1; public static final int AUTH_REJECTEDCRED = 2; public static final int AUTH_BADVERF = 3; public static final int AUTH_REJECTEDVERF = 4; public static final int AUTH_TOOWEAK = 5; public static final int AUTH_INVALIDRESP = 6; public static final int AUTH_FAILED = 7; public static final int RPCSEC_GSS_NOCRED = 13; public static final int RPCSEC_GSS_FAILED = 14; /* * Construct a new Exception for the specified RPC accepted error * @param error The RPC error number */ public MsgRejectedException(int error) { super(error); } /* * Construct a new RPC error with the given auth sub-error * @param error The RPC error number * @param why The auth sub-error */ public MsgRejectedException(int error, int why) { super(error); this.why = why; } /* * Construct a new RPC error with the given low and high parameters * @param error The RPC error number * @param lo The low version number * @param hi The high version number */ public MsgRejectedException(int error, int lo, int hi) { super(error); this.lo = lo; this.hi = hi; } public String toString() { switch (error) { case RPC_MISMATCH: return "Version mismatch: " + "low=" + lo + ",high=" + hi; case AUTH_ERROR: String msg = "Authentication error: "; switch (why) { case AUTH_BADCRED: msg += "bogus credentials (seal broken)"; break; case AUTH_REJECTEDCRED: msg += "client should begin new session"; break; case AUTH_BADVERF: msg += "bogus verifier (seal broken)"; break; case AUTH_REJECTEDVERF: msg += "verifier expired or was replayed"; break; case AUTH_TOOWEAK: msg += "too weak"; break; case AUTH_INVALIDRESP: msg += "bogus response verifier"; break; case RPCSEC_GSS_NOCRED: msg += "no credentials for user"; break; case RPCSEC_GSS_FAILED: msg += "GSS failure, credentials deleted"; break; case AUTH_FAILED: default: msg += "unknown reason"; break; } return msg; default: return "Unknown RPC Error = " + error; } } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/Rpc.java000066400000000000000000000361321356275373100220270ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; import java.net.InetAddress; /** * * This class transmits and receives RPC calls to an RPC service * at a specific host and port. * * @see Connection * @see RpcException * @see MsgAcceptedException * @see MsgDeniedException * @author Brent Callaghan */ public class Rpc { public Connection conn; int prog; int vers; Cred cred; RpcHandler rhandler = new RpcHandler(); private static int xid = (int) System.currentTimeMillis() & 0x0fffffff; private static final int PMAP_PROG = 100000; private static final int PMAP_PORT = 111; private static final int PMAP_VERS = 2; private static final int PMAP_GETPORT = 3; private static final int PMAP_MAXSZ = 128; private static final int MAX_TIMEOUT = 30 * 1000; // 30 sec private static final int MAX_REPLY = 8192 + 256; /** * Construct a new Rpc object - equivalent to a "client handle" * using an AUTH_NONE cred handle. * * @param conn A connection to the server * @param prog The program number of the service * @param vers The version number of the service */ public Rpc(Connection conn, int prog, int vers) { this.conn = conn; this.prog = prog; this.vers = vers; cred = new CredNone(); } /** * Construct a new Rpc object - equivalent to a "client handle" * using a given cred handle "cr" * * @param conn A connection to the server * @param prog The program number of the service * @param vers The version number of the service * @param cr The cred to be used: CredUnix or CredGss */ public Rpc(Connection conn, int prog, int vers, Cred cr) { this.conn = conn; this.prog = prog; this.vers = vers; cred = cr; } /** * Construct a new Rpc object - equivalent to a "client handle" * * @param server The hostname of the server * @param port The port number for the service * @param prog The program number of the service * @param vers The version number of the service * @param proto The protocol to be used: "tcp" or "udp" * @param maxReply The maximum size of the RPC reply * @exception IOException if an I/O error occurs */ public Rpc(String server, int port, int prog, int vers, String proto, int maxReply) throws IOException { this.conn = getConnection(server, port, prog, vers, proto, maxReply); this.prog = prog; this.vers = vers; cred = new CredNone(); } private Connection getConnection(String server, int port, int prog, int vers, String proto, int maxReply) throws IOException { if (port == 0) { Rpc pmap = new Rpc(server, PMAP_PORT, PMAP_PROG, PMAP_VERS, "udp", PMAP_MAXSZ); Xdr call = new Xdr(PMAP_MAXSZ); pmap.rpc_header(call, PMAP_GETPORT); call.xdr_int(prog); call.xdr_int(vers); call.xdr_int(proto.equals("tcp") ? 6 : 17); call.xdr_int(0); // no port Xdr reply = pmap.rpc_call(call, 5 * 1000, 3); port = reply.xdr_int(); if (port == 0) throw new MsgAcceptedException(PROG_UNAVAIL); } /* * Check the connection cache first to see * if there's a connection already set up * for this port, server and protocol. This is * particularly important for TCP with its * high connection overhead. * * The code is synchronized to prevent concurrent * threads from missing the cache and setting * up multiple connections. */ synchronized (Connection.connections) { conn = Connection.getCache(server, port, proto); if (conn == null) { if (proto.equals("tcp")) conn = new ConnectSocket(server, port, maxReply); else conn = new ConnectDatagram(server, port, maxReply); Connection.putCache(conn); } } return conn; } /** * Set the RPC credential * * @param c - cred to be used */ public void setCred(Cred c) throws RpcException { cred = c; cred.init(conn, prog, vers); } /** * Delete the RPC credential data and destroy its security * context with the server. */ public void delCred() throws RpcException { cred.destroy(this); } /** * Return the RPC credential * * @return The credential */ public Cred getCred() { return cred; } /** * */ public void setRpcHandler(RpcHandler r) { rhandler = r == null ? new RpcHandler() : r; } /** * Construct an RPC header in the XDR buffer * * @param call The XDR buffer for the header * @param proc The service procedure to be called */ public void rpc_header(Xdr call, int proc) throws RpcException { call.xid = next_xid(); /* * Initialize XDR buffer * If using TCP then reserve space for record mark */ call.xdr_offset(conn instanceof ConnectSocket ? 4 : 0); call.xdr_int(call.xid); call.xdr_int(0); // direction=CALL call.xdr_int(2); // RPC version call.xdr_int(prog); call.xdr_int(vers); call.xdr_int(proc); cred.putCred(call); } /* * A rare static method! We need to * make sure that the xid is unique * for all instances of an RPC connection * on this client. */ static synchronized int next_xid() { return xid++; } /* * Message type */ static final int CALL = 0; static final int REPLY = 1; /* * Reply Status */ static final int MSG_ACCEPTED = 0; static final int MSG_DENIED = 1; /* * Accept Status */ static final int SUCCESS = 0; static final int PROG_UNAVAIL = 1; static final int PROG_MISMATCH = 2; static final int PROC_UNAVAIL = 3; static final int GARBAGE_ARGS = 4; static final int SYSTEM_ERR = 5; /* * Reject Status */ static final int RPC_MISMATCH = 0; static final int AUTH_ERROR = 1; /* * Re-construct the call xdr buffer when retranmitting an * RPCSEC_GSS request. * (i.e. for a retransmitted RPCSEC_GSS requests, it uses a * different sequence number and it needs to use its un-encrypted * argument to do wrap() again. */ private Xdr call_reconstruct(Xdr call, byte[] arg) throws IOException, RpcException { Xdr recall = new Xdr(call.xdr_size()); recall.xid = call.xid; // the rpc_header recall.xdr_raw(call.xdr_raw(0, conn instanceof ConnectSocket ? 28 : 24)); cred.putCred(recall); // the not-yet-encrypted rpc argument if (arg != null) { if (recall.xdr_offset() == recall.xdr_wrap_offset()) { recall.xdr_raw(arg); } else { recall.xdr_raw(arg, 4, arg.length - 4); } } return recall; } /** * Transmit the XDR call buffer containing an RPC header * followed by a protocol header and receive the * reply. * * @param call XDR buffer containing RPC call to transmit * @param arg (seq_num + RPC argument) if wrap * @param timeout after this number of milliseconds * @return Xdr the XDR buffer for the reply * @throws RpcException */ public Xdr rpc_call_one(Xdr call, byte[] arg, int timeout) throws IOException, RpcException { int status, astat, rstat; int why; byte[] verifier; // encrypt the rpc argument if it's needed if (arg != null) cred.wrap(call, arg); Xdr reply = conn.send(call, timeout); // XID already xdr'ed by the connection listener if (reply.xdr_int() != REPLY) // direction throw new RpcException("Unknown RPC header"); status = reply.xdr_int(); switch (status) { case MSG_ACCEPTED: reply.xdr_skip(4); // verifier flavor verifier = reply.xdr_bytes(); // get the verifier astat = reply.xdr_int(); switch (astat) { case SUCCESS: int seq_num_in = cred.unwrap(reply); // decrypt the result if it's needed if (seq_num_in > 0) { cred.validate(verifier, seq_num_in); } break; case PROG_UNAVAIL: case PROG_MISMATCH: case PROC_UNAVAIL: throw new MsgAcceptedException(astat, reply.xdr_int(), reply.xdr_int()); case GARBAGE_ARGS: case SYSTEM_ERR: default: throw new MsgAcceptedException(astat); } break; case MSG_DENIED: rstat = reply.xdr_int(); switch (rstat) { case RPC_MISMATCH: throw new MsgRejectedException(rstat, reply.xdr_int(), reply.xdr_int()); case AUTH_ERROR: why = reply.xdr_int(); throw new MsgRejectedException(rstat, why); default: throw new MsgRejectedException(rstat); } } return reply; } /** * Make an RPC call but retry if necessary * * Retries use exponential backoff up to MAX_TIMEOUT ms. * * Note that we handle TCP connections differently: there is * no timeout, and retransmission is used only when reconnecting. * * @param call XDR buffer containing RPC call to transmit * @param timeout for the initial call * @param retries the number of times to retry the call. * A value of zero implies forever. * @return Xdr the XDR buffer for the reply * @throws IOException */ public Xdr rpc_call(Xdr call, int timeout, int retries) throws IOException { boolean timedout = false; Xdr reply = null; long startTime = System.currentTimeMillis(); if (retries == 0) retries = Integer.MAX_VALUE; // retry forever /* * If it's a TCP connection, do retries only * to re-establish connection. */ if (conn instanceof ConnectSocket) timeout = MAX_TIMEOUT; // refresh twice if needed int num_refresh = 2; for (int c = 0; c < retries; c++) { byte[] arg = null; /* * Currently, only CredNone, CredUnix, CredGss is supported. * For CredGss: save the (seq_num + rpc argument) before * it's encrypted. This arg will be needed during retransmit. * * CredGss not checked to avoid loading un-used CredGss class. */ if (!(cred instanceof CredUnix) && !(cred instanceof CredNone) && (call.xdr_offset() > call.xdr_wrap_offset())) { arg = call.xdr_raw(call.xdr_wrap_offset(), call.xdr_offset() - call.xdr_wrap_offset()); } try { reply = rpc_call_one(call, arg, timeout); break; // reply received OK } catch (MsgRejectedException e) { /* * Refresh the cred and try again */ if (num_refresh > 0 && (e.why == MsgRejectedException.RPCSEC_GSS_NOCRED || e.why == MsgRejectedException.RPCSEC_GSS_FAILED) && cred.refresh(conn, prog, vers)) { // re-construct the "call" Xdr buffer. call = call_reconstruct(call, arg); num_refresh--; c--; // to do refresh } else { throw e; } } catch (RpcException e) { /* * An error that cannot be recovered by * retrying - just give up. */ throw e; } catch (IOException e) { /* * If it's a timeout then tell the RPC handler. * It may request an abort by returning true. */ if (rhandler.timeout(conn.server, c, (int) (System.currentTimeMillis() - startTime))) throw new InterruptedIOException(); /* * Probably a timeout. * Double the timeout and retry */ timedout = true; timeout *= 2; // double the timeout if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; /* * For CredGss: reconstruct the clear-text-argument * and use a new sequence number. * Currently, only CredNone, CredUnix, CredGss is supported. * * CredGss not checked to avoid loading un-used CredGss class. */ if (!(cred instanceof CredUnix) && !(cred instanceof CredNone)) { call = call_reconstruct(call, arg); } } } if (reply == null) // reached retry limit throw new InterruptedIOException(); /* * If recovered after a timeout then tell * the RPC Handler so it can display a * "server OK" message. */ if (timedout && reply != null) rhandler.ok(conn.server); return reply; } /** * Since this returns the address of the server it may * seem redundant - but if you receive a reply to a * broadcast RPC you need to know who is replying. * @return address of the Peer */ public InetAddress getPeer() { return conn.getPeer(); } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/RpcException.java000066400000000000000000000050511356275373100237020ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; /** * * Handle the RPC exceptions. Most of the work is done * by the two subclasses that handle the Accepted and Denied * classes of RPC errors. * * @see MsgDeniedException * @see MsgAcceptedConnection * @author Brent Callaghan */ public class RpcException extends java.io.IOException { public int error; public int why; public int lo, hi; /* * Construct a new RPC exception with the given error * @param string The error message */ public RpcException(String msg) { super("RPC error: " + msg); } /* * Construct a new RPC exception with the given error * @param error The RPC error */ public RpcException(int error) { super("RPC error: " + error); this.error = error; } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/RpcHandler.java000066400000000000000000000051071356275373100233230ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; /** * This handler is implemented by the RPC application * if it wishes to be notifed of retransmissions. * A good example is an NFS client that displays * "NFS Server not responding" and "NFS server OK" */ public class RpcHandler { /** * Called when the RPC times out. * * @param server The name of the server * @param retries Number of retries (initially 0) * @param waittime Total time waiting for response * @return bool True to abort, false to continue retrying */ public boolean timeout(String server, int retries, int waittime) { return false; } /** * Called when the server responds after a timeout * * @param server The name of the server */ public void ok(String server) { } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/Xdr.java000066400000000000000000000250451356275373100220410ustar00rootroot00000000000000/* * Copyright (c) 1997-1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.rpc; import java.io.*; /** * This class handles the marshalling/unmarshalling of * primitive data types into and out of a buffer. * * The XDR buffer is a field within this class and its * size is determined when the class is instantiated. * Other than this buffer, there are just two pointers: * "off" is the current XDR offset into the buffer and * moves up the buffer by an integral number of XDRUNITs * as data are encoded/decoded. The other pointer is * "size" which is the number of valid data bytes in * the buffer and is set only for received buffers. * * XXX we should perhaps check that off <= size * whenever an item is decoded so that we can raise * an exception if the received data is underlength. * * @see Rpc * @author Brent Callaghan */ public class Xdr { private static int XDRUNIT = 4; private byte[] buf; private int size, off, wrap_offset; int xid; /** * Build a new Xdr object with a buffer of given size * * @param size of the buffer in bytes */ public Xdr(int size) { this.buf = new byte[size]; this.size = size; this.off = 0; } /** * Skip a number of bytes. *
Note that the count is * rounded up to the next XDRUNIT. * * @param count of the buffer in bytes */ public void xdr_skip(int count) { int r = (off += count) % XDRUNIT; if (r > 0) off += XDRUNIT - r; } /** * Return the entire Xdr buffer * * @return Xdr buffer */ public byte[] xdr_buf() { return buf; } /** * Return the current offset * * @return offset */ public int xdr_offset() { return off; } /** * Set the current offset * * @param off offset into XDR buffer */ public void xdr_offset(int off) { this.off = off; } /** * Return the starting point of the bytes that will * be encrypted. * * @return offset for bytes to be encrypted */ public int xdr_wrap_offset() { return wrap_offset; } /** * Set the starting point of the bytes that will * be encrypted. * * @return offset for bytes to be encrypted */ public void xdr_wrap_offset(int off) { wrap_offset = off; } /** * Return the current size of the XDR buffer * * @return size */ public int xdr_size() { return size; } /** * Set the current size of the XDR buffer * * @param size of buffer */ public void xdr_size(int size) { this.size = size; } /** * Get an integer from the buffer * * @return integer */ public int xdr_int() { return ((buf[off++] & 0xff) << 24 | (buf[off++] & 0xff) << 16 | (buf[off++] & 0xff) << 8 | (buf[off++] & 0xff)); } /** * Put an integer into the buffer * * @param i Integer to store in XDR buffer. */ public void xdr_int(int i) { buf[off++] = (byte)(i >>> 24); buf[off++] = (byte)(i >> 16); buf[off++] = (byte)(i >> 8); buf[off++] = (byte)i; } /** * Get an unsigned integer from the buffer * *
Note that Java has no unsigned integer * type so we must return it as a long. * * @return long */ public long xdr_u_int() { return ((buf[off++] & 0xff) << 24 | (buf[off++] & 0xff) << 16 | (buf[off++] & 0xff) << 8 | (buf[off++] & 0xff)); } /** * Put an unsigned integer into the buffer * * Note that Java has no unsigned integer * type so we must submit it as a long. * * @param i unsigned integer to store in XDR buffer. */ public void xdr_u_int(long i) { buf[off++] = (byte)(i >>> 24 & 0xff); buf[off++] = (byte)(i >> 16); buf[off++] = (byte)(i >> 8); buf[off++] = (byte)i; } /** * Get a long from the buffer * * @return long */ public long xdr_hyper() { return ((long)(buf[off++] & 0xff) << 56 | (long)(buf[off++] & 0xff) << 48 | (long)(buf[off++] & 0xff) << 40 | (long)(buf[off++] & 0xff) << 32 | (long)(buf[off++] & 0xff) << 24 | (long)(buf[off++] & 0xff) << 16 | (long)(buf[off++] & 0xff) << 8 | (long)(buf[off++] & 0xff)); } /** * Put a long into the buffer * * @param i long to store in XDR buffer */ public void xdr_hyper(long i) { buf[off++] = (byte)(i >>> 56) ; buf[off++] = (byte)((i >> 48) & 0xff); buf[off++] = (byte)((i >> 40) & 0xff); buf[off++] = (byte)((i >> 32) & 0xff); buf[off++] = (byte)((i >> 24) & 0xff); buf[off++] = (byte)((i >> 16) & 0xff); buf[off++] = (byte)((i >> 8) & 0xff); buf[off++] = (byte)(i & 0xff); } /* * Note: we have no XDR routines for encoding/decoding * unsigned longs. They exist in XDR but not in Java * hence we can't represent them. * Best just to use xdr_hyper() and hope the sign bit * isn't used. */ /** * Get a boolean from the buffer * * @return boolean */ public boolean xdr_bool() { return (xdr_int() != 0); } /** * Put a boolean into the buffer * * @param b boolean */ public void xdr_bool(boolean b) { xdr_int(b ? 1 : 0); } /** * Get a floating point number from the buffer * * @return float */ public float xdr_float() { return (Float.intBitsToFloat(xdr_int())); } /** * Put a floating point number into the buffer * * @param f float */ public void xdr_float(float f) { xdr_int(Float.floatToIntBits(f)); } /** * Get a string from the buffer * * @return string */ public String xdr_string() { int len = xdr_int(); String s = new String(buf, off, len); xdr_skip(len); return s; } /** * Put a string into the buffer * * @param s string */ public void xdr_string(String s) { xdr_bytes(s.getBytes()); } /** * Get a counted array of bytes from the buffer * * @return bytes */ public byte[] xdr_bytes() { return (xdr_raw(xdr_int())); } /** * Put a counted array of bytes into the buffer. * Note that the entire byte array is encoded. * * @param b byte array */ public void xdr_bytes(byte[] b) { xdr_bytes(b, 0, b.length); } /** * Put a counted array of bytes into the buffer * * @param b byte array * @param len number of bytes to encode */ public void xdr_bytes(byte[] b, int len) { xdr_bytes(b, 0, len); } /** * Put a counted array of bytes into the buffer * * @param b byte array * @param boff offset into byte array * @param len number of bytes to encode */ public void xdr_bytes(byte[] b, int boff, int len) { xdr_int(len); System.arraycopy(b, boff, buf, off, len); xdr_skip(len); } /** * Put an Xdr buffer into the buffer * *
This is used to encode the RPC credentials * * @param x XDR buffer */ public void xdr_bytes(Xdr x) { xdr_bytes(x.xdr_buf(), x.xdr_offset()); } /** * Get a fixed number of bytes from the buffer * * e.g. an NFS v2 filehandle * * @param len Number of bytes to get * @return byte array */ public byte[] xdr_raw(int len) { if (len == 0) return null; byte[] b = new byte[len]; System.arraycopy(buf, off, b, 0, len); xdr_skip(len); return b; } /** * Get a fixed number (len) of bytes from the buffer * at offset off. Do not change any buffer indicators. * * @param off Offset of bytes to get from * @param len Number of bytes to copy * @return byte array */ public byte[] xdr_raw(int off, int len) { if (len == 0) return null; byte[] b = new byte[len]; System.arraycopy(buf, off, b, 0, len); return b; } /** * Put a fixed number of bytes into the buffer * The length is not encoded. * * e.g. an NFS v2 filehandle * * @param b byte array */ public void xdr_raw(byte[] b) { int len = b.length; System.arraycopy(b, 0, buf, off, len); xdr_skip(len); } /** * Put a fixed number of bytes into the buffer * at offset off. The length is not encoded. * * @param b byte array * @param off where to put the byte array */ public void xdr_raw(byte[] b, int off) { int len = b.length; System.arraycopy(b, 0, buf, off, len); xdr_skip(len); } /** * Put a counted array of bytes into the buffer. * The length is not encoded. * * @param b byte array * @param boff offset into byte array * @param len number of bytes to encode */ public void xdr_raw(byte[] b, int boff, int len) { System.arraycopy(b, boff, buf, off, len); xdr_skip(len); } } yanfs-yanfs-1.4/src/main/java/com/sun/rpc/samples/000077500000000000000000000000001356275373100220775ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/rpc/samples/README000066400000000000000000000031601356275373100227570ustar00rootroot00000000000000 #pragma ident "@(#)README 1.3 98/11/12 SMI" System ------ Solaris Install the dummy mechanism package on the server. Server Setup ------------ Before running the client java test program, the C server program has to be invoked first: /home/lling/test/rpcsec_gss/C/list_svc [-l] -n -m Check README in /home/lling/test/rpcsec_gss/C for server program usage. Example: % ./list_svc -n nfs -m 2& Client Setup ------------ o Set CLASSPATH as follows: client% setenv CLASSPATH /usr/java/lib/classes.zip:/home/lling/test/rpcsec_gss/java/classes.jar:. How to run ---------- client% cd /home/lling/test/rpcsec_gss/java client% java RPCGSSClient host service -m mech# -m 1 is for kerberos_v5 -m 2 is for dummy default is dummy Example: % java RPCGSSClient jaywing nfs -m 2 How to test ----------- commands are: set get del service (integrity | privacy | none) create-context destroy-context loop n quit enter cmd -> *NOTE: context must be created before performing set/get/del commands create-context to create a secure context service (integrity | privacy | none) to change the service level (Only works without -l option on server) set to add an value to the server's list e.g. enter cmd -> set foo 80 get to fetch an value from the server's list: e.g. enter cmd -> get foo del to delete an value from the server's list e.g. enter cmd -> del foo destroy-context to destroy a secure context: loop n Create/destroy context n times. yanfs-yanfs-1.4/src/main/java/com/sun/rpc/samples/RPCGSSClient.java000066400000000000000000000216631356275373100251120ustar00rootroot00000000000000package com.sun.rpc.samples; /* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ /* * Sample rpcgss-client application. * This program will inter-operate with the "C" rpcsec_gss server sample * test program. * * This java client sample program is invoked as follows: * * % java RPCGSSClient host service -m * * The -m indicates the mechanism used. * '-m 1' is for kerberos mechanism * '-m 2' is for dummy mechanism * The dummy is used as the default mechanism. */ import java.io.*; import com.sun.rpc.*; class RPCGSSClient { private static final int ADDRLISTPROG = 620756992; private static final int ADDRLISTVERS = 1; private static final int ADDR_SET = 1; private static final int ADDR_GET = 2; private static final int ADDR_DEL = 3; private static final int SVC_SET = 4; private static final int CREATE = 5; private static final int DESTROY = 6; private static final int LOOP = 8; private static final int QUIT = 7; private static final String mech1 = "1.2.840.113554.1.2.2"; //krb5 private static final String mech2 = "1.3.6.1.4.1.42.2.26.1.2"; //dummy private static String serverHost, serviceName, mech, svcString; private static int op = 0, serviceType = CredGss.SVC_PRIVACY, loop_times; private static String name = null, addr = null; /** * Main method for the RPCGSSClient sample application. */ public static void main(String args[]) { Rpc rpc = null; CredGss cred = null; Xdr callmsg = new Xdr(1024), replymsg; boolean status; if ((args.length < 2) || (args.length > 4)) { usage(); exit(1); } //set the required command line args serverHost = args[0]; serviceName = args[1]; // parse -m option; use dummy mech if -m is not specified if (args.length > 2) { if (args[2].equals("-m")) { if (args[3].equals("1")) { mech = mech1; print("Kerberos mechanism " + mech); } else if (args[3].equals("2")) { mech = mech2; print("Dummy mechanism " + mech); } else { usage(); exit(1); } } else { usage(); exit(1); } } else { mech = mech2; print("Dummy mechanism " + mech); } try { rpc = new Rpc(serverHost, 0, ADDRLISTPROG, ADDRLISTVERS, "tcp", 512); } catch (IOException e) { print("\n***RPC ERROR:\t" + e.toString()); e.printStackTrace(); exit(-1); } while (true) { try { parseargs(); switch (op) { case CREATE: cred = new CredGss(serviceName, mech, serviceType, 0); rpc.setCred(cred); break; case SVC_SET: if (svcString.equals("none")) { serviceType = CredGss.SVC_NONE; } else if (svcString.equals("integrity")) { serviceType = CredGss.SVC_INTEGRITY; } else if (svcString.equals("privacy")) { serviceType = CredGss.SVC_PRIVACY; } if (cred != null) { cred.serviceType = serviceType; } break; case ADDR_SET: rpc.rpc_header(callmsg, ADDR_SET); callmsg.xdr_string(name); callmsg.xdr_string(addr); replymsg = rpc.rpc_call(callmsg, 3 * 1000, 3); status = replymsg.xdr_bool(); if (status) { print("set ok \n"); } else { print("set failed\n"); } break; case ADDR_GET: rpc.rpc_header(callmsg, ADDR_GET); callmsg.xdr_string(name); replymsg = rpc.rpc_call(callmsg, 3 * 1000, 3); name = replymsg.xdr_string(); addr = replymsg.xdr_string(); if (addr.getBytes().length != 0) { print(name + " = " + addr); } else { print("no value"); } break; case ADDR_DEL: rpc.rpc_header(callmsg, ADDR_DEL); callmsg.xdr_string(name); replymsg = rpc.rpc_call(callmsg, 3 * 1000, 3); status = replymsg.xdr_bool(); if (status) { print("delete ok"); } else { print("delete failed"); } break; case DESTROY: if (cred != null) { rpc.delCred(); print("Context destroyed"); cred = null; } else { print("No Context to be destroyed"); } break; case LOOP: if (cred != null) { rpc.delCred(); cred = null; } int i = 0; while (loop_times-- > 0) { i++; print("\n***LOOP " + i + "***"); // create-context cred = new CredGss(serviceName, mech, serviceType, 0); rpc.setCred(cred); // destroy-context rpc.delCred(); cred = null; print("Context destroyed"); } break; case QUIT: exit(0); } // switch } catch (IOException e) { print("\n**IO ERRORS**:\t" + e.toString()); e.printStackTrace(); } } // while (true) } // main() /** * Parse command line input */ private static void parseargs() { InputStream in = System.in; byte[] argbuf = new byte[128]; String[] args = new String[4]; int len, offset, n, i; usage1(); System.out.print("enter cmd -> "); try { len = in.read(argbuf); offset = 0; n = 0; i = 0; while (i < (len - 1)) { while (Character.isSpace((char) argbuf[i])) { i++; } offset = i; while ((char) argbuf[i] != '\n' && (char) argbuf[i] != ' ') { //!Character.isSpace((char) argbuf[i])) i++; } args[n++] = new String(argbuf, 0, offset, i-offset); } args[n] = null; } catch (IOException e) { print(e.toString()); parseargs(); } if (args[0] == null) parseargs(); if (args[0].equals("set")) { op = ADDR_SET; name = args[1]; addr = args[2]; if (name == null || addr == null) { print("syntax error"); parseargs(); } } else if (args[0].equals("get")) { op = ADDR_GET; name = args[1]; if (name == null) { print("syntax error"); parseargs(); } } else if (args[0].equals("del")) { op = ADDR_DEL; if (args[1] == null) { print("syntax error"); parseargs(); } name = args[1]; } else if (args[0].equals("service")) { op = SVC_SET; if (args[1] == null) { print("syntax error"); parseargs(); } svcString = args[1]; } else if (args[0].equals("create-context")) { op = CREATE; } else if (args[0].equals("destroy-context")) { op = DESTROY; } else if (args[0].equals("loop")) { op = LOOP; if (args[1] != null) { loop_times = Integer.parseInt(args[1]); } else { loop_times = 5; } } else if (args[0].equals("quit") || args[0].equals("exit")) { op = QUIT; } else { print("syntax error"); parseargs(); } } private static void usage1() { print("\ncommands are:"); print("\tset "); print("\tget "); print("\tdel "); print("\tservice (integrity | privacy | none)"); print("\tcreate-context"); print("\tdestroy-context"); print("\tloop n"); print("\tquit"); } /** * Utility method to display application usage string. */ private static void usage() { print("\nUsage: "); print("\tjava RPCGSSClient serverHost serviceName -m mech#\n"); print("\t-m 1 is for kerberos_v5"); print("\t-m 2 is for dummy"); print("\tdefault mech is dummy if -m is not specified\n"); } /** * Utility method to display information to the screen. */ private static void print(String msg) { System.out.println(msg); } /* private static void print(int x) { System.out.println(x); } */ /** * Utility method to gracefully shut down the connection and * terminate the application. */ private static void exit(int status) { System.exit(status); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/000077500000000000000000000000001356275373100207565ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFile.java000066400000000000000000000741161356275373100226410ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; import java.util.Vector; import java.lang.reflect.Constructor; import java.util.Hashtable; import java.util.StringTokenizer; /** * * Instances of this class represent the name of a file or directory. * Since only the name of the file is represented, the file itself * need not exist. *

* The XFile object is functionally equivalent to the java.io.File * object with the ability to handle not only native pathnames * but also URL-style pathnames. URL pathnames have some advantages * over native pathnames: *

*

    *
  • The name is platform-independent.
    * You can use the same name to reference a file * independent of the pathname syntax supported * by the underlying operating system. The * component separator in a URL pathname is always * a forward slash. *

    *

  • The name can be global in scope.
    * For instance, a URL name can refer to a file * anywhere on the Internet, e.g. *

    * nfs://santa.northpole.org/toys/catalog *

    *

  • The name can refer explicitly to an access scheme.
    * For example: *
      *
    • file:///C|/java/bin (a local directory) *
    • nfs://myserver/home/ed * (directory on NFS server) *
    • ftp://ftpsrv/pub/pkg.zip * (file on FTP server) *
    * This property makes possible the dynamic loading * of new filesystem accessors. *

    *

  • Consistent rules for composition of relative names.
    * URLs support a well defined set of rules for the use * of names relative to a "base" URL described in * RFC 1808. *
    For instance: *

    * * * * * * * * * * * * * * * * * * * * * * * * *
    BaseRelativeComposition
    file:///a/b/cxfile:///a/b/c/x
    nfs://server/a/b/c/ynfs://server/y
    nfs://server/a/b/c../znfs://server/a/b/z
    file:///a/b/cd/.nfs://server/a/b/c/d
    file:///a/b/cnfs://srv/xnfs://srv/x
    *
    *

    *

  • Will support Universal Resource Names.
    * Although URLs are necessarily location dependent, * location indepent Universal Resource Names (URN) * names can be used within the same structure (see * * RFC 2141. *

    *

*

* * Pathnames that are not represented as URL names will be * assumed to represent "native" names and XFile will present * the same semantics as the java.io.File class. */ public class XFile { /** * File Accessor that implements the underlying filesystem */ private XFileAccessor xfa; /** * The url of the file. */ private XFurl url; private String urlStr; private File nativeFile; private boolean bound; /** * Creates a XFile instance that represents the file * whose pathname is the given url argument. * * If the the name argument contains the string "://" then it * is assumed to be a URL name. The characters prior to the * colon are assumed to be the filesystem scheme name, e.g. * "file", "nfs", etc. The rest of the URL name is assumed * to be structured according to the Common Internet Scheme * syntax described in * RFC 1738; * an optional location part followed by a hierarchical set * of slash separated directories. *

* <scheme>://<location>/<path> * * @param name the file url * @exception java.lang.NullPointerException if the file url * is equal to null. */ public XFile(String name) { urlStr = name; if (name == null) throw new NullPointerException(); try { url = new XFurl(name); xfa = loadAccessor(url); } catch (Exception e) { if (name.startsWith(".:")) name = name.substring(2); // lop off ".:" nativeFile = new File(name); xfa = makeNative(nativeFile); } } /** * Creates a XFile instance that represents the file * with the specified name in the specified directory. * * If the dir XFile is null, or if the * name string is a full URL, then the single-arg * constructor is used on the name. *

* If the dir XFile represents a native file * and the name string isAbsolute * then the single-arg constructor is used on the name. * If the name is not absolute then the resulting * path is the simple concatenation of the dir * path with the file separator and the name as * for the two-arg constructor of the File class. *

* If the dir XFile represents a URL name then * the dir is assumed to be a base URL * and the name string is evaluated as a * relative URL according to the rules described in * RFC 1808. * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
DirNameComposition
file:///a/b/cxfile:///a/b/c/x
nfs://server/a/b/c/ynfs://server/y
nfs://server/a/b/c../znfs://server/a/b/z
file:///a/b/cd/.nfs://server/a/b/c/d
file:///a/b/cnfs://srv/xnfs://srv/x
C:\Data\Programsmyprog.exeC:\Data\Programs\myprog.exe
*
* * @param dir the directory. * @param name absolute or relative file name or URL */ public XFile(XFile dir, String name) { if (name == null) throw new NullPointerException(); try { url = new XFurl(name); xfa = loadAccessor(url); } catch (Exception e) { /* * If the name starts with ".:" then its * a "native" URL - not relative. */ if (name.startsWith(".:")) { name = name.substring(2); // lop off ".:" dir = null; } /* * The name is not a URL * If dir is not a URL then * make a native file. */ if (dir == null) { nativeFile = new File(name); xfa = makeNative(nativeFile); /* * Departure from strict java.io semantics here: * If name is absolute then ignore the dir. */ } else if (dir.nativeFile != null) { if (new File(name).isAbsolute()) nativeFile = new File(name); else nativeFile = new File(dir.nativeFile, name); xfa = makeNative(nativeFile); /* * If the dir is a URL then evaluate * name as a relative URL (see RFC 1808) */ } else { try { url = new XFurl(dir.getURL(), name); xfa = loadAccessor(url); } catch (Exception ee) { System.out.println("Error: " + dir.getURL() + " " + name); } } } urlStr = url.toString(); } /* * Extract the protocol scheme from the url and * load a class for an XFileAccessor or XFileExtensionAccessor * * The accessor is located by constructing a package * name that contains the scheme string which is then * located relative to the CLASSPATH. * * The package name is constructed from three components: * * . . * * The default package prefix is "com.sun" however this may * changed by setting of the System property "java.protocol.xfile" * to the value of one or more alternative prefixes delimited * by vertical bars. The list is searched until the XFileAccessor * is found. This method of locating accessors is similar to that * of java.net.URL protocol handlers. The suffix is either * "XFileAccessor" or "XFileExtensionAccessor". * * The hash table is used as a cache for previously loaded classes. */ private Class loadClass(String proto, String suffix, Hashtable ht) throws ClassNotFoundException, IllegalAccessException { /* * Check if there's a cached class for this protocol */ Class cl = (Class)ht.get(proto); if (cl != null) return cl; String prefixList = null; try { // applets will get a security exception here prefixList = System.getProperty("java.protocol.xfile"); } catch (SecurityException e) {}; if (prefixList == null) prefixList = ""; else prefixList += "|"; prefixList += "com.sun"; // always the default StringTokenizer pkgs = new StringTokenizer(prefixList, "|"); while (cl == null && pkgs.hasMoreTokens()) { String prefix = pkgs.nextToken().trim(); String clname = prefix + "." + proto + "." + suffix; try { cl = Class.forName(clname); } catch (Exception e) {}; } if (cl == null) throw new ClassNotFoundException(); ht.put(proto, cl); return (cl); } /* * A table of cached XFileAccessors */ static Hashtable cachedAccessors = new Hashtable(); /* * Load an XFileAccessor */ private XFileAccessor loadAccessor(XFurl url) throws ClassNotFoundException, IllegalAccessException, InstantiationException { Class cl = loadClass(url.getProtocol(), "XFileAccessor", cachedAccessors); if (cl == null) return null; return (XFileAccessor)cl.newInstance(); } /* * Return a file accessor that corresponds * to a native file. */ private XFileAccessor makeNative(File f) { char sep = f.separatorChar; try { url = new XFurl("file:///" + f.getPath().replace(sep, '/')); return loadAccessor(url); } catch (Exception e) { System.out.println("Error: makenative:" + f.getPath()); return null; } } /* * Check that the file is open. * The open() method must be called before * any other methods in the Accessor. * This makes it easier for Accessors to * centralize initialization code in one place. */ private boolean bind() { if (bound) return true; bound = xfa.open(this, false, false); return bound; } /* * Return the bound status */ private boolean getBound() { return bound; } /* * Get the native file */ private File getNative() { return nativeFile; } /* * Get a new XFileAccessor for this object */ protected XFileAccessor newAccessor() { try { return loadAccessor(url); } catch (Exception e) { return makeNative(nativeFile); } } /* * Get the XFileAccessor for this Object * * @return XFileAccessor */ private XFileAccessor getAccessor() { return xfa; } /* * A table of cached XFileExtensionAccessors */ static Hashtable cachedExtensionAccessors = new Hashtable(); /** * Get the XFileExtensionAccessor * * @return instance of XFileExtensionAccessor or null * if there is no XFileExtensionAccessor. */ public XFileExtensionAccessor getExtensionAccessor() { try { /* * XXX The following ugly code avoids a ClassCastException * for old apps using the deprecated * nfsXFileExtensionAccessor class. */ String suffix; if (url.getProtocol().equals("nfs")) suffix = "nfsXFileExtensionAccessor"; else suffix = "XFileExtensionAccessor"; Class cl = loadClass(url.getProtocol(), suffix, cachedExtensionAccessors); Constructor con = cl.getConstructor(new Class[]{this.getClass()}); return (XFileExtensionAccessor)con.newInstance(new Object[]{this}); } catch (Exception e) { return null; } } /* * Get the XFile URL */ private XFurl getURL() { return url; } /** * Returns the name of the filesystem, the string before * the colon of the URL. * * If this XFile represents a native path then the * "file" filesystem will be returned. * * @return the name of the filesystem. */ public String getFileSystemName() { return url.getProtocol(); } /** * Returns the name of the file represented by this object. * * The name is the last component of the pathname. * For a URL this is the last, non-terminating slash. * For a native file it is the portion of the pathname after * the last occurrence of the separator character. * * @return the name of the file (without any directory components) * represented by this XFile object. */ public String getName() { if (nativeFile != null) return nativeFile.getName(); return url.getName(); } /** * Returns the pathname of the file represented by this object. * * @return the pathname represented by this XFile * object. *

* If the object is a URL type, the path is the part * of the URL following the location, e.g. *

* new XFile("nfs://location/a/b/c").getPath() * == "a/b/c" *

* new XFile("file:///a/b/c").getPath() * == "a/b/c" *

* new XFile("nfs://server/").getPath() * == "" */ public String getPath() { if (nativeFile != null) return nativeFile.getPath(); return url.getPath(); } /** * Returns the absolute pathname of the file represented by this * object. * * If this object is represented by a native pathname and is an * absolute pathname, then return the pathname. Otherwise, return * a pathname that is a concatenation of the current user * directory, the separator character, and the pathname of this * file object. * The system property user.dir contains the current * user directory. *

* If the object is represented by a URL then return the entire URL * string. * * @return a system-dependent absolute pathname for this * XFile. */ public String getAbsolutePath() { if (nativeFile != null) return nativeFile.getAbsolutePath(); return urlStr; } /** * Returns the canonical form of this XFile object's * pathname. * * If the object is represented by a URL name then the full * URL is always returned. URL names are always canonical. *

* For native paths the precise definition of canonical form * is system-dependent, but it usually specifies an absolute * pathname in which all relative references and references * to the current user directory have been completely * resolved. The canonical form of a pathname of a nonexistent * file may not be defined. * * @return the canonical path of the object * @exception java.io.IOException If an I/O error occurs, which * is possible because the construction of the * canonical path may require filesystem queries. */ public String getCanonicalPath() throws IOException { if (nativeFile != null) return nativeFile.getCanonicalPath(); return urlStr; } /** * Returns the parent part of the pathname of this * XFile object, or null if the name * has no parent part. * * If the name is a URL then the parent part is the URL with * the last component of the pathname removed. If the URL * has no pathname part, then the URL is returned unchanged. *

* For native paths the parent part is generally everything * leading up to the last occurrence of the separator character, * although the precise definition is system dependent. * On UNIX, for example, the parent part of "/usr/lib" * is "/usr" whose parent part is "/", * which in turn has no parent. * On Windows platforms, the parent part of "c:\java" * is "c:\", which in turn has no parent. * * @return the name of the parent directory */ public String getParent() { if (nativeFile != null) return nativeFile.getParent(); return url.getParent(); } /** * Tests if the file represented by this XFile * object is an absolute pathname. * * If the object is represented by a URL then true * is always returned.
* If the XFile represents a native name then * the definition of an absolute pathname is system * dependent. For example, on UNIX, a pathname is absolute if its * first character is the separator character. * On Windows platforms, * a pathname is absolute if its first character is an ASCII * '\' or '/', or if it begins with a letter followed by * a colon. * * @return true if the pathname indicated by the * XFile object is an absolute pathname; * false otherwise. */ public boolean isAbsolute() { if (nativeFile != null) return nativeFile.isAbsolute(); return true; } /** * Tests if this XFile exists. * * @return true if the file specified by this object * exists; false otherwise. */ public boolean exists() { if (!bind()) return false; return xfa.exists(); } /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this object; * false otherwise. */ public boolean canWrite() { if (!bind()) return false; return xfa.canWrite(); } /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ public boolean canRead() { if (!bind()) return false; return xfa.canRead(); } /** * Tests if the file represented by this XFile * object is a "normal" file. * * A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is guaranteed * to be a normal file. * * @return true if the file specified by this object * exists and is a "normal" file; false * otherwise. */ public boolean isFile() { if (!bind()) return false; return xfa.isFile(); } /** * Tests if the file represented by this XFile * object is a directory. * * @return true if this XFile exists * and is a directory; false otherwise. */ public boolean isDirectory() { if (!bind()) return false; return xfa.isDirectory(); } /** * Returns the time that the file represented by this * XFile object was last modified. *

* The return value is system dependent and should only be used to * compare with other values returned by last modified. It should * not be interpreted as an absolute time. * * @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ public long lastModified() { if (!bind()) return 0L;; return xfa.lastModified(); } /** * Returns the length of the file represented by this * XFile object. * * @return the length, in bytes, of the file specified by this * object, or 0L if the specified file does * not exist. The length constitutes the number of bytes * readable via an InputStream. The length value for * a directory is undefined. */ public long length() { if (!bind()) return 0L; return xfa.exists() ? xfa.length() : 0L; } /** * Renames the file specified by this XFile object to * have the pathname given by the XFile argument. * * This object and dest must represent filesystems * of the same type. For instance: both native or both of * the same URL scheme. * * After a successful renameTo, this object continues to * be a valid reference to the file. Only the name * is different. * * If the destination filename already exists, it will be replaced. * The application must have permission to modify the source and * destination directory. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ public boolean renameTo(XFile dest) { if (dest == null) throw new NullPointerException(); if (! xfa.getClass().isInstance(dest.getAccessor())) return false; if (!bind()) return false; boolean ok = xfa.renameTo(dest); /* * Only the name of the file is changed. * Its data and state are unaffected. * Hence we make this XFile object a clone * of the dest XFile. */ if (ok) { url = dest.getURL(); urlStr = dest.getAbsolutePath(); nativeFile = dest.getNative(); xfa = dest.getAccessor(); bound = dest.getBound(); } return ok; } /** * Creates a directory whose pathname is specified by this * XFile object. * * If any parent directories in the pathname do not * exist, the method will return false. * * @return true if the directory could be created; * false otherwise. */ public boolean mkdir() { bind(); return xfa.mkdir(); } /** * Creates a directory whose pathname is specified by this * XFile object, including any necessary parent * directories. * * @return true if the directory (or directories) * could be created; false otherwise. */ public boolean mkdirs() { bind(); if (exists()) { return false; } if (mkdir()) { return true; } String parent = getParent(); return (parent != null) && (new XFile(parent).mkdirs() && mkdir()); } /** * Returns a list of the files in the directory specified by this * XFile object. * * @return an array of file names in the specified directory. * This list does not include the current directory or the * parent directory ("." and ".." * on Unix systems). */ public String[] list() { if (!bind()) return null;; return xfa.list(); } /** * Returns a list of the files in the directory specified by this * XFile that satisfy the specified filter. * * @param filter a filename filter. * @return an array of file names in the specified directory. * This list does not include the current directory or the * parent directory ("." and ".." * on Unix systems). * @see com.sun.xfilenameFilter */ public String[] list(XFilenameFilter filter) { if (!bind()) return null;; String names[] = list(); if (names == null) { return null; } // Fill in the Vector Vector v = new Vector(); for (int i = 0 ; i < names.length ; i++) { if ((filter == null) || filter.accept(this, names[i])) { v.addElement(names[i]); } } // Create the array String files[] = new String[v.size()]; v.copyInto(files); return files; } /** * Deletes the file specified by this object. * If the target file to be deleted is a directory, it must be * empty for deletion to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ public boolean delete() { if (!bind()) return false;; boolean ok = xfa.delete(); bound = !ok; return ok; } /** * Computes a hashcode for the file. * * @return a hash code value for this XFile object. */ public int hashCode() { return urlStr.hashCode() ^ 1234321; } /** * Compares this object against the specified object. * * Returns true if and only if the argument is * not null and is a XFile object whose * pathname is equal to the pathname of this object. * * @param obj the object to compare with. * @return true if the objects are the same; * false otherwise. */ public boolean equals(Object obj) { if ((obj == null) || (! (obj instanceof XFile))) return false; return url.toString().equals(((XFile)obj).getURL().toString()); } /** * Returns a string representation of this object. * * @return a string giving the pathname of this object. */ public String toString() { if (nativeFile != null) return (nativeFile.toString()); return urlStr; } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileAccessor.java000066400000000000000000000257501356275373100243240ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.IOException; /** * The XFileAccessor interface is implemented by filesystems that * need to be accessed via the XFile API. * * Classes that implement this interface must be associated * with a URL scheme that is structured according to the * Common Internet Scheme syntax described in * RFC 1738; * an optional location part followed by a hierarchical set * of slash separated directories. *

* A class file that implements this interface must be named * "XFileAccessor" and be installed in a directory named after * the URL scheme that it implements, for instance, an XFileAccessor * that provides file access through the HTTP protocol would be * associated with the "http" URL and its class file would be * called: *

* http.XFileAccessor *

* A class prefix is added to this name. The default prefix is * com.sun and this composite name is located by the * classLoader via the CLASSPATH. * For instance, Sun's "nfs" XFileAccessor is installed as: *

* com.sun.nfs.XFileAccessor *

* The default class prefix com.sun can be changed by * setting the System property java.protocol.xfile * to any desired prefix or a list of prefixes separated by * vertical bars. Each prefix in the list will be used to * construct a package name and the classLoader will attempt * to load that package via the CLASSPATH. This process will * continue until the XFileAccessor is successfully loaded. *

* For instance, if you want to use the "ftp" * XFileAccessor from Acme, Inc and the "nfs" XFileAccessor * from "ABC Inc." then you can set the system property as * follows: *

* java.protocol.xfile=com.acme|com.abc *
* When an "ftp" URL is used, the following package names will * be constructed: *
 *    com.acme.ftp.XFileAccessor
 *    com.abc.ftp.XFileAccessor
 *    com.sun.ftp.XFileAccessor
 * 
* (the default "com.sun" prefix is automatically added to * the end of the property list) *

* The class loader attempts to load each of the constructed * package names in turn relative to the CLASSPATH until it is * successful. *

* A subsequent reference to an "nfs" URL will result in * the following list of candidate package names: *

 *    com.acme.nfs.XFileAccessor
 *    com.abc.nfs.XFileAccessor
 *    com.sun.nfs.XFileAccessor
 * 
* In this case the "nfs" XFileAccessor from ABC, Inc. will * be loaded in preference to Sun's NFS. * * * @author Brent Callaghan * @version 1.0, 04/08/98 * @see com.sun.xfile.XFile */ public interface XFileAccessor { /** * Open a file in this filesystem. * * This method is called before any other method. * It may be used to open the real file. * * @param xf The XFile for the file to be accessed * The URL will be of the form *

* <proto>://<location>/<path> *

* where <proto> is the name of the filesystem, * e.g. "nfs" and <location> is the location of * the filesystem. For nfs this is the network name of * a server. The <path> is a pathname that locates * the file within <location>. As required by * RFC 1738, the component delimiters in the pathname * are as for URL syntax: forward slashes only. * @param serial true if serial access; false if random access * @param readOnly true if read only; false if read/write */ boolean open(XFile xf, boolean serial, boolean readOnly); /** * Return the XFile for this Accessor */ XFile getXFile(); /** * Tests if this XFile object exists. * * @return true if the file specified by this object * exists; false otherwise. */ boolean exists(); /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this * object; false otherwise. */ boolean canWrite(); /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ boolean canRead(); /** * Tests if the file represented by this * object is a "normal" file. *

* A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is * guaranteed to be a normal file. * * @return true if the file specified by this * object exists and is a "normal" * file; false otherwise. */ boolean isFile(); /** * Tests if the file represented by this XFileAccessor * object is a directory. * * @return true if this XFileAccessor object * exists and is a directory; false * otherwise. */ boolean isDirectory(); /** * Returns the time that the file represented by this * XFile object was last modified. * It is measured as the time in milliseconds since * midnight, January 1, 1970 UTC. *

* @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ long lastModified(); /** * Returns the length of the file represented by this * XFileAccessor object. * * @return the length, in bytes, of the file specified by * this object, or 0L if the specified * file does not exist. */ long length(); /** * Creates an empty file whose pathname is specified by this * XFileAccessor object. * * @return true if the file was created; * false otherwise. */ boolean mkfile(); /** * Creates a directory whose pathname is specified by this * XFileAccessor object. * * @return true if the directory could be created; * false otherwise. */ boolean mkdir(); /** * Renames the file specified by this XFileAccessor object to * have the pathname given by the XFileAccessor object argument. * * The destination XFile object will be of the same URL * scheme as this object. The change of name must not * affect the existence or accessibility of this object. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ boolean renameTo(XFile dest); /** * Deletes the file specified by this object. If the target * file to be deleted is a directory, it must be empty for deletion * to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ boolean delete(); /** * Returns a list of the files in the directory specified by * this XFileAccessor object. * * @return an array of file names in the specified directory. * This list does not include the current directory or * the parent directory ("." and * ".." on Unix systems). */ String[] list(); /** * Reads a subarray as a sequence of bytes. * * @param b the buffer into which the data is read * @param off the start offset in the data buffer * @param len the maximum number of bytes to be read * @param foff the offset into the file * @return number of bytes read - zero if none. * @exception java.io.IOException If an I/O error has occurred. */ int read(byte b[], int off, int len, long foff) throws IOException; /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data in the buffer * @param len the number of bytes that are written * @param foff the offset into the file * @exception java.io.IOException If an I/O error has occurred. */ void write(byte b[], int off, int len, long foff) throws IOException; /** * Forces any buffered output bytes to be written out. *

* * @exception java.io.IOException if an I/O error occurs. */ void flush() throws IOException; /** * Close the file. * * Closes this file and releases any system resources * associated with the file. * * After the file is closed further I/O operations may * throw IOException. * * @exception java.io.IOException If an I/O error has occurred. */ void close() throws IOException; } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileExtensionAccessor.java000066400000000000000000000071501356275373100262130ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; /** * This is an abstract class to intended to be extended with * filesystem-specific methods. *

* An XFileExtensionAccessor class must be associated with an * XFileAccessor. An XFileExtensionAccessor can be used to * provide access to filesystem-specific methods that are not * defined within the XFileAccessor interface. * A subclass of XFileExtensionAccessor must be declared as: *


 *     import com.sun.xfile.*;
 *     

* public class XFileExtensionAccessor extends com.sun.xfile.XFileExtensionAccessor { * : * *

*

* An XFileExtensionAccessor class is loaded when the * XFile.getExtensionAccessor() method is invoked. The * class loading process is identical to that of an * XFileAccessor except for the final component of the package * name: "XFileExtensionAccessor" instead of "XFileAccessor". *

* An application that needs to use the methods within the * XFileExtensionAccessor must cast the result of XFile.getExtensionAccessor. *


 *    import com.sun.xfile.*;
 *    

* XFile xf = new XFile("ftp://server/path"); * com.acme.ftp.XFileExtensionAccessor xftp = * (com.acme.ftp.XFileExtensionAccessor) xf.getExtensionAccessor(); * xftp.login(); * : *

* * * @author Brent Callaghan * @see com.sun.xfile.XFile#getExtensionAccessor() * @see com.sun.xfile.XFileAccessor */ public abstract class XFileExtensionAccessor { private XFile xf; /* * Constructor for the XFileExtensionAccessor. * * Invoked by the XFile class when its getExtensionAccessor * method is called. The XFile argument of * the constructor provides context for the methods * within the class. */ public XFileExtensionAccessor(XFile xf) { this.xf = xf; } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileInputStream.java000066400000000000000000000153641356275373100250350ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; /** * An XFile input stream is an input stream for reading data from an * XFile. */ public class XFileInputStream extends InputStream { private long fp; /* File Pointer */ /** * File Accessor that implements the underlying filesystem */ private XFileAccessor xfa; /** * Creates an input file stream to read from the specified * XFile object. * * @param xfile the file to be opened for reading. * @exception java.io.FileNotFoundException if the file is * not found. */ public XFileInputStream(XFile xfile) throws IOException { xfa = xfile.newAccessor(); if (! xfa.open(xfile, true, true)) // serial, read-only throw new FileNotFoundException("no file"); if (!xfa.canRead()) throw new IOException("no read permission"); } /** * Creates an input file stream to read from a file with the * specified name. * * @param name the system-dependent file name. * @exception java.io.FileNotFoundException if the file is * not found. */ public XFileInputStream(String name) throws IOException { this(new XFile(name)); } /* * Reads a subarray as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @exception java.io.IOException If an I/O error has occurred. */ synchronized private int XFAread(byte b[], int off, int len) throws IOException { if (b == null) throw new NullPointerException(); if (len == 0) return 0; if (off < 0 || len < 0 || off >= b.length || (off + len) > b.length) throw new IllegalArgumentException("Invalid argument"); int c = xfa.read(b, off, len, fp); if (c <= 0) return (-1); fp += c; return (c); } /** * Reads a byte of data from this XFile. * * @return the next byte of data, or -1 * if the end of the file is reached. * @exception java.io.IOException if an I/O error occurs. */ public int read() throws IOException { byte[] b = new byte[1]; if (XFAread(b, 0, 1) != 1) return (-1); return b[0] & 0xff; } /** * Reads up to b.length bytes of data from this file * into an array of bytes. * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because * the end of the file has been reached. * @exception java.io.IOException if an I/O error occurs. */ public int read(byte b[]) throws IOException { return XFAread(b, 0, b.length); } /** * Reads up to len bytes of data from this file * into an array of bytes. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because * the end of the file has been reached. * @exception java.io.IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { return XFAread(b, off, len); } /** * Returns the number of bytes yet to be read from this file. * * @return the number of bytes yet to be read from this file * without blocking. * @exception java.io.IOException if an I/O error occurs. */ public int available() throws IOException { return (int)(xfa.length() - fp); } /** * Skips over and discards n bytes of data from the * file. * * The skip method may, for a variety of * reasons, end up skipping over some smaller number of bytes, * possibly 0. * The actual number of bytes skipped is returned. * * @param n the number of bytes to be skipped. * @return the actual number of bytes skipped. * @exception java.io.IOException if an I/O error occurs. */ public long skip(long n) throws IOException { if (n < 0) throw new IllegalArgumentException("illegal skip: " + n); fp += n; return n; } /** * Closes this file input stream and releases any system resources * associated with the stream. * * After the file is closed further I/O operations may * throw IOException. * * @exception java.io.IOException if an I/O error occurs. */ public void close() throws IOException { xfa.close(); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileOutputStream.java000066400000000000000000000161521356275373100252320ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; /** * An XFile output stream is an output stream for writing data to an * XFile. */ public class XFileOutputStream extends OutputStream { private long fp; /* File Pointer */ /* * File Accessor that implements the underlying filesystem */ private XFileAccessor xfa; /** * Creates an XFile output stream to write to the specified * XFile object. * * @param file the XFile to be opened for writing. * @exception java.io.IOException if the XFile could not * be opened for writing. */ public XFileOutputStream(XFile xfile) throws IOException { xfa = xfile.newAccessor(); if (xfa.open(xfile, true, false)) { // serial, not readonly if (!xfa.isFile()) throw new IOException("not a file"); if (!xfa.canWrite()) throw new IOException("no write permission"); } if (!xfa.mkfile()) throw new IOException("no write permission"); } /** * Creates an output XFile stream to write to the file with the * specified name. * * @param name the system-dependent filename. * @exception java.io.IOException if the file could * not be opened for writing. */ public XFileOutputStream(String name) throws IOException { this(new XFile(name)); } /** * Creates an output file for the specified XFile object. * * @param xfile the XFile to be opened for writing. * @param append true if writes begin at the end of the file * @exception java.io.IOException If the file is not found. */ public XFileOutputStream(XFile xfile, boolean append) throws IOException { boolean isExist; xfa = xfile.newAccessor(); if ((isExist = xfa.open(xfile, true, false))) { // serial, not readonly if (!xfa.isFile()) throw new IOException("not a file"); if (!xfa.canWrite()) throw new IOException("no write permission"); } /* * If file doesn't exist or append is False create the file */ if (!isExist || !append) { if (!xfa.mkfile()) throw new IOException("no write permission"); } if (append) fp = xfa.length(); } /** * Creates an output file with the specified name or URL. * * @param name the native name or URL * @param append true if writes begin at the end of the file * @exception java.io.IOException If the file is not found. */ public XFileOutputStream(String name, boolean append) throws IOException { this(new XFile(name), append); } /* * All writes to the Accessor go through here. */ synchronized private void XFAwrite(byte b[], int off, int len) throws IOException { if (b == null) throw new NullPointerException(); if (len == 0) return; if (off < 0 || len < 0 || off >= b.length || (off + len) > b.length) throw new IllegalArgumentException("Invalid argument"); xfa.write(b, off, len, fp); fp += len; } /** * Writes the specified byte to this file output stream. * * @param b the byte to be written. * @exception java.io.IOException if an I/O error occurs. */ public void write(int b) throws IOException { XFAwrite(new byte[] {(byte)b}, 0, 1); } /** * Writes b.length bytes from the specified byte array * to this file output stream. * * @param b the data. * @exception java.io.IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { XFAwrite(b, 0, b.length); } /** * Writes len bytes from the specified byte array * starting at offset off to this XFile output stream. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception java.io.IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { XFAwrite(b, off, len); } /** * Flushes this output stream and forces any buffered output bytes * to be written out. *

* * @exception java.io.IOException if an I/O error occurs. */ public void flush() throws IOException { xfa.flush(); } /** * Closes this file output stream, flushes any buffered, * unwritten data, and releases any system resources * associated with this stream. * * After the file is closed further I/O operations may * throw IOException. * * @exception java.io.IOException if an I/O error occurs. */ public void close() throws IOException { xfa.close(); } /** * Ensures that the close method of this XFile * output stream is called when there are no more references * to this stream. * * @exception java.io.IOException if an I/O error occurs. * @see com.sun.xfile.XFileInputStream#close() */ protected void finalize() throws IOException { close(); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileReader.java000066400000000000000000000046221356275373100237570ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; /** * Convenience class for reading character files. * * The constructors of this class assume that the default character * encoding and the default byte-buffer size are appropriate. * To specify these values yourself, construct an * InputStreamReader on a FileInputStream. * * @see InputStreamReader * @see XFileInputStream * */ public class XFileReader extends InputStreamReader { public XFileReader(String fileName) throws IOException { super(new XFileInputStream(fileName)); } public XFileReader(XFile file) throws IOException { super(new XFileInputStream(file)); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFileWriter.java000066400000000000000000000050321356275373100240250ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; /** * Convenience class for writing character files. * * The constructors of this class assume that the default character * encoding and the default byte-buffer size are acceptable. * To specify these values yourself, construct an * OutputStreamWriter on a FileOutputStream. * * @see OutputStreamWriter * @see XFileOutputStream */ public class XFileWriter extends OutputStreamWriter { public XFileWriter(String fileName) throws IOException { super(new XFileOutputStream(fileName)); } public XFileWriter(String fileName, boolean append) throws IOException { super(new XFileOutputStream(fileName, append)); } public XFileWriter(XFile file) throws IOException { super(new XFileOutputStream(file)); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFilenameFilter.java000066400000000000000000000047371356275373100246520ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; /** * Instances of classes that implement this interface are used to * filter filenames. These instances are used to filter directory * listings in the list method of class * XFile. * * @see com.sun.xfile.XFile#list(com.sun.xfile.XFilenameFilter) */ public interface XFilenameFilter { /** * Tests if a specified file should be included in a file list. * * @param dir the directory in which the file was found. * @param name the name of the file. * @return true if the name should be included in * the file list; false otherwise. */ boolean accept(XFile dir, String name); } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XFurl.java000066400000000000000000000141421356275373100226630ustar00rootroot00000000000000/* * Copyright (c) 1999, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.net.MalformedURLException; /** * This is just a dumb URL parser class. * I wrote it because I got fed up with the * JDK URL class calling NFS URL's "invalid" * simply because the Handler wasn't installed. * * @author Brent Callaghan */ class XFurl { private String url; private String protocol; private String location; private String path; XFurl(String url) throws MalformedURLException { int p, q, r; url = url.trim(); // remove leading & trailing spaces this.url = url; int end = url.length(); p = url.indexOf(':'); if (p < 0) throw new MalformedURLException("colon expected"); protocol = url.substring(0, p); q = p; p++; // skip colon if (url.regionMatches(p, "//", 0, 2)) { // have hostname p += 2; q = url.indexOf('/', p); if (q < 0) q = end; location = url.substring(p, q); } path = q < end ? url.substring(q + 1, end) : ""; // Remove trailing slashes from path while (path.endsWith("/")) path = path.substring(0, path.length()-1); } XFurl(XFurl base, String rpath) throws MalformedURLException { protocol = base.getProtocol(); location = base.getLocation(); path = base.getPath(); rpath = rpath.trim(); if (rpath.indexOf("://") > 0) { // URL - ignore base url = rpath; XFurl u = new XFurl(rpath); protocol = u.getProtocol(); location = u.getLocation(); path = u.getPath(); } else if (rpath.startsWith("/")) { // absolute path path = rpath.substring(1); } else { /* * Escape any "%" characters in the name * e.g. "%markup" -> "%25markup" */ String npath = ""; int len = rpath.length(); int p1 = 0, p2; while (true) { p2 = rpath.indexOf('%', p1); // look for % if (p2 < 0) p2 = len; npath += rpath.substring(p1, p2); if (p2 >= len) break; npath += "%25"; // replace % with %25 p1 = p2 + 1; } rpath = npath; len = rpath.length(); /* * Combine base path with relative path * according to rules in RFCs 1808 & 2054 * * e.g. /a/b/c + x = /a/b/c/x * /a/b/c + /y = /y * /a/b/c + ../z = /a/b/z * /a/b/c + d/. = /a/b/c/d */ String bpath = base.getPath(); p1 = 0; while (p1 <= len) { p2 = rpath.indexOf("/", p1); if (p2 < 0) p2 = len; String component = rpath.substring(p1, p2); if (component.equals(".") || component.equals("")) { // ignore } else if (component.equals("..")) { int q = bpath.lastIndexOf("/"); bpath = q < 0 ? "" : bpath.substring(0, q); } else { if (bpath.equals("")) bpath = component; else bpath += "/" + component; } p1 = p2 + 1; } path = bpath; } } String getProtocol() { return (protocol); } String getLocation() { return (location); } String getPath() { return (path); } String getParent() { if (path.equals("")) return null; // no parent String s = protocol + ":"; if (location != null) s += "//" + location; int index = path.lastIndexOf('/'); if (index >= 0) s += "/" + path.substring(0, index); return s; } String getName() { int index = path.lastIndexOf('/'); return index < 0 ? path : path.substring(index + 1); } public String toString() { String s = protocol + ":"; if (location != null) s += "//" + location; if (path != null) s += "/" + path; return (s); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfile/XRandomAccessFile.java000066400000000000000000000740451356275373100251250ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfile; import java.io.*; /** * Instances of this class support both reading and writing to a * random access file. An application can modify the position in the * file at which the next read or write occurs. * This class provides a sense of security * by offering methods that allow specified mode accesses of * read-only or read-write to files. * */ public class XRandomAccessFile implements DataOutput, DataInput { private long fp; /* File Pointer */ private boolean readOnly; /* * File Accessor that implements the underlying filesystem */ private XFileAccessor xfa; /** * Creates a random access file stream to read from, and optionally * to write to, the file specified by the XFile * argument. * * The mode argument must either be equal to "r" or to * "rw", indicating either to open the file for input, * or for both input and output, respectively. * * @param xf the XFile object. * @param mode the access mode. * @exception java.lang.IllegalArgumentException if the mode * argument is not equal to "r" or * to "rw". * @exception java.io.IOException if an I/O error occurs. */ public XRandomAccessFile(XFile xf, String mode) throws IOException { if (! (mode.equals("r") || mode.equals("rw"))) throw new IllegalArgumentException("mode must be r or rw"); readOnly = mode.equals("r"); xfa = xf.newAccessor(); xfa.open(xf, false, readOnly); if (xfa.exists()) { if (readOnly && ! xfa.canRead()) throw new IOException("no read permission"); if (! readOnly && ! xfa.canWrite()) throw new IOException("no write permission"); } else { if (readOnly) throw new IOException("no such file or directory"); if (! xfa.mkfile()) throw new IOException("no write permission"); } } /** * Creates a random access file to read from, and optionally * to write to, a file with the specified name. *

* The mode argument must either be equal to "r" or * "rw", indicating either to open the file for input * or for both input and output. * * @param name the native or URL file name. * @param mode the access mode. * @exception java.lang.IllegalArgumentException if the mode * argument is not equal to "r" or to * "rw". * @exception java.io.IOException if an I/O error occurs. */ public XRandomAccessFile(String name, String mode) throws IOException { this(new XFile(name), mode); } // 'Read' primitives private int XFAread(byte b[], int off, int len) throws IOException { if (b == null) throw new NullPointerException(); if (len == 0) return 0; if (off < 0 || len < 0 || off >= b.length || (off + len) > b.length) throw new IllegalArgumentException("Invalid argument"); int c = xfa.read(b, off, len, fp); if (c >= 0) fp += c; return c; } /** * Reads a byte of data from this file. * * @return the next byte of data, or -1 if the * end of the file is reached. * @exception java.io.IOException if an I/O error occurs. */ public int read() throws IOException { byte[] b = new byte[1]; if (XFAread(b, 0, 1) != 1) return (-1); return b[0] & 0xff; } /** * Reads up to len bytes of data from this file into * an array of bytes. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the maximum number of bytes read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because * the end of the file has been reached. * @exception java.io.IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { return XFAread(b, off, len); } /** * Reads up to b.length bytes of data from this file * into an array of bytes. * * @param b the buffer into which the data is read. * @return the total number of bytes read into the buffer, or * -1 if there is no more data because * the end of this file has been reached. * @exception java.io.IOException if an I/O error occurs. */ public int read(byte b[]) throws IOException { return XFAread(b, 0, b.length); } /** * Reads b.length bytes from this file into the byte * array. * * @param b the buffer into which the data is read. * @exception java.io.EOFException if this file reaches * the end before reading all the bytes. * @exception java.io.IOException if an I/O error occurs. */ public final void readFully(byte b[]) throws IOException { readFully(b, 0, b.length); } /** * Reads exactly len bytes from this file into * the byte array. * * @param b the buffer into which the data is read. * @param off the start offset of the data. * @param len the number of bytes to read. * @exception java.io.EOFException if this file reaches the * end before reading all the bytes. * @exception java.io.IOException if an I/O error occurs. */ public final void readFully(byte b[], int off, int len) throws IOException { if (XFAread(b, off, len) < len) throw new EOFException(); } /** * Skips exactly n bytes of input. *

* * @param n the number of bytes to be skipped. * @return the number of bytes skipped, which is always * n. * @exception java.io.EOFException if this file reaches the end * before skipping all the bytes. * @exception java.io.IOException if an I/O error occurs. */ public int skipBytes(int n) throws IOException { if (fp + n > xfa.length()) throw new EOFException(); seek(fp + n); return n; } // 'Write' primitives private void XFAwrite(byte b[], int off, int len) throws IOException { if (b == null) throw new NullPointerException(); if (readOnly) throw new IOException("Read only file"); if (off < 0 || len < 0) throw new IllegalArgumentException("Invalid argument"); xfa.write(b, off, len, fp); fp += len; } /** * Writes the specified byte to this file. * * @param b the byte to be written. * @exception java.io.IOException if an I/O error occurs. */ public void write(int b) throws IOException { XFAwrite(new byte[]{(byte)b}, 0, 1); } /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @exception java.io.IOException If an I/O error has occurred. */ private void writeBytes(byte b[], int off, int len) throws IOException { XFAwrite(b, off, len); } /** * Writes b.length bytes from the specified byte array * starting at offset off to this file. * * @param b the data. * @exception java.io.IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { writeBytes(b, 0, b.length); } /** * Writes len bytes from the specified byte array * starting at offset off to this file. * * @param b the data. * @param off the start offset in the data. * @param len the number of bytes to write. * @exception java.io.IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { writeBytes(b, off, len); } // 'Random access' stuff /** * Returns the current offset in this file. * * @return the offset from the beginning of the file, in bytes, * at which the next read or write occurs. * @exception java.io.IOException if an I/O error occurs. */ public long getFilePointer() throws IOException { return fp; } /** * Sets the offset from the beginning of this file at which * the next read or write occurs. * * @param pos the absolute position. * @exception java.io.IOException if an I/O error occurs. */ public void seek(long pos) throws IOException { if ( pos < 0 || (readOnly && pos >= xfa.length())) throw new IOException("illegal seek" + pos); fp = pos; } /** * Returns the length of this file. * * @return the length of this file. * @exception java.io.IOException if an I/O error occurs. */ public long length() throws IOException { return xfa.length(); } /** * Forces any buffered output bytes to be written out. * * @exception java.io.IOException if an I/O error occurs. */ public void flush() throws IOException { if (readOnly) throw new IOException("Read only file"); xfa.flush(); } /** * Closes this random access file and flushes any * unwritten data to the file. * * After the file is closed further I/O operations may * throw IOException. * * @exception java.io.IOException if an I/O error occurs. */ public void close() throws IOException { xfa.close(); } // // Some "reading/writing Java data types" methods stolen from // DataInputStream and DataOutputStream. // /** * Reads a boolean from this file. This method reads a * single byte from the file. A value of 0 represents * false. Any other value represents true. * This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the boolean value read. * @exception java.io.EOFException if this file has reached the end. * @exception java.io.IOException if an I/O error occurs. */ public final boolean readBoolean() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return (ch != 0); } /** * Reads a signed 8-bit value from this file. This method reads a * byte from the file. If the byte read is b, where * 0 <= b <= 255, * then the result is: *

    * (byte)(b) *
*

* This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the next byte of this file as a signed 8-bit * byte. * @exception java.io.EOFException if this file has reached the end. * @exception java.io.IOException if an I/O error occurs. */ public final byte readByte() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return (byte)(ch); } /** * Reads an unsigned 8-bit number from this file. This method reads * a byte from this file and returns that byte. *

* This method blocks until the byte is read, the end of the stream * is detected, or an exception is thrown. * * @return the next byte of this file, interpreted as an unsigned * 8-bit number. * @exception java.io.EOFException if this file has reached the end. * @exception java.io.IOException if an I/O error occurs. */ public final int readUnsignedByte() throws IOException { int ch = this.read(); if (ch < 0) throw new EOFException(); return ch; } /** * Reads a signed 16-bit number from this file. The method reads 2 * bytes from this file. If the two bytes read, in order, are * b1 and b2, where each of the two values is * between 0 and 255, inclusive, then the * result is equal to: *

    * (short)((b1 << 8) | b2) *
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this file, interpreted as a signed * 16-bit number. * @exception java.io.EOFException if this file reaches the end before reading * two bytes. * @exception java.io.IOException if an I/O error occurs. */ public final short readShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (short)((ch1 << 8) + (ch2 << 0)); } /** * Reads an unsigned 16-bit number from this file. This method reads * two bytes from the file. If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

    * (b1 << 8) | b2 *
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this file, interpreted as an unsigned * 16-bit integer. * @exception java.io.EOFException if this file reaches the end before reading * two bytes. * @exception java.io.IOException if an I/O error occurs. */ public final int readUnsignedShort() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (ch1 << 8) + (ch2 << 0); } /** * Reads a Unicode character from this file. This method reads two * bytes from the file. If the bytes read, in order, are * b1 and b2, where * 0 <= b1, b2 <= 255, * then the result is equal to: *

    * (char)((b1 << 8) | b2) *
*

* This method blocks until the two bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next two bytes of this file as a Unicode character. * @exception java.io.EOFException if this file reaches the end before reading * two bytes. * @exception java.io.IOException if an I/O error occurs. */ public final char readChar() throws IOException { int ch1 = this.read(); int ch2 = this.read(); if ((ch1 | ch2) < 0) throw new EOFException(); return (char)((ch1 << 8) + (ch2 << 0)); } /** * Reads a signed 32-bit integer from this file. This method reads 4 * bytes from the file. If the bytes read, in order, are b1, * b2, b3, and b4, where * 0 <= b1, b2, b3, b4 <= 255, * then the result is equal to: *

    * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4 *
*

* This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this file, interpreted as an * int. * @exception java.io.EOFException if this file reaches the end before reading * four bytes. * @exception java.io.IOException if an I/O error occurs. */ public final int readInt() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); } /** * Reads a signed 64-bit integer from this file. This method reads eight * bytes from the file. If the bytes read, in order, are * b1, b2, b3, * b4, b5, b6, * b7, and b8, where: *

    * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255, *
*

* then the result is equal to: *

     *     ((long)b1 << 56) + ((long)b2 << 48)
     *     + ((long)b3 << 40) + ((long)b4 << 32)
     *     + ((long)b5 << 24) + ((long)b6 << 16)
     *     + ((long)b7 << 8) + b8
     * 
*

* This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this file, interpreted as a * long. * @exception java.io.EOFException if this file reaches the end before reading * eight bytes. * @exception java.io.IOException if an I/O error occurs. */ public final long readLong() throws IOException { return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL); } /** * Reads a float from this file. This method reads an * int value as if by the readInt method * and then converts that int to a float * using the intBitsToFloat method in class * Float. *

* This method blocks until the four bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next four bytes of this file, interpreted as a * float. * @exception java.io.EOFException if this file reaches the end before reading * four bytes. * @exception java.io.IOException if an I/O error occurs. * @see com.sun.xfile.XRandomAccessFile#readInt() * @see java.lang.Float#intBitsToFloat(int) */ public final float readFloat() throws IOException { return Float.intBitsToFloat(readInt()); } /** * Reads a double from this file. This method reads a * long value as if by the readLong method * and then converts that long to a double * using the longBitsToDouble method in * class Double. *

* This method blocks until the eight bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return the next eight bytes of this file, interpreted as a * double. * @exception java.io.EOFException if this file reaches the end before reading * eight bytes. * @exception java.io.IOException if an I/O error occurs. * @see com.sun.xfile.XRandomAccessFile#readLong() * @see java.lang.Double#longBitsToDouble(long) */ public final double readDouble() throws IOException { return Double.longBitsToDouble(readLong()); } /** * Reads the next line of text from this file. This method * successively reads bytes from the file until it reaches the end of * a line of text. *

* A line of text is terminated by a carriage-return character * ('\r'), a newline character ('\n'), a * carriage-return character immediately followed by a newline * character, or the end of the input stream. The line-terminating * character(s), if any, are included as part of the string returned. *

* This method blocks until a newline character is read, a carriage * return and the byte following it are read (to see if it is a * newline), the end of the stream is detected, or an exception is thrown. * * @return the next line of text from this file. * @exception java.io.IOException if an I/O error occurs. */ public final String readLine() throws IOException { StringBuffer input = new StringBuffer(); int c; while (((c = read()) != -1) && (c != '\n')) { input.append((char)c); } if ((c == -1) && (input.length() == 0)) { return null; } return input.toString(); } /** * Reads in a string from this file. The string has been encoded * using a modified UTF-8 format. *

* The first two bytes are read as if by * readUnsignedShort. This value gives the number of * following bytes that are in the encoded string, not * the length of the resulting string. The following bytes are then * interpreted as bytes encoding characters in the UTF-8 format * and are converted into characters. *

* This method blocks until all the bytes are read, the end of the * stream is detected, or an exception is thrown. * * @return a Unicode string. * @exception java.io.EOFException if this file reaches the end before * reading all the bytes. * @exception java.io.IOException if an I/O error occurs. * @exception java.io.UTFDataFormatException if the bytes do not represent * valid UTF-8 encoding of a Unicode string. * @see com.sun.xfile.XRandomAccessFile#readUnsignedShort() */ public final String readUTF() throws IOException { return DataInputStream.readUTF(this); } /** * Writes a boolean to the file as a 1-byte value. The * value true is written out as the value * (byte)1; the value false is written out * as the value (byte)0. * * @param v a boolean value to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeBoolean(boolean v) throws IOException { write(v ? 1 : 0); //written++; } /** * Writes a byte to the file as a 1-byte value. * * @param v a byte value to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeByte(int v) throws IOException { write(v); //written++; } /** * Writes a short to the file as two bytes, high byte first. * * @param v a short to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeShort(int v) throws IOException { write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); //written += 2; } /** * Writes a char to the file as a 2-byte value, high * byte first. * * @param v a char value to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeChar(int v) throws IOException { write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); //written += 2; } /** * Writes an int to the file as four bytes, high byte first. * * @param v an int to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeInt(int v) throws IOException { write((v >>> 24) & 0xFF); write((v >>> 16) & 0xFF); write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); //written += 4; } /** * Writes a long to the file as eight bytes, high byte first. * * @param v a long to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeLong(long v) throws IOException { write((int)(v >>> 56) & 0xFF); write((int)(v >>> 48) & 0xFF); write((int)(v >>> 40) & 0xFF); write((int)(v >>> 32) & 0xFF); write((int)(v >>> 24) & 0xFF); write((int)(v >>> 16) & 0xFF); write((int)(v >>> 8) & 0xFF); write((int)(v >>> 0) & 0xFF); //written += 8; } /** * Converts the float argument to an int using the * floatToIntBits method in class Float, * and then writes that int value to the file as a * 4-byte quantity, high byte first. * * @param v a float value to be written. * @exception java.io.IOException if an I/O error occurs. * @see java.lang.Float#floatToIntBits(float) */ public final void writeFloat(float v) throws IOException { writeInt(Float.floatToIntBits(v)); } /** * Converts the double argument to a long using the * doubleToLongBits method in class Double, * and then writes that long value to the file as an * 8-byte quantity, high byte first. * * @param v a double value to be written. * @exception java.io.IOException if an I/O error occurs. * @see java.lang.Double#doubleToLongBits(double) */ public final void writeDouble(double v) throws IOException { writeLong(Double.doubleToLongBits(v)); } /** * Writes the string to the file as a sequence of bytes. Each * character in the string is written out, in sequence, by discarding * its high eight bits. * * @param s a string of bytes to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeBytes(String s) throws IOException { int len = s.length(); for (int i = 0 ; i < len ; i++) { write((byte)s.charAt(i)); } //written += len; } /** * Writes a string to the file as a sequence of characters. Each * character is written to the data output stream as if by the * writeChar method. * * @param s a String value to be written. * @exception java.io.IOException if an I/O error occurs. * @see com.sun.xfile.XRandomAccessFile#writeChar(int) */ public final void writeChars(String s) throws IOException { int len = s.length(); for (int i = 0 ; i < len ; i++) { int v = s.charAt(i); write((v >>> 8) & 0xFF); write((v >>> 0) & 0xFF); } //written += len * 2; } /** * Writes a string to the file using UTF-8 encoding in a * machine-independent manner. *

* First, two bytes are written to the file as if by the * writeShort method giving the number of bytes to * follow. This value is the number of bytes actually written out, * not the length of the string. Following the length, each character * of the string is output, in sequence, using the UTF-8 encoding * for each character. * * @param str a string to be written. * @exception java.io.IOException if an I/O error occurs. */ public final void writeUTF(String str) throws IOException { int strlen = str.length(); int utflen = 0; for (int i = 0 ; i < strlen ; i++) { int c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { utflen++; } else if (c > 0x07FF) { utflen += 3; } else { utflen += 2; } } if (utflen > 65535) throw new UTFDataFormatException(); write((utflen >>> 8) & 0xFF); write((utflen >>> 0) & 0xFF); for (int i = 0 ; i < strlen ; i++) { int c = str.charAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { write(c); } else if (c > 0x07FF) { write(0xE0 | ((c >> 12) & 0x0F)); write(0x80 | ((c >> 6) & 0x3F)); write(0x80 | ((c >> 0) & 0x3F)); //written += 2; } else { write(0xC0 | ((c >> 6) & 0x1F)); write(0x80 | ((c >> 0) & 0x3F)); //written += 1; } } //written += strlen + 2; } } yanfs-yanfs-1.4/src/main/java/com/sun/xfilechooser/000077500000000000000000000000001356275373100223415ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/xfilechooser/BeanXFile.java000066400000000000000000000110641356275373100250030ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfilechooser; import java.io.File; import com.sun.xfile.*; import java.io.IOException; /** * The BeanXFile class is the interface that makes an XFile object * look like a File object. This class is needed to support the * UI of the JFileChooser which accesses file objects. * Thus all the methods would call the corresponding XFile methods. * * @see #XFile */ public class BeanXFile extends File { private XFile beanXF; /* * BeanXFile constructors which mirror the File I/O constructors. */ public BeanXFile(String path) { super(path); beanXF = new XFile(path); } public BeanXFile(File dir, String name) { super(dir, name); XFile parentXF = new XFile(dir.getAbsolutePath()); beanXF = new XFile(parentXF, name); } /* * XFile Methods that can be accessed. */ public String getPath() { String path = beanXF.getPath(); // For nfs URLs, if the url is nfs://, path is "" if (path == "") path = beanXF.getAbsolutePath(); return path; } public String getAbsolutePath() { return beanXF.getAbsolutePath(); } public String getCanonicalPath() { try { String path = beanXF.getCanonicalPath(); return path; } catch (IOException e) { String path = beanXF.getAbsolutePath(); return path; } } public String getName() { String fname = beanXF.getName(); if (fname == null) return(beanXF.getAbsolutePath()); else return(fname); } public boolean renameTo(File dest) { XFile tmpFile = new XFile(dest.getAbsolutePath()); return (beanXF.renameTo(tmpFile)); } public String getParent() { return beanXF.getParent(); } public boolean exists() { return beanXF.exists(); } public boolean canWrite(){ return beanXF.canWrite(); } public boolean canRead() { return beanXF.canRead(); } public boolean isFile() { return beanXF.isFile(); } public boolean isDirectory() { return beanXF.isDirectory(); } public boolean isAbsolute() { // For nfs urls: isAbsolute is always true return beanXF.isAbsolute(); } public boolean equals(Object obj) { /* * Need to pass the XFile object to *.equals because * it checks for instance of XFile */ XFile xf = new XFile(((File)obj).getAbsolutePath()); return beanXF.equals(xf); } public long lastModified() { return beanXF.lastModified(); } public long length() { return beanXF.length(); } public boolean mkdir() { return beanXF.mkdir(); } public boolean mkdirs() { return beanXF.mkdirs(); } public String[] list() { return beanXF.list(); } public String toString() { return beanXF.toString(); } public boolean delete() { return beanXF.delete(); } } yanfs-yanfs-1.4/src/main/java/com/sun/xfilechooser/DialogEditor.java000066400000000000000000000066311356275373100255600ustar00rootroot00000000000000/* * Copyright (c) 1998, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.xfilechooser; import java.beans.*; import javax.swing.*; import javax.swing.filechooser.*; import java.util.*; import com.sun.xfilechooser.*; /** * An editor to set the Dialog Type of XFileChooser. Used during * customization via a bean editor. * @see #XFileChooserBeanInfo */ public class DialogEditor extends PropertyEditorSupport { /* For I18N */ private static ResourceBundle rb = ResourceBundle.getBundle("com.sun.xfilechooser.EditorResource"/*NOI18N*/); int[] dialogValues = {JFileChooser.OPEN_DIALOG, JFileChooser.SAVE_DIALOG, JFileChooser.CUSTOM_DIALOG}; String[] dialogNames = {rb.getString("Open"), rb.getString("Save"), rb.getString("Custom")}; /** * Provides the valid dialog type: Open, Save, or Custom * @return String name of the valid dialog type */ public String[] getTags() { return dialogNames; } /** * Gets the integer value of current selected dialog type and returns the * corresponding string of dialog type. * @return String name of type of dialog */ public String getAsText() { int s = ((Integer)getValue()).intValue(); for (int i=0; i

\n/

\n
\n"); } else { buf.append("

\n" + path + "

\n
\n"); } // Display a URL link to the parent directory if this is // not the root directory if (!root_directory) { String parentURL = url.toString(); int limit = parentURL.length() - 1; if (url.getFile() != null) { if (parentURL.endsWith("/")) { limit--; } parentURL = parentURL.substring(0, parentURL.lastIndexOf('/', limit)); buf.append(""); buf.append("

Go To Parent Directory

\n
\n"); } } // Display the list of files in the directory dirList = nfsFile.list(); if (dirList != null) { // Sort the entries in the directory list StringCompare strComp = new StringCompare(); //Sort.quicksort(dirList, strComp); Arrays.sort(dirList, strComp); boolean hideDotFiles = Boolean.getBoolean("file.hidedotfiles"); for (int i = 0 ; i < dirList.length ; i++) { XFile dirEntry; // Don't display the ".." or "." directory entries if (dirList[i].equals("..") || dirList[i].equals(".")) { continue; } // Skip files beginning with '.' if the file.hidedotfiles // property is set if (hideDotFiles) { if (dirList[i].charAt(0) == '.') { continue; } } // Display an image file for each directory entry buf.append("\n"); } else if (dirEntry.isFile()) { String imageFileName = MimeEntry_defaultImagePath + "/file.gif"; // Find the file image to use using the file's .suffix entry = mt.findByFileName(dirList[i]); if (entry != null) { String realImageName = entry.getImageFileName(); if (realImageName != null) { imageFileName = realImageName; } } buf.append(imageFileName); buf.append("\" WIDTH=" + iconWidth + " HEIGHT=" + iconHeight + ">\n"); } else { // Entry is a symbolic link. Use the default file image for now. buf.append(MimeEntry_defaultImagePath + "/file.gif\" WIDTH=" + iconWidth + " HEIGHT=" + iconHeight + ">\n"); } //dirEntry.close(); // Display the directory entry's name buf.append(""); buf.append(dirList[i] + "\n
"); } } // Finish the HTML document buf.append("\n\n"); // Hand the input stream off to HotJava is = new ByteArrayInputStream(buf.toString().getBytes()); } else { // Mark the input stream we return as containing a certain file type // by looking up the file name in the mimetable entry = mt.findByFileName(path); if (entry != null) { props.add("content-type", entry.getType()); } setProperties(props); if (!nfsFile.exists()) { throw new IOException("Cannot Access File " + nfsFile.getPath() + "!"); } // Hand the input stream off to HotJava is = new XFileInputStream(nfsFile); if (is == null) { throw new IOException("Unable to Open InputStream for " + url.getFile()); } } return is; } } /** * StringCompare implements the Compare interface. * Enables the comparison of two String objects. */ class StringCompare implements Comparator { /** * compare * @param str1 - an Object that is presumes is a String Object. * @param str1 - an Object that is presumes is a String Object. * @return -1 if str1 < str2, 0 if str1 == str2, 1 if str1 > str2 */ public int compare(String str1, String str2) { String s1, s2; s1 = str1.toLowerCase(); s2 = str2.toLowerCase(); return s1.compareTo(s2); } } yanfs-yanfs-1.4/src/main/java/com/sun/zip/000077500000000000000000000000001356275373100204515ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/java/com/sun/zip/XFileAccessor.java000066400000000000000000000260641356275373100240160ustar00rootroot00000000000000/* * Copyright (c) 1997, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.zip; import com.sun.xfile.*; import java.io.*; import java.util.*; import java.util.zip.*; /** * The XFileAccessor interface is implemented by filesystems that * need to be accessed via the XFile API. * * @author Brent Callaghan * @version 1.0, 04/08/98 * @see com.sun.xfile.XFile */ public class XFileAccessor implements com.sun.xfile.XFileAccessor { private XFile xf; private InputStream iStream; private long fp; // file pointer private ZipFile zf; private ZipEntry ze; private String path; private ZipURL zu; private Enumeration zipList; /** * Open this file object * * @param xf the XFile for this file * @param serial true if serial access * @param readOnly true if read only */ public boolean open(XFile xf, boolean serial, boolean readOnly) { this.xf = xf; try { zu = new ZipURL(xf.getAbsolutePath()); zf = new ZipFile(zu.getLocation()); zipList = zf.entries(); path = zu.getPath(); if (path != null && !path.equals("")) { ze = zf.getEntry(path); if (ze == null) { path += "/"; ze = zf.getEntry(path); } } return true; } catch (IOException e) { return false; } } /** * Get the XFile for this Accessor * * @return XFile for this object */ public XFile getXFile() { return xf; } /** * Tests if this XFileAccessor object exists. * * @return true if the file specified by this object * exists; false otherwise. */ public boolean exists() { return ze != null; } /** * Tests if the application can write to this file. * * @return true if the application is allowed to * write to a file whose name is specified by this * object; false otherwise. */ public boolean canWrite() { return false; } /** * Tests if the application can read from the specified file. * * @return true if the file specified by this * object exists and the application can read the file; * false otherwise. */ public boolean canRead() { return true; } /** * Tests if the file represented by this XFileAccessor * object is a directory. * * @return true if this XFileAccessor object * exists and is a directory; false * otherwise. */ public boolean isDirectory() { if (ze != null) return ze.isDirectory(); /* * The Zip file may not have an explicit directory * entry so we may need to infer its presence by * checking the pathnames of the Zip entries. */ String dirPath = path.endsWith("/") ? path : path + "/"; while (zipList.hasMoreElements()) { ZipEntry z = (ZipEntry)zipList.nextElement(); if (z.getName().startsWith(dirPath)) return true; } return false; } /** * Tests if the file represented by this * object is a "normal" file. *

* A file is "normal" if it is not a directory and, in * addition, satisfies other system-dependent criteria. Any * non-directory file created by a Java application is * guaranteed to be a normal file. * * @return true if the file specified by this * XFile object exists and is a "normal" * file; false otherwise. */ public boolean isFile() { if (ze != null) return ! ze.isDirectory(); return ! isDirectory(); } /** * Returns the time that the file represented by this * XFile object was last modified. *

* The return value is system dependent and should only be * used to compare with other values returned by last modified. * It should not be interpreted as an absolute time. * * @return the time the file specified by this object was last * modified, or 0L if the specified file * does not exist. */ public long lastModified() { return ze.getTime(); } /** * Returns the length of the file represented by this * XFileAccessor object. * * @return the length, in bytes, of the file specified by * this object, or 0L if the specified * file does not exist. */ public long length() { return ze.getSize(); } /** * Creates a file whose pathname is specified by this * XFileAccessor object. * * @return true if the file could be created; * false otherwise. */ public boolean mkfile() { return false; } /** * Creates a directory whose pathname is specified by this * XFileAccessor object. * * @return true if the directory could be created; * false otherwise. */ public boolean mkdir() { return false; } /** * Renames the file specified by this XFileAccessor object to * have the pathname given by the XFileAccessor object argument. * * @param dest the new filename. * @return true if the renaming succeeds; * false otherwise. */ public boolean renameTo(XFile dest) { return false; } /** * Returns a list of the files in the directory specified by * this XFileAccessor object. * * @return an array of file names in the specified directory. * This list does not include the current directory or * the parent directory ("." and * ".." on Unix systems). */ public String[] list() { String dirPath = path.endsWith("/") ? path : path + "/"; int plen = dirPath.length(); String[] s = new String[8]; int i = 0; while (zipList.hasMoreElements()) { ZipEntry z = (ZipEntry)zipList.nextElement(); String zname = z.getName(); if (zname.startsWith(dirPath)) { int slash = zname.indexOf('/', plen); if (slash < 0) slash = zname.length(); s[i++] = zname.substring(plen, slash); if (i >= s.length) { // last elem in array ? String[] tmp = s; s = new String[i*2]; // double its size System.arraycopy(tmp, 0, s, 0, i); } } } /* * Trim array to exact size */ if (i < s.length) { String[] tmp = s; s = new String[i]; System.arraycopy(tmp, 0, s, 0, i); } return s; } /** * Deletes the file specified by this object. If the target * file to be deleted is a directory, it must be empty for * deletion to succeed. * * @return true if the file is successfully deleted; * false otherwise. */ public boolean delete() { return false; } /** * Reads a subarray as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @return number of bytes read; -1 if EOF * @exception IOException If an I/O error has occurred. */ public int read(byte b[], int off, int len, long foff) throws IOException { if (iStream == null) iStream = zf.getInputStream(ze); if (foff > fp) { iStream.skip(foff - fp); fp = foff; } int c = iStream.read(b, off, len); if (c > 0) fp += c; return (c); } /** * Writes a sub array as a sequence of bytes. * * @param b the data to be written * @param off the start offset in the data * @param len the number of bytes that are written * @param foff the offset into the file * @exception IOException If an I/O error has occurred. */ public void write(byte b[], int off, int len, long foff) throws IOException { throw new IOException("write not supported"); } /** * Forces any buffered output bytes to be written out. *

* Since RandomAccessFile has no corresponding method * this does nothing. * * @exception IOException if an I/O error occurs. */ public void flush() throws IOException { } /** * Close the file * * @exception IOException If an I/O error has occurred. */ public void close() throws IOException { if (iStream != null) iStream.close(); } /** * Returns a string representation of this object. * * @return a string giving the pathname of this object. */ public String toString() { return zu.toString(); } } yanfs-yanfs-1.4/src/main/java/com/sun/zip/ZipURL.java000066400000000000000000000065131356275373100224460ustar00rootroot00000000000000/* * Copyright (c) 1997, 2007 Sun Microsystems, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE * LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED * AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed,licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */ package com.sun.zip; import java.net.MalformedURLException; /** * @author Brent Callaghan */ public class ZipURL { private String url; private String protocol; private String location; private String path; /* * Undocumented testing options */ private int version; private String proto; private boolean pub = true; public ZipURL(String url) throws MalformedURLException { int p, q, r; int end = url.length(); url = url.trim(); // remove leading & trailing spaces this.url = url; p = url.indexOf(':'); if (p < 0) throw new MalformedURLException("colon expected"); protocol = url.substring(0, p); p++; // skip colon if (url.regionMatches(p, "//", 0, 2)) { // have location p += 2; q = url.indexOf('/', p); if (q < 0) q = end; location = url.substring(0, q); r = q; // no port if (p < r) location = url.substring(p, r); } else { q = p; } if (q < end) path = url.substring(q + 1, end); } public String getProtocol() { return (protocol); } public String getLocation() { return (location); } public String getPath() { return (path); } public String toString() { String s = getProtocol() + ":"; if (location != null) s += "//" + location; if (path != null) s += "/" + path; return (s); } } yanfs-yanfs-1.4/src/main/resources/000077500000000000000000000000001356275373100173555ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/resources/com/000077500000000000000000000000001356275373100201335ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/resources/com/sun/000077500000000000000000000000001356275373100207405ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/resources/com/sun/nfs/000077500000000000000000000000001356275373100215265ustar00rootroot00000000000000yanfs-yanfs-1.4/src/main/resources/com/sun/nfs/nfssec.properties000066400000000000000000000067511356275373100251360ustar00rootroot00000000000000# # Copyright (c) 1999, 2007 Sun Microsystems, Inc. # All Rights Reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # -Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # -Redistribution in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Sun Microsystems, Inc. or the names of contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # This software is provided "AS IS," without a warranty of any kind. ALL # EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING # ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR # PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS # SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE # AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE # SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE # LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, # SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED # AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR # INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGES. # # You acknowledge that this software is not designed,licensed or intended # for use in the design, construction, operation or maintenance of any # nuclear facility. # # The WebNFS security services properties file. # # This file provides a mapping from nfs pseudo flavors to GSS-API # oriented triples. This mapping # should have been registed via iana@isi.edu. # # # Each entry is of the form: # # nfsFlavorNumber=nfsFlavorName:mechanismOID:service:qualityProtection # # where # # nfsFlavorNumber is the nfs/rpcsec_gss pseudo flavor number # registered with iana@isi.edu. # # nfsFlavorName is the nfs/rpcsec_gss pseudo flavor name for # the coresponding flavor number. # # mechanismOID is an unique ISO object identifier (OID) # for a security mechanism. # # e.g. 1.3.6.1.4.1.42.2.26.1.2 is dummy mechanism # 1.2.840.113554.1.2.2 is kerberos_v5 mechanism # # service is one of the following strings: privacy, integrity, none # # privacy - encrypt the whole messages # integrity - checksum the messages # none - no per-message protection but authentication only # # qualityProtection (QOP) is to provide finer control of per-message # protection algorithms to be used. 0 means to use a # default QOP defined by each mechanism. # # # # NOTE: nfs flavor names v.s. numbers # # dummy 390000 # dummyi 390001 # dummyp 390002 # # Examples: # # RPCSEC_GSS/dummy mechanism: # # 390000=dummy:1.3.6.1.4.1.42.2.26.1.2:none:0 # 390001=dummyi:1.3.6.1.4.1.42.2.26.1.2:integrity:0 # 390002=dummyp:1.3.6.1.4.1.42.2.26.1.2:privacy:0 # AUTH_SYS 1=sys::: # # # If the remote file system allows a range of security services for # the clients to get thru, the "prefer" key indicates which security # service this client prefers to use. # # Example: # # prefer=390002 # # The "default" key is to identify a default security service # to be used by WebNFS. Specify one of the numbers defined in this file. # default=1