aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/sun/security/jgss/krb5/Krb5ProxyCredential.java
blob: 8fbe93a57685dcd1b6aec5500b10e3e8fd920606 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.jgss.krb5;

import org.ietf.jgss.*;
import sun.security.jgss.GSSCaller;
import sun.security.jgss.spi.*;

import java.io.IOException;

import sun.security.krb5.Credentials;
import sun.security.krb5.KrbException;
import sun.security.krb5.internal.Ticket;

import javax.security.auth.kerberos.KerberosTicket;

/**
 * Implements the krb5 proxy credential element used in constrained
 * delegation. It is used in both impersonation (where there is no Kerberos 5
 * communication between the middle server and the client) and normal
 * constrained delegation (where there is, but client has not called
 * requestCredDeleg(true)).
 * @since 1.8
 */

public class Krb5ProxyCredential
    implements Krb5CredElement {

    public final Krb5InitCredential self;   // the middle server
    private final Krb5NameElement client;     // the client

    // The ticket with cname=client and sname=self. This can be a normal
    // service ticket or an S4U2self ticket.
    public final Ticket tkt;

    Krb5ProxyCredential(Krb5InitCredential self, Krb5NameElement client,
            Ticket tkt) {
        this.self = self;
        this.tkt = tkt;
        this.client = client;
    }

    // The client name behind the proxy
    @Override
    public final Krb5NameElement getName() throws GSSException {
        return client;
    }

    @Override
    public int getInitLifetime() throws GSSException {
        // endTime of tkt is not used by KDC, and it's also not
        // available in the case of kerberos constr deleg
        return self.getInitLifetime();
    }

    @Override
    public int getAcceptLifetime() throws GSSException {
        return 0;
    }

    @Override
    public boolean isInitiatorCredential() throws GSSException {
        return true;
    }

    @Override
    public boolean isAcceptorCredential() throws GSSException {
        return false;
    }

    @Override
    public final Oid getMechanism() {
        return Krb5MechFactory.GSS_KRB5_MECH_OID;
    }

    @Override
    public final java.security.Provider getProvider() {
        return Krb5MechFactory.PROVIDER;
    }

    @Override
    public void dispose() throws GSSException {
        try {
            self.destroy();
        } catch (javax.security.auth.DestroyFailedException e) {
            GSSException gssException =
                new GSSException(GSSException.FAILURE, -1,
                 "Could not destroy credentials - " + e.getMessage());
            gssException.initCause(e);
        }
    }

    @Override
    public GSSCredentialSpi impersonate(GSSNameSpi name) throws GSSException {
        // Cannot impersonate multiple levels without the impersonatee's TGT.
        throw new GSSException(GSSException.FAILURE, -1,
                "Only an initiate credentials can impersonate");
    }

    // Try to see if a default credential should act as an impersonator.
    static Krb5CredElement tryImpersonation(GSSCaller caller,
            Krb5InitCredential initiator) throws GSSException {

        try {
            KerberosTicket proxy = initiator.proxyTicket;
            if (proxy != null) {
                Credentials proxyCreds = Krb5Util.ticketToCreds(proxy);
                return new Krb5ProxyCredential(initiator,
                        Krb5NameElement.getInstance(proxyCreds.getClient()),
                        proxyCreds.getTicket());
            } else {
                return initiator;
            }
        } catch (KrbException | IOException e) {
            throw new GSSException(GSSException.DEFECTIVE_CREDENTIAL, -1,
                    "Cannot create proxy credential");
        }
    }
}