View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.ipc;
19  
20  import java.io.DataInput;
21  import java.io.DataOutput;
22  import java.io.IOException;
23  
24  import org.apache.hadoop.hbase.security.HBaseSaslRpcServer.AuthMethod;
25  import org.apache.hadoop.io.Text;
26  import org.apache.hadoop.hbase.security.User;
27  import org.apache.hadoop.security.UserGroupInformation;
28  
29  /**
30   * The IPC connection header sent by the client to the server
31   * on connection establishment.  Part of the {@link SecureRpcEngine}
32   * implementation.
33   */
34  class SecureConnectionHeader extends ConnectionHeader {
35    private User user = null;
36    private AuthMethod authMethod;
37  
38    public SecureConnectionHeader() {}
39  
40    /**
41     * Create a new {@link org.apache.hadoop.hbase.ipc.SecureConnectionHeader} with the given <code>protocol</code>
42     * and {@link org.apache.hadoop.security.UserGroupInformation}.
43     * @param protocol protocol used for communication between the IPC client
44     *                 and the server
45     * @param ugi {@link org.apache.hadoop.security.UserGroupInformation} of the client communicating with
46     *            the server
47     */
48    public SecureConnectionHeader(String protocol, User user, AuthMethod authMethod) {
49      this.protocol = protocol;
50      this.user = user;
51      this.authMethod = authMethod;
52    }
53  
54    @Override
55    public void readFields(DataInput in) throws IOException {
56      protocol = Text.readString(in);
57      if (protocol.isEmpty()) {
58        protocol = null;
59      }
60      boolean ugiUsernamePresent = in.readBoolean();
61      if (ugiUsernamePresent) {
62        String username = in.readUTF();
63        boolean realUserNamePresent = in.readBoolean();
64        if (realUserNamePresent) {
65          String realUserName = in.readUTF();
66          UserGroupInformation realUserUgi =
67              UserGroupInformation.createRemoteUser(realUserName);
68          user = User.create(
69              UserGroupInformation.createProxyUser(username, realUserUgi));
70        } else {
71          user = User.create(UserGroupInformation.createRemoteUser(username));
72        }
73      } else {
74        user = null;
75      }
76    }
77  
78    @Override
79    public void write(DataOutput out) throws IOException {
80      Text.writeString(out, (protocol == null) ? "" : protocol);
81      if (user != null) {
82        UserGroupInformation ugi = user.getUGI();
83        if (authMethod == AuthMethod.KERBEROS ||
84            authMethod == AuthMethod.KERBEROS_USER_REALM) {
85          // Send effective user for Kerberos auth
86          out.writeBoolean(true);
87          out.writeUTF(ugi.getUserName());
88          out.writeBoolean(false);
89        } else if (authMethod == AuthMethod.DIGEST) {
90          // Don't send user for token auth
91          out.writeBoolean(false);
92        } else {
93          //Send both effective user and real user for simple auth
94          out.writeBoolean(true);
95          out.writeUTF(ugi.getUserName());
96          if (ugi.getRealUser() != null) {
97            out.writeBoolean(true);
98            out.writeUTF(ugi.getRealUser().getUserName());
99          } else {
100           out.writeBoolean(false);
101         }
102       }
103     } else {
104       out.writeBoolean(false);
105     }
106   }
107 
108   public String getProtocol() {
109     return protocol;
110   }
111 
112   public User getUser() {
113     return user;
114   }
115 
116   public String toString() {
117     return protocol + "-" + user;
118   }
119 }