View Javadoc
1   /*
2    * Copyright 2025 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.socksx.v5;
17  
18  import io.netty.util.internal.ObjectUtil;
19  
20  /**
21   * The status of a SOCKS5 private authentication response.
22   * <p>
23   * RFC 1928 reserves method codes 0x80-0xFE for private authentication methods but does not
24   * specify the format of their subnegotiation. This class provides standard status codes
25   * for the private authentication response that follow the pattern established by the
26   * username/password authentication method in RFC 1929.
27   * </p>
28   *
29   * @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC 1928 Section 3</a>
30   * @see <a href="https://www.ietf.org/rfc/rfc1929.txt">RFC 1929</a>
31   */
32  public final class Socks5PrivateAuthStatus implements Comparable<Socks5PrivateAuthStatus> {
33  
34      public static final Socks5PrivateAuthStatus SUCCESS = new Socks5PrivateAuthStatus(0x00, "SUCCESS");
35      public static final Socks5PrivateAuthStatus FAILURE = new Socks5PrivateAuthStatus(0xFF, "FAILURE");
36  
37      /**
38       * Returns the {@link Socks5PrivateAuthStatus} instance that corresponds to the specified byte value.
39       * <p>
40       * This method returns a singleton instance for standard status codes:
41       * <ul>
42       *   <li>0x00: {@link #SUCCESS}</li>
43       *   <li>0xFF: {@link #FAILURE}</li>
44       * </ul>
45       * For any other values, a new instance is created.
46       *
47       * @param b The byte value of the SOCKS5 private authentication status
48       * @return The corresponding {@link Socks5PrivateAuthStatus} instance
49       */
50      public static Socks5PrivateAuthStatus valueOf(byte b) {
51          switch (b) {
52              case 0x00:
53                  return SUCCESS;
54              case (byte) 0xFF:
55                  return FAILURE;
56          }
57  
58          return new Socks5PrivateAuthStatus(b);
59      }
60  
61      private final byte byteValue;
62      private final String name;
63      private String text;
64  
65      private Socks5PrivateAuthStatus(int byteValue) {
66          this(byteValue, "UNKNOWN");
67      }
68  
69      /**
70       * Creates a new SOCKS5 private authentication status.
71       *
72       * @param byteValue The byte value representing the authentication status
73       *                  (0x00 for success, 0xFF for failure, or custom values)
74       * @param name      The descriptive name of this status, must not be null
75       * @throws NullPointerException if the name is null
76       */
77      public Socks5PrivateAuthStatus(int byteValue, String name) {
78          this.name = ObjectUtil.checkNotNull(name, "name");
79          this.byteValue = (byte) byteValue;
80      }
81  
82      public byte byteValue() {
83          return byteValue;
84      }
85  
86      public boolean isSuccess() {
87          return byteValue == 0;
88      }
89  
90      @Override
91      public int hashCode() {
92          return byteValue;
93      }
94  
95      @Override
96      public boolean equals(Object obj) {
97          if (!(obj instanceof Socks5PrivateAuthStatus)) {
98              return false;
99          }
100 
101         return byteValue == ((Socks5PrivateAuthStatus) obj).byteValue;
102     }
103 
104     @Override
105     public int compareTo(Socks5PrivateAuthStatus o) {
106         return byteValue - o.byteValue;
107     }
108 
109     @Override
110     public String toString() {
111         String text = this.text;
112         if (text == null) {
113             this.text = text = name + '(' + (byteValue & 0xFF) + ')';
114         }
115         return text;
116     }
117 }