001: /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
002: /*
003: Copyright (c) 2006-2008 ymnk, JCraft,Inc. All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: 1. Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010:
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in
013: the documentation and/or other materials provided with the distribution.
014:
015: 3. The names of the authors may not be used to endorse or promote products
016: derived from this software without specific prior written permission.
017:
018: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
019: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
020: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
021: INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
022: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
024: OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
027: EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jcraft.jsch.jgss;
031:
032: import com.jcraft.jsch.JSchException;
033:
034: import java.net.InetAddress;
035: import java.net.UnknownHostException;
036: import org.ietf.jgss.GSSContext;
037: import org.ietf.jgss.GSSCredential;
038: import org.ietf.jgss.GSSException;
039: import org.ietf.jgss.GSSManager;
040: import org.ietf.jgss.GSSName;
041: import org.ietf.jgss.MessageProp;
042: import org.ietf.jgss.Oid;
043:
044: public class GSSContextKrb5 implements com.jcraft.jsch.GSSContext {
045:
046: private static final String pUseSubjectCredsOnly = "javax.security.auth.useSubjectCredsOnly";
047: private static String useSubjectCredsOnly = getSystemProperty(pUseSubjectCredsOnly);
048:
049: private GSSContext context = null;
050:
051: public void create(String user, String host) throws JSchException {
052: try {
053: // RFC 1964
054: Oid krb5 = new Oid("1.2.840.113554.1.2.2");
055: // Kerberos Principal Name Form
056: Oid principalName = new Oid("1.2.840.113554.1.2.2.1");
057:
058: GSSManager mgr = GSSManager.getInstance();
059:
060: GSSCredential crd = null;
061: /*
062: try{
063: GSSName _user=mgr.createName(user, principalName);
064: crd=mgr.createCredential(_user,
065: GSSCredential.DEFAULT_LIFETIME,
066: krb5,
067: GSSCredential.INITIATE_ONLY);
068: }
069: catch(GSSException crdex){
070: }
071: */
072:
073: String cname = host;
074: try {
075: cname = InetAddress.getByName(cname)
076: .getCanonicalHostName();
077: } catch (UnknownHostException e) {
078: }
079: GSSName _host = mgr.createName("host/" + cname,
080: principalName);
081:
082: context = mgr.createContext(_host, krb5, crd,
083: GSSContext.DEFAULT_LIFETIME);
084:
085: // RFC4462 3.4. GSS-API Session
086: //
087: // When calling GSS_Init_sec_context(), the client MUST set
088: // integ_req_flag to "true" to request that per-message integrity
089: // protection be supported for this context. In addition,
090: // deleg_req_flag MAY be set to "true" to request access delegation, if
091: // requested by the user.
092: //
093: // Since the user authentication process by its nature authenticates
094: // only the client, the setting of mutual_req_flag is not needed for
095: // this process. This flag SHOULD be set to "false".
096:
097: // TODO: OpenSSH's sshd does accepts 'false' for mutual_req_flag
098: //context.requestMutualAuth(false);
099: context.requestMutualAuth(true);
100: context.requestConf(true);
101: context.requestInteg(true); // for MIC
102: context.requestCredDeleg(true);
103: context.requestAnonymity(false);
104:
105: return;
106: } catch (GSSException ex) {
107: throw new JSchException(ex.toString());
108: }
109: }
110:
111: public boolean isEstablished() {
112: return context.isEstablished();
113: }
114:
115: public byte[] init(byte[] token, int s, int l) throws JSchException {
116: try {
117: // Without setting "javax.security.auth.useSubjectCredsOnly" to "false",
118: // Sun's JVM for Un*x will show messages to stderr in
119: // processing context.initSecContext().
120: // This hack is not thread safe ;-<.
121: // If that property is explicitly given as "true" or "false",
122: // this hack must not be invoked.
123: if (useSubjectCredsOnly == null) {
124: setSystemProperty(pUseSubjectCredsOnly, "false");
125: }
126: return context.initSecContext(token, 0, l);
127: } catch (GSSException ex) {
128: throw new JSchException(ex.toString());
129: } catch (java.lang.SecurityException ex) {
130: throw new JSchException(ex.toString());
131: } finally {
132: if (useSubjectCredsOnly == null) {
133: // By the default, it must be "true".
134: setSystemProperty(pUseSubjectCredsOnly, "true");
135: }
136: }
137: }
138:
139: public byte[] getMIC(byte[] message, int s, int l) {
140: try {
141: MessageProp prop = new MessageProp(0, true);
142: return context.getMIC(message, s, l, prop);
143: } catch (GSSException ex) {
144: return null;
145: }
146: }
147:
148: public void dispose() {
149: try {
150: context.dispose();
151: } catch (GSSException ex) {
152: }
153: }
154:
155: private static String getSystemProperty(String key) {
156: try {
157: return System.getProperty(key);
158: } catch (Exception e) {
159: // We are not allowed to get the System properties.
160: return null;
161: }
162: }
163:
164: private static void setSystemProperty(String key, String value) {
165: try {
166: System.setProperty(key, value);
167: } catch (Exception e) {
168: // We are not allowed to set the System properties.
169: }
170: }
171: }
|