├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .gitignore
├── README.adoc
├── SECURITY.md
├── handler-proxy
├── src
│ ├── test
│ │ └── java
│ │ │ └── io
│ │ │ └── netty
│ │ │ └── contrib
│ │ │ └── handler
│ │ │ └── proxy
│ │ │ ├── TestMode.java
│ │ │ ├── NativeImageHandlerMetadataTest.java
│ │ │ └── UnresponsiveHandler.java
│ └── main
│ │ ├── java
│ │ └── io
│ │ │ └── netty
│ │ │ └── contrib
│ │ │ └── handler
│ │ │ └── proxy
│ │ │ ├── package-info.java
│ │ │ ├── ProxyConnectException.java
│ │ │ └── ProxyConnectionEvent.java
│ │ └── resources
│ │ └── META-INF
│ │ └── native-image
│ │ └── io.netty.contrib
│ │ └── netty-handler-proxy
│ │ └── generated
│ │ └── handlers
│ │ └── reflect-config.json
└── pom.xml
├── codec-socks
├── src
│ ├── main
│ │ └── java
│ │ │ └── io
│ │ │ └── netty
│ │ │ └── contrib
│ │ │ └── handler
│ │ │ └── codec
│ │ │ ├── socks
│ │ │ ├── package-info.java
│ │ │ ├── SocksMessageType.java
│ │ │ ├── SocksRequestType.java
│ │ │ ├── SocksResponseType.java
│ │ │ ├── UnknownSocksRequest.java
│ │ │ ├── UnknownSocksResponse.java
│ │ │ ├── SocksAuthStatus.java
│ │ │ ├── SocksCmdType.java
│ │ │ ├── SocksProtocolVersion.java
│ │ │ ├── SocksSubnegotiationVersion.java
│ │ │ ├── SocksAddressType.java
│ │ │ ├── SocksAuthScheme.java
│ │ │ ├── SocksCmdStatus.java
│ │ │ ├── SocksRequest.java
│ │ │ ├── SocksResponse.java
│ │ │ ├── SocksMessageEncoder.java
│ │ │ ├── SocksInitResponse.java
│ │ │ ├── SocksAuthResponse.java
│ │ │ ├── SocksInitRequest.java
│ │ │ ├── SocksCommonUtils.java
│ │ │ ├── SocksMessage.java
│ │ │ ├── SocksInitResponseDecoder.java
│ │ │ ├── SocksAuthResponseDecoder.java
│ │ │ ├── SocksInitRequestDecoder.java
│ │ │ ├── SocksAuthRequest.java
│ │ │ └── SocksAuthRequestDecoder.java
│ │ │ └── socksx
│ │ │ ├── package-info.java
│ │ │ ├── v4
│ │ │ ├── package-info.java
│ │ │ ├── Socks4Message.java
│ │ │ ├── AbstractSocks4Message.java
│ │ │ ├── Socks4CommandResponse.java
│ │ │ ├── Socks4CommandRequest.java
│ │ │ ├── Socks4ServerEncoder.java
│ │ │ ├── Socks4CommandType.java
│ │ │ ├── Socks4ClientEncoder.java
│ │ │ ├── Socks4CommandStatus.java
│ │ │ ├── DefaultSocks4CommandResponse.java
│ │ │ ├── Socks4ClientDecoder.java
│ │ │ └── DefaultSocks4CommandRequest.java
│ │ │ ├── v5
│ │ │ ├── package-info.java
│ │ │ ├── Socks5Message.java
│ │ │ ├── Socks5InitialResponse.java
│ │ │ ├── Socks5PasswordAuthResponse.java
│ │ │ ├── AbstractSocks5Message.java
│ │ │ ├── Socks5InitialRequest.java
│ │ │ ├── Socks5PasswordAuthRequest.java
│ │ │ ├── Socks5CommandRequest.java
│ │ │ ├── Socks5CommandResponse.java
│ │ │ ├── DefaultSocks5InitialResponse.java
│ │ │ ├── DefaultSocks5PasswordAuthResponse.java
│ │ │ ├── Socks5AddressEncoder.java
│ │ │ ├── Socks5CommandType.java
│ │ │ ├── Socks5AddressType.java
│ │ │ ├── Socks5PasswordAuthStatus.java
│ │ │ ├── DefaultSocks5InitialRequest.java
│ │ │ ├── Socks5AuthMethod.java
│ │ │ ├── Socks5AddressDecoder.java
│ │ │ ├── DefaultSocks5PasswordAuthRequest.java
│ │ │ ├── Socks5PasswordAuthResponseDecoder.java
│ │ │ ├── Socks5InitialResponseDecoder.java
│ │ │ ├── Socks5InitialRequestDecoder.java
│ │ │ ├── Socks5PasswordAuthRequestDecoder.java
│ │ │ ├── DefaultSocks5CommandRequest.java
│ │ │ ├── Socks5CommandStatus.java
│ │ │ └── Socks5ServerEncoder.java
│ │ │ ├── SocksMessage.java
│ │ │ ├── AbstractSocksMessage.java
│ │ │ └── SocksVersion.java
│ └── test
│ │ └── java
│ │ └── io
│ │ └── netty
│ │ └── contrib
│ │ └── handler
│ │ └── codec
│ │ ├── socks
│ │ ├── SocksAuthResponseTest.java
│ │ ├── SocksInitRequestTest.java
│ │ ├── SocksInitResponseTest.java
│ │ ├── SocksCommonTestUtils.java
│ │ ├── SocksAuthResponseDecoderTest.java
│ │ ├── SocksAuthRequestDecoderTest.java
│ │ └── SocksAuthRequestTest.java
│ │ ├── socksx
│ │ ├── v5
│ │ │ ├── DefaultSocks5InitialRequestTest.java
│ │ │ ├── DefaultSocks5InitialResponseTest.java
│ │ │ ├── DefaultSocks5PasswordAuthResponseTest.java
│ │ │ ├── Socks5PasswordAuthRequestDecoderTest.java
│ │ │ ├── Socks5InitialRequestDecoderTest.java
│ │ │ ├── Socks5CommonTestUtils.java
│ │ │ ├── Socks5PasswordAuthResponseDecoderTest.java
│ │ │ ├── DefaultSocks5PasswordAuthRequestTest.java
│ │ │ └── DefaultSocks5CommandRequestTest.java
│ │ └── v4
│ │ │ ├── Socks4CommonTestUtils.java
│ │ │ ├── Socks4ClientDecoderTest.java
│ │ │ └── Socks4ServerDecoderTest.java
│ │ └── NativeImageHandlerMetadataTest.java
└── pom.xml
├── .github
└── workflows
│ ├── release.yml
│ └── ci-build.yml
├── examples
├── pom.xml
└── src
│ └── main
│ └── java
│ └── io
│ └── netty
│ └── contrib
│ └── handler
│ └── codec
│ └── example
│ └── socksproxy
│ ├── SocksServerUtils.java
│ ├── SocksServerInitializer.java
│ ├── DirectClientHandler.java
│ ├── RelayHandler.java
│ └── SocksServer.java
└── NOTICE.txt
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/netty-contrib/socks-proxy/HEAD/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://maven-central.storage-download.googleapis.com/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .project
2 | .classpath
3 | .settings
4 | *.iml
5 | *.ipr
6 | *.iws
7 | .idea/
8 | .shelf/
9 | target/
10 | .DS_Store
11 | hs_err_pid*.log
12 | dependency-reduced-pom.xml
13 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | = Netty 5.x SOCKS Codec and Handler Repository for Netty Contrib
2 |
3 | * Netty core repository: https://github.com/netty/netty
4 | * License: Apache-2.0 License
5 | * Required Java version: Java 11
6 | * Maven coordinates:
7 | ** `io.netty.contrib:netty-socks-proxy:5.0.0.Final-SNAPSHOT`
8 |
9 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | The following versions of this library are supported:
6 |
7 | | Version | Supported |
8 | | ------- | ------------------ |
9 | | 5.0.x | :white_check_mark: |
10 | | < 5.0 | :x: |
11 |
12 | Older versions, for use with Netty 4.1, are located in the Netty repository.
13 |
14 | ## Reporting a security issue
15 |
16 | If you think the bug you found is likely to make Netty-based applications vulnerable to an attack,
17 | please do not use our public issue tracker
18 | but report it to [the dedicated private Google Group](https://groups.google.com/d/forum/netty-security).
19 |
--------------------------------------------------------------------------------
/handler-proxy/src/test/java/io/netty/contrib/handler/proxy/TestMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.proxy;
17 |
18 | enum TestMode {
19 | INTERMEDIARY,
20 | TERMINAL,
21 | UNRESPONSIVE,
22 | }
23 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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 |
17 | /**
18 | * Encoder, decoder and their related message types for Socks.
19 | */
20 | package io.netty.contrib.handler.codec.socks;
21 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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 |
17 | /**
18 | * Encoder, decoder and their related message types for SOCKS protocol.
19 | */
20 | package io.netty.contrib.handler.codec.socksx;
21 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksMessageType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksMessageType {
19 | REQUEST,
20 | RESPONSE,
21 | UNKNOWN
22 | }
23 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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 |
17 | /**
18 | * Encoder, decoder and their related message types for SOCKSv4 protocol.
19 | */
20 | package io.netty.contrib.handler.codec.socksx.v4;
21 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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 |
17 | /**
18 | * Encoder, decoder and their related message types for SOCKSv5 protocol.
19 | */
20 | package io.netty.contrib.handler.codec.socksx.v5;
21 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | workflow_dispatch:
4 | inputs:
5 | version:
6 | description: 'The version being released (pom.xml files will be updated) - leave empty for Maven default'
7 | required: false
8 | type: string
9 | default: ''
10 | netty:
11 | description: 'The version range to use for the Netty Core dependencies - will use value from pom.xml if empty'
12 | required: false
13 | type: string
14 | default: ''
15 | java-version:
16 | description: 'The version of Java to use for building'
17 | required: false
18 | type: string
19 | default: '11'
20 |
21 | jobs:
22 | Release:
23 | uses: netty-contrib/.github/.github/workflows/release.yml@main
24 | with:
25 | version: ${{ inputs.version }}
26 | netty: ${{ inputs.netty }}
27 | java-version: ${{ inputs.java-version }}
28 | secrets: inherit
29 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksRequestType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | /**
19 | * Type of socks request
20 | */
21 | public enum SocksRequestType {
22 | INIT,
23 | AUTH,
24 | CMD,
25 | UNKNOWN
26 | }
27 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksResponseType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | /**
19 | * Type of socks response
20 | */
21 | public enum SocksResponseType {
22 | INIT,
23 | AUTH,
24 | CMD,
25 | UNKNOWN
26 | }
27 |
--------------------------------------------------------------------------------
/handler-proxy/src/main/java/io/netty/contrib/handler/proxy/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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 | /**
17 | * Adds support for client connections via proxy protocols such as
18 | * SOCKS and
19 | * HTTP CONNECT tunneling
20 | */
21 | package io.netty.contrib.handler.proxy;
22 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4Message.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty.contrib.handler.codec.socksx.SocksMessage;
19 |
20 | /**
21 | * A tag interface that all SOCKS4a protocol messages implement.
22 | */
23 | public interface Socks4Message extends SocksMessage {
24 | // Tag interface
25 | }
26 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5Message.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty.contrib.handler.codec.socksx.SocksMessage;
19 |
20 | /**
21 | * A tag interface that all SOCKS5 protocol messages implement.
22 | */
23 | public interface Socks5Message extends SocksMessage {
24 | // Tag interface
25 | }
26 |
--------------------------------------------------------------------------------
/examples/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.netty.contrib
7 | netty-socks-proxy-parent
8 | 5.0.0.Alpha3-SNAPSHOT
9 |
10 |
11 | netty-socks-proxy-examples
12 | 5.0.0.Alpha3-SNAPSHOT
13 |
14 |
15 |
16 | io.netty.contrib
17 | netty-codec-socks
18 | ${project.version}
19 |
20 |
21 | io.netty
22 | netty5-handler
23 | ${netty.version}
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/SocksMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx;
17 |
18 | import io.netty5.handler.codec.DecoderResultProvider;
19 |
20 | /**
21 | * An interface that all SOCKS protocol messages implement.
22 | */
23 | public interface SocksMessage extends DecoderResultProvider {
24 |
25 | /**
26 | * Returns the protocol version of this message.
27 | */
28 | SocksVersion version();
29 | }
30 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksAuthResponseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class SocksAuthResponseTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new SocksAuthResponse(null));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksInitRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class SocksInitRequestTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new SocksInitRequest(null));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksInitResponseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class SocksInitResponseTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new SocksInitResponse(null));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5InitialRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class DefaultSocks5InitialRequestTest {
23 | @Test
24 | public void testConstructorParamsAreNotEmpty() {
25 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5InitialRequest());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5InitialResponseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class DefaultSocks5InitialResponseTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new DefaultSocks5InitialResponse(null));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5PasswordAuthResponseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class DefaultSocks5PasswordAuthResponseTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new DefaultSocks5PasswordAuthResponse(null));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5InitialResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | /**
19 | * An initial SOCKS5 authentication method selection request, as defined in
20 | * the section 3, RFC1928 .
21 | */
22 | public interface Socks5InitialResponse extends Socks5Message {
23 |
24 | /**
25 | * Returns the {@code METHOD} field of this response.
26 | */
27 | Socks5AuthMethod authMethod();
28 | }
29 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | /**
19 | * A SOCKS5 subnegotiation response for username-password authentication, as defined in
20 | * the section 2, RFC1929 .
21 | */
22 | public interface Socks5PasswordAuthResponse extends Socks5Message {
23 | /**
24 | * Returns the status of this response.
25 | */
26 | Socks5PasswordAuthStatus status();
27 | }
28 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/AbstractSocks4Message.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty.contrib.handler.codec.socksx.AbstractSocksMessage;
19 | import io.netty.contrib.handler.codec.socksx.SocksVersion;
20 |
21 | /**
22 | * An abstract {@link Socks4Message}.
23 | */
24 | public abstract class AbstractSocks4Message extends AbstractSocksMessage implements Socks4Message {
25 | @Override
26 | public final SocksVersion version() {
27 | return SocksVersion.SOCKS4a;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/AbstractSocks5Message.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty.contrib.handler.codec.socksx.AbstractSocksMessage;
19 | import io.netty.contrib.handler.codec.socksx.SocksVersion;
20 |
21 | /**
22 | * An abstract {@link Socks5Message}.
23 | */
24 | public abstract class AbstractSocks5Message extends AbstractSocksMessage implements Socks5Message {
25 | @Override
26 | public final SocksVersion version() {
27 | return SocksVersion.SOCKS5;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5InitialRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import java.util.List;
19 |
20 | /**
21 | * An initial SOCKS5 authentication method selection request, as defined in
22 | * the section 3, RFC1928 .
23 | */
24 | public interface Socks5InitialRequest extends Socks5Message {
25 | /**
26 | * Returns the list of desired authentication methods.
27 | */
28 | List authMethods();
29 | }
30 |
--------------------------------------------------------------------------------
/.github/workflows/ci-build.yml:
--------------------------------------------------------------------------------
1 | # ----------------------------------------------------------------------------
2 | # Copyright 2021 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 | name: Build
17 |
18 | on:
19 | push:
20 | branches: ["main"]
21 | pull_request:
22 | branches: ["main"]
23 | workflow_dispatch: # Allows you to run this workflow manually from the Actions tab
24 | schedule:
25 | - cron: '30 8 * * 1' # At 08:30 on Monday, every Monday.
26 |
27 | jobs:
28 | Build:
29 | uses: netty-contrib/.github/.github/workflows/ci-build.yml@main
30 | secrets: inherit
31 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/NativeImageHandlerMetadataTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 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.contrib.handler.codec;
17 |
18 | import io.netty5.nativeimage.ChannelHandlerMetadataUtil;
19 | import org.junit.jupiter.api.Test;
20 |
21 | public class NativeImageHandlerMetadataTest {
22 |
23 | @Test
24 | public void collectAndCompareMetadata() {
25 | ChannelHandlerMetadataUtil.generateMetadata(
26 | "io.netty.contrib/netty-codec-socks/reflect-config.json",
27 | "io.netty.contrib.handler.codec");
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/handler-proxy/src/test/java/io/netty/contrib/handler/proxy/NativeImageHandlerMetadataTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 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.contrib.handler.proxy;
17 |
18 | import io.netty5.nativeimage.ChannelHandlerMetadataUtil;
19 | import org.junit.jupiter.api.Test;
20 |
21 | public class NativeImageHandlerMetadataTest {
22 |
23 | @Test
24 | public void collectAndCompareMetadata() {
25 | ChannelHandlerMetadataUtil.generateMetadata(
26 | "io.netty.contrib/netty-handler-proxy/reflect-config.json",
27 | "io.netty.contrib.handler.proxy");
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4CommandResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | /**
19 | * A SOCKS4a response.
20 | */
21 | public interface Socks4CommandResponse extends Socks4Message {
22 |
23 | /**
24 | * Returns the status of this response.
25 | */
26 | Socks4CommandStatus status();
27 |
28 | /**
29 | * Returns the {@code DSTIP} field of this response.
30 | */
31 | String dstAddr();
32 |
33 | /**
34 | * Returns the {@code DSTPORT} field of this response.
35 | */
36 | int dstPort();
37 | }
38 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/UnknownSocksRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | /**
21 | * An unknown socks request.
22 | *
23 | * @see SocksInitRequestDecoder
24 | * @see SocksAuthRequestDecoder
25 | * @see SocksCmdRequestDecoder
26 | */
27 | public final class UnknownSocksRequest extends SocksRequest {
28 |
29 | public UnknownSocksRequest() {
30 | super(SocksRequestType.UNKNOWN);
31 | }
32 |
33 | @Override
34 | public void encodeAsBuffer(Buffer buffer) {
35 | // NOOP
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/UnknownSocksResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | /**
21 | * An unknown socks response.
22 | *
23 | * @see SocksInitResponseDecoder
24 | * @see SocksAuthResponseDecoder
25 | * @see SocksCmdResponseDecoder
26 | */
27 | public final class UnknownSocksResponse extends SocksResponse {
28 |
29 | public UnknownSocksResponse() {
30 | super(SocksResponseType.UNKNOWN);
31 | }
32 |
33 | @Override
34 | public void encodeAsBuffer(Buffer buffer) {
35 | // NOOP
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | /**
19 | * A SOCKS5 subnegotiation request for username-password authentication, as defined in
20 | * the section 2, RFC1929 .
21 | */
22 | public interface Socks5PasswordAuthRequest extends Socks5Message {
23 |
24 | /**
25 | * Returns the username of this request.
26 | */
27 | String username();
28 |
29 | /**
30 | * Returns the password of this request.
31 | */
32 | String password();
33 | }
34 |
--------------------------------------------------------------------------------
/handler-proxy/src/main/resources/META-INF/native-image/io.netty.contrib/netty-handler-proxy/generated/handlers/reflect-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "io.netty.contrib.handler.proxy.HttpProxyHandler",
4 | "condition": {
5 | "typeReachable": "io.netty.contrib.handler.proxy.HttpProxyHandler"
6 | },
7 | "queryAllPublicMethods": true
8 | },
9 | {
10 | "name": "io.netty.contrib.handler.proxy.HttpProxyHandler$HttpClientCodecWrapper",
11 | "condition": {
12 | "typeReachable": "io.netty.contrib.handler.proxy.HttpProxyHandler$HttpClientCodecWrapper"
13 | },
14 | "queryAllPublicMethods": true
15 | },
16 | {
17 | "name": "io.netty.contrib.handler.proxy.ProxyHandler",
18 | "condition": {
19 | "typeReachable": "io.netty.contrib.handler.proxy.ProxyHandler"
20 | },
21 | "queryAllPublicMethods": true
22 | },
23 | {
24 | "name": "io.netty.contrib.handler.proxy.Socks4ProxyHandler",
25 | "condition": {
26 | "typeReachable": "io.netty.contrib.handler.proxy.Socks4ProxyHandler"
27 | },
28 | "queryAllPublicMethods": true
29 | },
30 | {
31 | "name": "io.netty.contrib.handler.proxy.Socks5ProxyHandler",
32 | "condition": {
33 | "typeReachable": "io.netty.contrib.handler.proxy.Socks5ProxyHandler"
34 | },
35 | "queryAllPublicMethods": true
36 | }
37 | ]
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksAuthStatus {
19 | SUCCESS((byte) 0x00),
20 | FAILURE((byte) 0xff);
21 |
22 | private final byte b;
23 |
24 | SocksAuthStatus(byte b) {
25 | this.b = b;
26 | }
27 |
28 | public static SocksAuthStatus valueOf(byte b) {
29 | for (SocksAuthStatus code : values()) {
30 | if (code.b == b) {
31 | return code;
32 | }
33 | }
34 | return FAILURE;
35 | }
36 |
37 | public byte byteValue() {
38 | return b;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/netty/contrib/handler/codec/example/socksproxy/SocksServerUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.example.socksproxy;
17 |
18 | import io.netty5.channel.Channel;
19 | import io.netty5.channel.ChannelFutureListeners;
20 |
21 | public final class SocksServerUtils {
22 |
23 | /**
24 | * Closes the specified channel after all queued write requests are flushed.
25 | */
26 | public static void closeOnFlush(Channel ch) {
27 | if (ch.isActive()) {
28 | ch.writeAndFlush(ch.bufferAllocator().allocate(0)).addListener(ch, ChannelFutureListeners.CLOSE);
29 | }
30 | }
31 |
32 | private SocksServerUtils() { }
33 | }
34 |
--------------------------------------------------------------------------------
/handler-proxy/src/main/java/io/netty/contrib/handler/proxy/ProxyConnectException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.proxy;
17 |
18 | import java.net.ConnectException;
19 |
20 | public class ProxyConnectException extends ConnectException {
21 | private static final long serialVersionUID = 5211364632246265538L;
22 |
23 | public ProxyConnectException() { }
24 |
25 | public ProxyConnectException(String msg) {
26 | super(msg);
27 | }
28 |
29 | public ProxyConnectException(Throwable cause) {
30 | initCause(cause);
31 | }
32 |
33 | public ProxyConnectException(String msg, Throwable cause) {
34 | super(msg);
35 | initCause(cause);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksCmdType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksCmdType {
19 | CONNECT((byte) 0x01),
20 | BIND((byte) 0x02),
21 | UDP((byte) 0x03),
22 | UNKNOWN((byte) 0xff);
23 |
24 | private final byte b;
25 |
26 | SocksCmdType(byte b) {
27 | this.b = b;
28 | }
29 |
30 | public static SocksCmdType valueOf(byte b) {
31 | for (SocksCmdType code : values()) {
32 | if (code.b == b) {
33 | return code;
34 | }
35 | }
36 | return UNKNOWN;
37 | }
38 |
39 | public byte byteValue() {
40 | return b;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/handler-proxy/src/test/java/io/netty/contrib/handler/proxy/UnresponsiveHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.proxy;
17 |
18 | import io.netty5.channel.ChannelHandlerContext;
19 | import io.netty5.channel.SimpleChannelInboundHandler;
20 |
21 | final class UnresponsiveHandler extends SimpleChannelInboundHandler {
22 |
23 | static final UnresponsiveHandler INSTANCE = new UnresponsiveHandler();
24 |
25 | private UnresponsiveHandler() { }
26 |
27 | @Override
28 | protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
29 | // Ignore
30 | }
31 |
32 | @Override
33 | public boolean isSharable() {
34 | return true;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksProtocolVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksProtocolVersion {
19 | SOCKS4a((byte) 0x04),
20 | SOCKS5((byte) 0x05),
21 | UNKNOWN((byte) 0xff);
22 |
23 | private final byte b;
24 |
25 | SocksProtocolVersion(byte b) {
26 | this.b = b;
27 | }
28 |
29 | public static SocksProtocolVersion valueOf(byte b) {
30 | for (SocksProtocolVersion code : values()) {
31 | if (code.b == b) {
32 | return code;
33 | }
34 | }
35 | return UNKNOWN;
36 | }
37 |
38 | public byte byteValue() {
39 | return b;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksSubnegotiationVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksSubnegotiationVersion {
19 | AUTH_PASSWORD((byte) 0x01),
20 | UNKNOWN((byte) 0xff);
21 |
22 | private final byte b;
23 |
24 | SocksSubnegotiationVersion(byte b) {
25 | this.b = b;
26 | }
27 |
28 | public static SocksSubnegotiationVersion valueOf(byte b) {
29 | for (SocksSubnegotiationVersion code : values()) {
30 | if (code.b == b) {
31 | return code;
32 | }
33 | }
34 | return UNKNOWN;
35 | }
36 |
37 | public byte byteValue() {
38 | return b;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAddressType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksAddressType {
19 | IPv4((byte) 0x01),
20 | DOMAIN((byte) 0x03),
21 | IPv6((byte) 0x04),
22 | UNKNOWN((byte) 0xff);
23 |
24 | private final byte b;
25 |
26 | SocksAddressType(byte b) {
27 | this.b = b;
28 | }
29 |
30 | public static SocksAddressType valueOf(byte b) {
31 | for (SocksAddressType code : values()) {
32 | if (code.b == b) {
33 | return code;
34 | }
35 | }
36 | return UNKNOWN;
37 | }
38 |
39 | public byte byteValue() {
40 | return b;
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksCommonTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.embedded.EmbeddedChannel;
20 |
21 | final class SocksCommonTestUtils {
22 | /**
23 | * A constructor to stop this class being constructed.
24 | */
25 | private SocksCommonTestUtils() {
26 | //NOOP
27 | }
28 |
29 | @SuppressWarnings("deprecation")
30 | public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, SocksMessage msg) {
31 | Buffer buf = embedder.bufferAllocator().allocate(64);
32 | msg.encodeAsBuffer(buf);
33 | embedder.writeInbound(buf);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthScheme.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksAuthScheme {
19 | NO_AUTH((byte) 0x00),
20 | AUTH_GSSAPI((byte) 0x01),
21 | AUTH_PASSWORD((byte) 0x02),
22 | UNKNOWN((byte) 0xff);
23 |
24 | private final byte b;
25 |
26 | SocksAuthScheme(byte b) {
27 | this.b = b;
28 | }
29 |
30 | public static SocksAuthScheme valueOf(byte b) {
31 | for (SocksAuthScheme code : values()) {
32 | if (code.b == b) {
33 | return code;
34 | }
35 | }
36 | return UNKNOWN;
37 | }
38 |
39 | public byte byteValue() {
40 | return b;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4CommandRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | /**
19 | * A SOCKS4a {@code CONNECT} or {@code BIND} request.
20 | */
21 | public interface Socks4CommandRequest extends Socks4Message {
22 |
23 | /**
24 | * Returns the type of this request.
25 | */
26 | Socks4CommandType type();
27 |
28 | /**
29 | * Returns the {@code USERID} field of this request.
30 | */
31 | String userId();
32 |
33 | /**
34 | * Returns the {@code DSTIP} field of this request.
35 | */
36 | String dstAddr();
37 |
38 | /**
39 | * Returns the {@code DSTPORT} field of this request.
40 | */
41 | int dstPort();
42 | }
43 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 |
2 | The Netty Project
3 | =================
4 |
5 | Please visit the Netty web site for more information:
6 |
7 | * https://netty.io/
8 |
9 | Copyright 2021 The Netty Project
10 |
11 | The Netty Project licenses this file to you under the Apache License,
12 | version 2.0 (the "License"); you may not use this file except in compliance
13 | with the License. You may obtain a copy of the License at:
14 |
15 | https://www.apache.org/licenses/LICENSE-2.0
16 |
17 | Unless required by applicable law or agreed to in writing, software
18 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
20 | License for the specific language governing permissions and limitations
21 | under the License.
22 |
23 | Also, please refer to each LICENSE..txt file, which is located in
24 | the 'license' directory of the distribution file, for the license terms of the
25 | components that this product depends on.
26 |
27 | -------------------------------------------------------------------------------
28 |
29 | This product contains the Maven wrapper scripts from 'Maven Wrapper', that provides an easy way to ensure a user has everything necessary to run the Maven build.
30 |
31 | * LICENSE:
32 | * license/LICENSE.mvn-wrapper.txt (Apache License 2.0)
33 | * HOMEPAGE:
34 | * https://github.com/takari/maven-wrapper
35 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/AbstractSocksMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 |
20 | import static java.util.Objects.requireNonNull;
21 |
22 | /**
23 | * An abstract {@link SocksMessage}.
24 | */
25 | public abstract class AbstractSocksMessage implements SocksMessage {
26 |
27 | private DecoderResult decoderResult = DecoderResult.success();
28 |
29 | @Override
30 | public DecoderResult decoderResult() {
31 | return decoderResult;
32 | }
33 |
34 | @Override
35 | public void setDecoderResult(DecoderResult decoderResult) {
36 | requireNonNull(decoderResult, "decoderResult");
37 | this.decoderResult = decoderResult;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/netty/contrib/handler/codec/example/socksproxy/SocksServerInitializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.example.socksproxy;
17 |
18 | import io.netty5.channel.ChannelInitializer;
19 | import io.netty5.channel.socket.SocketChannel;
20 | import io.netty.contrib.handler.codec.socksx.SocksPortUnificationServerHandler;
21 | import io.netty5.handler.logging.LogLevel;
22 | import io.netty5.handler.logging.LoggingHandler;
23 |
24 | public final class SocksServerInitializer extends ChannelInitializer {
25 | @Override
26 | public void initChannel(SocketChannel ch) throws Exception {
27 | ch.pipeline().addLast(
28 | new LoggingHandler(LogLevel.DEBUG),
29 | new SocksPortUnificationServerHandler(),
30 | SocksServerHandler.INSTANCE);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5CommandRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | /**
19 | * A SOCKS5 request detail message, as defined in
20 | * the section 4, RFC1928 .
21 | */
22 | public interface Socks5CommandRequest extends Socks5Message {
23 |
24 | /**
25 | * Returns the type of this request.
26 | */
27 | Socks5CommandType type();
28 |
29 | /**
30 | * Returns the type of the {@code DST.ADDR} field of this request.
31 | */
32 | Socks5AddressType dstAddrType();
33 |
34 | /**
35 | * Returns the {@code DST.ADDR} field of this request.
36 | */
37 | String dstAddr();
38 |
39 | /**
40 | * Returns the {@code DST.PORT} field of this request.
41 | */
42 | int dstPort();
43 | }
44 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5CommandResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | /**
19 | * A response to a SOCKS5 request detail message, as defined in
20 | * the section 6, RFC1928 .
21 | */
22 | public interface Socks5CommandResponse extends Socks5Message {
23 |
24 | /**
25 | * Returns the status of this response.
26 | */
27 | Socks5CommandStatus status();
28 |
29 | /**
30 | * Returns the address type of the {@code BND.ADDR} field of this response.
31 | */
32 | Socks5AddressType bndAddrType();
33 |
34 | /**
35 | * Returns the {@code BND.ADDR} field of this response.
36 | */
37 | String bndAddr();
38 |
39 | /**
40 | * Returns the {@code BND.PORT} field of this response.
41 | */
42 | int bndPort();
43 | }
44 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v4/Socks4CommonTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 |
20 | final class Socks4CommonTestUtils {
21 | /**
22 | * A constructor to stop this class being constructed.
23 | */
24 | private Socks4CommonTestUtils() {
25 | //NOOP
26 | }
27 |
28 | public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks4Message msg) {
29 | EmbeddedChannel out;
30 | if (msg instanceof Socks4CommandRequest) {
31 | out = new EmbeddedChannel(Socks4ClientEncoder.INSTANCE);
32 | } else {
33 | out = new EmbeddedChannel(Socks4ServerEncoder.INSTANCE);
34 | }
35 | out.writeOutbound(msg);
36 | embedder.writeInbound((Object) out.readOutbound());
37 | out.finish();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/netty/contrib/handler/codec/example/socksproxy/DirectClientHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.example.socksproxy;
17 |
18 | import io.netty5.channel.Channel;
19 | import io.netty5.channel.ChannelHandler;
20 | import io.netty5.channel.ChannelHandlerContext;
21 | import io.netty5.util.concurrent.Promise;
22 |
23 | public final class DirectClientHandler implements ChannelHandler {
24 |
25 | private final Promise promise;
26 |
27 | public DirectClientHandler(Promise promise) {
28 | this.promise = promise;
29 | }
30 |
31 | @Override
32 | public void channelActive(ChannelHandlerContext ctx) {
33 | ctx.pipeline().remove(this);
34 | promise.setSuccess(ctx.channel());
35 | }
36 |
37 | @Override
38 | public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable throwable) {
39 | promise.setFailure(throwable);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksCmdStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | public enum SocksCmdStatus {
19 | SUCCESS((byte) 0x00),
20 | FAILURE((byte) 0x01),
21 | FORBIDDEN((byte) 0x02),
22 | NETWORK_UNREACHABLE((byte) 0x03),
23 | HOST_UNREACHABLE((byte) 0x04),
24 | REFUSED((byte) 0x05),
25 | TTL_EXPIRED((byte) 0x06),
26 | COMMAND_NOT_SUPPORTED((byte) 0x07),
27 | ADDRESS_NOT_SUPPORTED((byte) 0x08),
28 | UNASSIGNED((byte) 0xff);
29 |
30 | private final byte b;
31 |
32 | SocksCmdStatus(byte b) {
33 | this.b = b;
34 | }
35 |
36 | public static SocksCmdStatus valueOf(byte b) {
37 | for (SocksCmdStatus code : values()) {
38 | if (code.b == b) {
39 | return code;
40 | }
41 | }
42 | return UNASSIGNED;
43 | }
44 |
45 | public byte byteValue() {
46 | return b;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * An abstract class that defines a SocksRequest, providing common properties for
22 | * {@link SocksInitRequest}, {@link SocksAuthRequest}, {@link SocksCmdRequest} and {@link UnknownSocksRequest}.
23 | *
24 | * @see SocksInitRequest
25 | * @see SocksAuthRequest
26 | * @see SocksCmdRequest
27 | * @see UnknownSocksRequest
28 | */
29 | public abstract class SocksRequest extends SocksMessage {
30 | private final SocksRequestType requestType;
31 |
32 | protected SocksRequest(SocksRequestType requestType) {
33 | super(SocksMessageType.REQUEST);
34 | requireNonNull(requestType, "requestType");
35 | this.requestType = requestType;
36 | }
37 |
38 | /**
39 | * Returns socks request type
40 | *
41 | * @return socks request type
42 | */
43 | public SocksRequestType requestType() {
44 | return requestType;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static org.junit.jupiter.api.Assertions.assertEquals;
22 | import static org.junit.jupiter.api.Assertions.assertNull;
23 |
24 | public class Socks5PasswordAuthRequestDecoderTest {
25 |
26 | @Test
27 | public void testAuthRequestDecoder() {
28 | String username = "testUsername";
29 | String password = "testPassword";
30 | Socks5PasswordAuthRequest msg = new DefaultSocks5PasswordAuthRequest(username, password);
31 | EmbeddedChannel embedder = new EmbeddedChannel(new Socks5PasswordAuthRequestDecoder());
32 | Socks5CommonTestUtils.writeFromClientToServer(embedder, msg);
33 | msg = embedder.readInbound();
34 | assertEquals(username, msg.username());
35 | assertEquals(password, msg.password());
36 | assertNull(embedder.readInbound());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * An abstract class that defines a SocksResponse, providing common properties for
22 | * {@link SocksInitResponse}, {@link SocksAuthResponse}, {@link SocksCmdResponse} and {@link UnknownSocksResponse}.
23 | *
24 | * @see SocksInitResponse
25 | * @see SocksAuthResponse
26 | * @see SocksCmdResponse
27 | * @see UnknownSocksResponse
28 | */
29 | public abstract class SocksResponse extends SocksMessage {
30 | private final SocksResponseType responseType;
31 |
32 | protected SocksResponse(SocksResponseType responseType) {
33 | super(SocksMessageType.RESPONSE);
34 | requireNonNull(responseType, "responseType");
35 | this.responseType = responseType;
36 | }
37 |
38 | /**
39 | * Returns socks response type
40 | *
41 | * @return socks response type
42 | */
43 | public SocksResponseType responseType() {
44 | return responseType;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksMessageEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.MessageToByteEncoder;
21 |
22 | /**
23 | * Encodes an {@link SocksMessage} into a {@link Buffer}.
24 | * {@link MessageToByteEncoder} implementation.
25 | * Use this with {@link SocksInitRequest}, {@link SocksInitResponse}, {@link SocksAuthRequest},
26 | * {@link SocksAuthResponse}, {@link SocksCmdRequest} and {@link SocksCmdResponse}
27 | */
28 | public class SocksMessageEncoder extends MessageToByteEncoder {
29 |
30 | @Override
31 | protected Buffer allocateBuffer(ChannelHandlerContext ctx, SocksMessage msg) {
32 | return ctx.bufferAllocator().allocate(256);
33 | }
34 |
35 | @Override
36 | @SuppressWarnings("deprecation")
37 | protected void encode(ChannelHandlerContext ctx, SocksMessage msg, Buffer out) {
38 | msg.encodeAsBuffer(out);
39 | }
40 |
41 | @Override
42 | public boolean isSharable() {
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksInitResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | import static java.util.Objects.requireNonNull;
21 |
22 | /**
23 | * An socks init response.
24 | *
25 | * @see SocksInitRequest
26 | * @see SocksInitResponseDecoder
27 | */
28 | public final class SocksInitResponse extends SocksResponse {
29 | private final SocksAuthScheme authScheme;
30 |
31 | public SocksInitResponse(SocksAuthScheme authScheme) {
32 | super(SocksResponseType.INIT);
33 | requireNonNull(authScheme, "authScheme");
34 | this.authScheme = authScheme;
35 | }
36 |
37 | /**
38 | * Returns the {@link SocksAuthScheme} of this {@link SocksInitResponse}
39 | *
40 | * @return The {@link SocksAuthScheme} of this {@link SocksInitResponse}
41 | */
42 | public SocksAuthScheme authScheme() {
43 | return authScheme;
44 | }
45 |
46 | @Override
47 | public void encodeAsBuffer(Buffer buffer) {
48 | buffer.writeByte(protocolVersion().byteValue());
49 | buffer.writeByte(authScheme.byteValue());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/Socks5InitialRequestDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import io.netty5.handler.codec.DecoderResult;
20 | import org.junit.jupiter.api.Test;
21 |
22 | import static org.junit.jupiter.api.Assertions.assertFalse;
23 | import static org.junit.jupiter.api.Assertions.assertSame;
24 | import static org.junit.jupiter.api.Assertions.assertTrue;
25 |
26 | public class Socks5InitialRequestDecoderTest {
27 | @Test
28 | public void testUnpackingCausesDecodeFail() {
29 | EmbeddedChannel e = new EmbeddedChannel(new Socks5InitialRequestDecoder());
30 | assertFalse(e.writeInbound(e.bufferAllocator().copyOf(new byte[]{5, 2, 0})));
31 | assertTrue(e.writeInbound(e.bufferAllocator().copyOf(new byte[]{1})));
32 | Object o = e.readInbound();
33 |
34 | assertTrue(o instanceof DefaultSocks5InitialRequest);
35 | DefaultSocks5InitialRequest req = (DefaultSocks5InitialRequest) o;
36 | assertSame(req.decoderResult(), DecoderResult.success());
37 | assertFalse(e.finish());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | import static java.util.Objects.requireNonNull;
21 |
22 | /**
23 | * An socks auth response.
24 | *
25 | * @see SocksAuthRequest
26 | * @see SocksAuthResponseDecoder
27 | */
28 | public final class SocksAuthResponse extends SocksResponse {
29 | private static final SocksSubnegotiationVersion SUBNEGOTIATION_VERSION = SocksSubnegotiationVersion.AUTH_PASSWORD;
30 | private final SocksAuthStatus authStatus;
31 |
32 | public SocksAuthResponse(SocksAuthStatus authStatus) {
33 | super(SocksResponseType.AUTH);
34 | requireNonNull(authStatus, "authStatus");
35 | this.authStatus = authStatus;
36 | }
37 |
38 | /**
39 | * Returns the {@link SocksAuthStatus} of this {@link SocksAuthResponse}
40 | *
41 | * @return The {@link SocksAuthStatus} of this {@link SocksAuthResponse}
42 | */
43 | public SocksAuthStatus authStatus() {
44 | return authStatus;
45 | }
46 |
47 | @Override
48 | public void encodeAsBuffer(Buffer buffer) {
49 | buffer.writeByte(SUBNEGOTIATION_VERSION.byteValue());
50 | buffer.writeByte(authStatus.byteValue());
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/SocksVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx;
17 |
18 | /**
19 | * The version of SOCKS protocol.
20 | */
21 | public enum SocksVersion {
22 | /**
23 | * SOCKS protocol version 4a (or 4)
24 | */
25 | SOCKS4a((byte) 0x04),
26 | /**
27 | * SOCKS protocol version 5
28 | */
29 | SOCKS5((byte) 0x05),
30 | /**
31 | * Unknown protocol version
32 | */
33 | UNKNOWN((byte) 0xff);
34 |
35 | /**
36 | * Returns the {@link SocksVersion} that corresponds to the specified version field value,
37 | * as defined in the protocol specification.
38 | *
39 | * @return {@link #UNKNOWN} if the specified value does not represent a known SOCKS protocol version
40 | */
41 | public static SocksVersion valueOf(byte b) {
42 | if (b == SOCKS4a.byteValue()) {
43 | return SOCKS4a;
44 | }
45 | if (b == SOCKS5.byteValue()) {
46 | return SOCKS5;
47 | }
48 | return UNKNOWN;
49 | }
50 |
51 | private final byte b;
52 |
53 | SocksVersion(byte b) {
54 | this.b = b;
55 | }
56 |
57 | /**
58 | * Returns the value of the version field, as defined in the protocol specification.
59 | */
60 | public byte byteValue() {
61 | return b;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/Socks5CommonTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.embedded.EmbeddedChannel;
20 |
21 | final class Socks5CommonTestUtils {
22 | /**
23 | * A constructor to stop this class being constructed.
24 | */
25 | private Socks5CommonTestUtils() {
26 | //NOOP
27 | }
28 |
29 | public static void writeFromClientToServer(EmbeddedChannel embedder, Socks5Message msg) {
30 | embedder.writeInbound(encodeClient(msg));
31 | }
32 |
33 | public static void writeFromServerToClient(EmbeddedChannel embedder, Socks5Message msg) {
34 | embedder.writeInbound(encodeServer(msg));
35 | }
36 |
37 | public static Buffer encodeClient(Socks5Message msg) {
38 | EmbeddedChannel out = new EmbeddedChannel(Socks5ClientEncoder.DEFAULT);
39 | out.writeOutbound(msg);
40 |
41 | Buffer encoded = out.readOutbound();
42 | out.finish();
43 |
44 | return encoded;
45 | }
46 |
47 | public static Buffer encodeServer(Socks5Message msg) {
48 | EmbeddedChannel out = new EmbeddedChannel(Socks5ServerEncoder.DEFAULT);
49 | out.writeOutbound(msg);
50 |
51 | Buffer encoded = out.readOutbound();
52 | out.finish();
53 |
54 | return encoded;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.junit.jupiter.api.Test;
22 |
23 | import static org.junit.jupiter.api.Assertions.assertNull;
24 | import static org.junit.jupiter.api.Assertions.assertSame;
25 |
26 | public class Socks5PasswordAuthResponseDecoderTest {
27 | private static final Logger logger = LoggerFactory.getLogger(
28 | Socks5PasswordAuthResponseDecoderTest.class);
29 |
30 | private static void test(Socks5PasswordAuthStatus status) {
31 | logger.debug("Testing Socks5PasswordAuthResponseDecoder with status: " + status);
32 | Socks5PasswordAuthResponse msg = new DefaultSocks5PasswordAuthResponse(status);
33 | EmbeddedChannel embedder = new EmbeddedChannel(new Socks5PasswordAuthResponseDecoder());
34 | Socks5CommonTestUtils.writeFromServerToClient(embedder, msg);
35 | msg = embedder.readInbound();
36 | assertSame(msg.status(), status);
37 | assertNull(embedder.readInbound());
38 | }
39 |
40 | @Test
41 | public void testSocksCmdResponseDecoder() {
42 | test(Socks5PasswordAuthStatus.SUCCESS);
43 | test(Socks5PasswordAuthStatus.FAILURE);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/netty/contrib/handler/codec/example/socksproxy/RelayHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.example.socksproxy;
17 |
18 | import io.netty5.channel.Channel;
19 | import io.netty5.channel.ChannelHandler;
20 | import io.netty5.channel.ChannelHandlerContext;
21 | import io.netty5.util.ReferenceCountUtil;
22 |
23 | public final class RelayHandler implements ChannelHandler {
24 |
25 | private final Channel relayChannel;
26 |
27 | public RelayHandler(Channel relayChannel) {
28 | this.relayChannel = relayChannel;
29 | }
30 |
31 | @Override
32 | public void channelActive(ChannelHandlerContext ctx) {
33 | ctx.writeAndFlush(ctx.bufferAllocator().allocate(0));
34 | }
35 |
36 | @Override
37 | public void channelRead(ChannelHandlerContext ctx, Object msg) {
38 | if (relayChannel.isActive()) {
39 | relayChannel.writeAndFlush(msg);
40 | } else {
41 | ReferenceCountUtil.release(msg);
42 | }
43 | }
44 |
45 | @Override
46 | public void channelInactive(ChannelHandlerContext ctx) {
47 | if (relayChannel.isActive()) {
48 | SocksServerUtils.closeOnFlush(relayChannel);
49 | }
50 | }
51 |
52 | @Override
53 | public void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
54 | cause.printStackTrace();
55 | ctx.close();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/examples/src/main/java/io/netty/contrib/handler/codec/example/socksproxy/SocksServer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.example.socksproxy;
17 |
18 | import io.netty5.bootstrap.ServerBootstrap;
19 | import io.netty5.channel.EventLoopGroup;
20 | import io.netty5.channel.MultithreadEventLoopGroup;
21 | import io.netty5.channel.nio.NioHandler;
22 | import io.netty5.channel.socket.nio.NioServerSocketChannel;
23 | import io.netty5.handler.logging.LogLevel;
24 | import io.netty5.handler.logging.LoggingHandler;
25 |
26 | public final class SocksServer {
27 |
28 | static final int PORT = Integer.parseInt(System.getProperty("port", "1080"));
29 |
30 | public static void main(String[] args) throws Exception {
31 | EventLoopGroup bossGroup = new MultithreadEventLoopGroup(1, NioHandler.newFactory());
32 | EventLoopGroup workerGroup = new MultithreadEventLoopGroup(NioHandler.newFactory());
33 | try {
34 | ServerBootstrap b = new ServerBootstrap();
35 | b.group(bossGroup, workerGroup)
36 | .channel(NioServerSocketChannel.class)
37 | .handler(new LoggingHandler(LogLevel.INFO))
38 | .childHandler(new SocksServerInitializer());
39 | b.bind(PORT).asStage().get().closeFuture().asStage().sync();
40 | } finally {
41 | bossGroup.shutdownGracefully();
42 | workerGroup.shutdownGracefully();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5InitialResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.internal.StringUtil;
20 |
21 | import static java.util.Objects.requireNonNull;
22 |
23 | /**
24 | * The default {@link Socks5InitialResponse}.
25 | */
26 | public class DefaultSocks5InitialResponse extends AbstractSocks5Message implements Socks5InitialResponse {
27 |
28 | private final Socks5AuthMethod authMethod;
29 |
30 | public DefaultSocks5InitialResponse(Socks5AuthMethod authMethod) {
31 | requireNonNull(authMethod, "authMethod");
32 | this.authMethod = authMethod;
33 | }
34 |
35 | @Override
36 | public Socks5AuthMethod authMethod() {
37 | return authMethod;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | StringBuilder buf = new StringBuilder(StringUtil.simpleClassName(this));
43 |
44 | DecoderResult decoderResult = decoderResult();
45 | if (!decoderResult.isSuccess()) {
46 | buf.append("(decoderResult: ");
47 | buf.append(decoderResult);
48 | buf.append(", authMethod: ");
49 | } else {
50 | buf.append("(authMethod: ");
51 | }
52 | buf.append(authMethod());
53 | buf.append(')');
54 |
55 | return buf.toString();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5PasswordAuthResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.internal.StringUtil;
20 |
21 | import static java.util.Objects.requireNonNull;
22 |
23 | /**
24 | * The default {@link Socks5PasswordAuthResponse}.
25 | */
26 | public class DefaultSocks5PasswordAuthResponse extends AbstractSocks5Message implements Socks5PasswordAuthResponse {
27 |
28 | private final Socks5PasswordAuthStatus status;
29 |
30 | public DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus status) {
31 | requireNonNull(status, "status");
32 |
33 | this.status = status;
34 | }
35 |
36 | @Override
37 | public Socks5PasswordAuthStatus status() {
38 | return status;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | StringBuilder buf = new StringBuilder(StringUtil.simpleClassName(this));
44 |
45 | DecoderResult decoderResult = decoderResult();
46 | if (!decoderResult.isSuccess()) {
47 | buf.append("(decoderResult: ");
48 | buf.append(decoderResult);
49 | buf.append(", status: ");
50 | } else {
51 | buf.append("(status: ");
52 | }
53 | buf.append(status());
54 | buf.append(')');
55 |
56 | return buf.toString();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksInitRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | import java.util.Collections;
21 | import java.util.List;
22 |
23 | import static java.util.Objects.requireNonNull;
24 |
25 | /**
26 | * An socks init request.
27 | *
28 | * @see SocksInitResponse
29 | * @see SocksInitRequestDecoder
30 | */
31 | public final class SocksInitRequest extends SocksRequest {
32 | private final List authSchemes;
33 |
34 | public SocksInitRequest(List authSchemes) {
35 | super(SocksRequestType.INIT);
36 | requireNonNull(authSchemes, "authSchemes");
37 | this.authSchemes = authSchemes;
38 | }
39 |
40 | /**
41 | * Returns the List<{@link SocksAuthScheme}> of this {@link SocksInitRequest}
42 | *
43 | * @return The List<{@link SocksAuthScheme}> of this {@link SocksInitRequest}
44 | */
45 | public List authSchemes() {
46 | return Collections.unmodifiableList(authSchemes);
47 | }
48 |
49 | @Override
50 | public void encodeAsBuffer(Buffer buffer) {
51 | buffer.writeByte(protocolVersion().byteValue());
52 | buffer.writeByte((byte) authSchemes.size());
53 | for (SocksAuthScheme authScheme : authSchemes) {
54 | buffer.writeByte(authScheme.byteValue());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksCommonUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.util.internal.StringUtil;
19 |
20 | final class SocksCommonUtils {
21 | public static final SocksRequest UNKNOWN_SOCKS_REQUEST = new UnknownSocksRequest();
22 | public static final SocksResponse UNKNOWN_SOCKS_RESPONSE = new UnknownSocksResponse();
23 |
24 | /**
25 | * A constructor to stop this class being constructed.
26 | */
27 | private SocksCommonUtils() {
28 | // NOOP
29 | }
30 |
31 | private static final char ipv6hextetSeparator = ':';
32 |
33 | /**
34 | * Converts numeric IPv6 to standard (non-compressed) format.
35 | */
36 | public static String ipv6toStr(byte[] src) {
37 | assert src.length == 16;
38 | StringBuilder sb = new StringBuilder(39);
39 | ipv6toStr(sb, src, 0, 8);
40 | return sb.toString();
41 | }
42 |
43 | private static void ipv6toStr(StringBuilder sb, byte[] src, int fromHextet, int toHextet) {
44 | int i;
45 | toHextet --;
46 | for (i = fromHextet; i < toHextet; i++) {
47 | appendHextet(sb, src, i);
48 | sb.append(ipv6hextetSeparator);
49 | }
50 |
51 | appendHextet(sb, src, i);
52 | }
53 |
54 | private static void appendHextet(StringBuilder sb, byte[] src, int i) {
55 | StringUtil.toHexString(sb, src, i << 1, 2);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4ServerEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.MessageToByteEncoder;
21 | import io.netty5.util.NetUtil;
22 |
23 | /**
24 | * Encodes a {@link Socks4CommandResponse} into a {@link Buffer}.
25 | */
26 | public final class Socks4ServerEncoder extends MessageToByteEncoder {
27 |
28 | public static final Socks4ServerEncoder INSTANCE = new Socks4ServerEncoder();
29 |
30 | private static final byte[] IPv4_HOSTNAME_ZEROED = { 0x00, 0x00, 0x00, 0x00 };
31 |
32 | private Socks4ServerEncoder() { }
33 |
34 | @Override
35 | protected Buffer allocateBuffer(ChannelHandlerContext ctx, Socks4CommandResponse msg) {
36 | return ctx.bufferAllocator().allocate(256);
37 | }
38 |
39 | @Override
40 | protected void encode(ChannelHandlerContext ctx, Socks4CommandResponse msg, Buffer out) {
41 | out.writeByte((byte) 0);
42 | out.writeByte(msg.status().byteValue());
43 | out.writeShort((short) msg.dstPort());
44 | out.writeBytes(msg.dstAddr() == null? IPv4_HOSTNAME_ZEROED
45 | : NetUtil.createByteArrayFromIpAddressString(msg.dstAddr()));
46 | }
47 |
48 | @Override
49 | public boolean isSharable() {
50 | return true;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksAuthResponseDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.junit.jupiter.api.Test;
22 |
23 | import static org.junit.jupiter.api.Assertions.assertNull;
24 | import static org.junit.jupiter.api.Assertions.assertSame;
25 |
26 | public class SocksAuthResponseDecoderTest {
27 | private static final Logger logger = LoggerFactory.getLogger(SocksAuthResponseDecoderTest.class);
28 |
29 | private static void testSocksAuthResponseDecoderWithDifferentParams(SocksAuthStatus authStatus) {
30 | logger.debug("Testing SocksAuthResponseDecoder with authStatus: " + authStatus);
31 | SocksAuthResponse msg = new SocksAuthResponse(authStatus);
32 | SocksAuthResponseDecoder decoder = new SocksAuthResponseDecoder();
33 | EmbeddedChannel embedder = new EmbeddedChannel(decoder);
34 | SocksCommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
35 | msg = embedder.readInbound();
36 | assertSame(msg.authStatus(), authStatus);
37 | assertNull(embedder.readInbound());
38 | }
39 |
40 | @Test
41 | public void testSocksCmdResponseDecoder() {
42 | for (SocksAuthStatus authStatus: SocksAuthStatus.values()) {
43 | testSocksAuthResponseDecoderWithDifferentParams(authStatus);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 |
20 | import static java.util.Objects.requireNonNull;
21 |
22 | /**
23 | * An abstract class that defines a SocksMessage, providing common properties for
24 | * {@link SocksRequest} and {@link SocksResponse}.
25 | *
26 | * @see SocksRequest
27 | * @see SocksResponse
28 | */
29 | public abstract class SocksMessage {
30 | private final SocksMessageType type;
31 | private final SocksProtocolVersion protocolVersion = SocksProtocolVersion.SOCKS5;
32 |
33 | protected SocksMessage(SocksMessageType type) {
34 | requireNonNull(type, "type");
35 | this.type = type;
36 | }
37 |
38 | /**
39 | * Returns the {@link SocksMessageType} of this {@link SocksMessage}
40 | *
41 | * @return The {@link SocksMessageType} of this {@link SocksMessage}
42 | */
43 | public SocksMessageType type() {
44 | return type;
45 | }
46 |
47 | /**
48 | * Returns the {@link SocksProtocolVersion} of this {@link SocksMessage}
49 | *
50 | * @return The {@link SocksProtocolVersion} of this {@link SocksMessage}
51 | */
52 | public SocksProtocolVersion protocolVersion() {
53 | return protocolVersion;
54 | }
55 |
56 | /**
57 | * @deprecated Do not use; this method was intended for an internal use only.
58 | */
59 | @Deprecated
60 | public abstract void encodeAsBuffer(Buffer buffer);
61 | }
62 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v4/Socks4ClientDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import org.junit.jupiter.api.Test;
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 |
23 | import static org.junit.jupiter.api.Assertions.assertEquals;
24 | import static org.junit.jupiter.api.Assertions.assertNull;
25 |
26 | public class Socks4ClientDecoderTest {
27 | private static final Logger logger = LoggerFactory.getLogger(Socks4ClientDecoderTest.class);
28 |
29 | private static void test(Socks4CommandStatus cmdStatus, String dstAddr, int dstPort) {
30 | logger.debug("Testing cmdStatus: " + cmdStatus);
31 | Socks4CommandResponse msg = new DefaultSocks4CommandResponse(cmdStatus, dstAddr, dstPort);
32 | EmbeddedChannel embedder = new EmbeddedChannel(new Socks4ClientDecoder());
33 | Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
34 |
35 | msg = embedder.readInbound();
36 | assertEquals(msg.status(), cmdStatus);
37 | if (dstAddr != null) {
38 | assertEquals(msg.dstAddr(), dstAddr);
39 | }
40 | assertEquals(msg.dstPort(), dstPort);
41 | assertNull(embedder.readInbound());
42 | }
43 |
44 | /**
45 | * Verifies that sent socks messages are decoded correctly.
46 | */
47 | @Test
48 | public void testSocksCmdResponseDecoder() {
49 | test(Socks4CommandStatus.IDENTD_AUTH_FAILURE, null, 0);
50 | test(Socks4CommandStatus.IDENTD_UNREACHABLE, null, 0);
51 | test(Socks4CommandStatus.REJECTED_OR_FAILED, null, 0);
52 | test(Socks4CommandStatus.SUCCESS, null, 0);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksInitResponseDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 |
22 | /**
23 | * Decodes {@link Buffer}s into {@link SocksInitResponse}.
24 | * Before returning SocksResponse decoder removes itself from pipeline.
25 | */
26 | public class SocksInitResponseDecoder extends ByteToMessageDecoder {
27 |
28 | private enum State {
29 | CHECK_PROTOCOL_VERSION,
30 | READ_PREFERRED_AUTH_TYPE
31 | }
32 | private State state = State.CHECK_PROTOCOL_VERSION;
33 |
34 | @Override
35 | protected void decode(ChannelHandlerContext ctx, Buffer buffer) throws Exception {
36 | switch (state) {
37 | case CHECK_PROTOCOL_VERSION: {
38 | if (buffer.readableBytes() < 1) {
39 | return;
40 | }
41 | if (buffer.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) {
42 | ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE);
43 | break;
44 | }
45 | state = State.READ_PREFERRED_AUTH_TYPE;
46 | }
47 | case READ_PREFERRED_AUTH_TYPE: {
48 | if (buffer.readableBytes() < 1) {
49 | return;
50 | }
51 | SocksAuthScheme authScheme = SocksAuthScheme.valueOf(buffer.readByte());
52 | ctx.fireChannelRead(new SocksInitResponse(authScheme));
53 | break;
54 | }
55 | default: {
56 | throw new Error();
57 | }
58 | }
59 | ctx.pipeline().remove(this);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthResponseDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 |
22 | /**
23 | * Decodes {@link Buffer}s into {@link SocksAuthResponse}.
24 | * Before returning SocksResponse decoder removes itself from pipeline.
25 | */
26 | public class SocksAuthResponseDecoder extends ByteToMessageDecoder {
27 |
28 | private enum State {
29 | CHECK_PROTOCOL_VERSION,
30 | READ_AUTH_RESPONSE
31 | }
32 |
33 | private State state = State.CHECK_PROTOCOL_VERSION;
34 |
35 | @Override
36 | protected void decode(ChannelHandlerContext ctx, Buffer buffer)
37 | throws Exception {
38 | switch (state) {
39 | case CHECK_PROTOCOL_VERSION: {
40 | if (buffer.readableBytes() < 1) {
41 | return;
42 | }
43 | if (buffer.readByte() != SocksSubnegotiationVersion.AUTH_PASSWORD.byteValue()) {
44 | ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_RESPONSE);
45 | break;
46 | }
47 | state = State.READ_AUTH_RESPONSE;
48 | }
49 | case READ_AUTH_RESPONSE: {
50 | if (buffer.readableBytes() < 1) {
51 | return;
52 | }
53 | SocksAuthStatus authStatus = SocksAuthStatus.valueOf(buffer.readByte());
54 | ctx.fireChannelRead(new SocksAuthResponse(authStatus));
55 | break;
56 | }
57 | default: {
58 | throw new Error();
59 | }
60 | }
61 | ctx.pipeline().remove(this);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4CommandType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The type of {@link Socks4CommandRequest}.
22 | */
23 | public class Socks4CommandType implements Comparable {
24 |
25 | public static final Socks4CommandType CONNECT = new Socks4CommandType(0x01, "CONNECT");
26 | public static final Socks4CommandType BIND = new Socks4CommandType(0x02, "BIND");
27 |
28 | public static Socks4CommandType valueOf(byte b) {
29 | switch (b) {
30 | case 0x01:
31 | return CONNECT;
32 | case 0x02:
33 | return BIND;
34 | }
35 |
36 | return new Socks4CommandType(b);
37 | }
38 |
39 | private final byte byteValue;
40 | private final String name;
41 | private String text;
42 |
43 | public Socks4CommandType(int byteValue) {
44 | this(byteValue, "UNKNOWN");
45 | }
46 |
47 | public Socks4CommandType(int byteValue, String name) {
48 | requireNonNull(name, "name");
49 | this.byteValue = (byte) byteValue;
50 | this.name = name;
51 | }
52 |
53 | public byte byteValue() {
54 | return byteValue;
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 | return byteValue;
60 | }
61 |
62 | @Override
63 | public boolean equals(Object obj) {
64 | if (!(obj instanceof Socks4CommandType)) {
65 | return false;
66 | }
67 |
68 | return byteValue == ((Socks4CommandType) obj).byteValue;
69 | }
70 |
71 | @Override
72 | public int compareTo(Socks4CommandType o) {
73 | return byteValue - o.byteValue;
74 | }
75 |
76 | @Override
77 | public String toString() {
78 | String text = this.text;
79 | if (text == null) {
80 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
81 | }
82 | return text;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4ClientEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.MessageToByteEncoder;
21 | import java.nio.charset.StandardCharsets;
22 | import io.netty5.util.NetUtil;
23 |
24 | /**
25 | * Encodes a {@link Socks4CommandRequest} into a {@link Buffer}.
26 | */
27 | public final class Socks4ClientEncoder extends MessageToByteEncoder {
28 |
29 | /**
30 | * The singleton instance of {@link Socks4ClientEncoder}
31 | */
32 | public static final Socks4ClientEncoder INSTANCE = new Socks4ClientEncoder();
33 |
34 | private static final byte[] IPv4_DOMAIN_MARKER = {0x00, 0x00, 0x00, 0x01};
35 |
36 | private Socks4ClientEncoder() { }
37 |
38 | @Override
39 | protected Buffer allocateBuffer(ChannelHandlerContext ctx, Socks4CommandRequest msg) {
40 | return ctx.bufferAllocator().allocate(256);
41 | }
42 |
43 | @Override
44 | protected void encode(ChannelHandlerContext ctx, Socks4CommandRequest msg, Buffer out) {
45 | out.writeByte(msg.version().byteValue());
46 | out.writeByte(msg.type().byteValue());
47 | out.writeShort((short) msg.dstPort());
48 | if (NetUtil.isValidIpV4Address(msg.dstAddr())) {
49 | out.writeBytes(NetUtil.createByteArrayFromIpAddressString(msg.dstAddr()));
50 | out.writeCharSequence(msg.userId(), StandardCharsets.US_ASCII);
51 | out.writeByte((byte) 0);
52 | } else {
53 | out.writeBytes(IPv4_DOMAIN_MARKER);
54 | out.writeCharSequence(msg.userId(), StandardCharsets.US_ASCII);
55 | out.writeByte((byte) 0);
56 | out.writeCharSequence(msg.dstAddr(), StandardCharsets.US_ASCII);
57 | out.writeByte((byte) 0);
58 | }
59 | }
60 |
61 | @Override
62 | public boolean isSharable() {
63 | return true;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5AddressEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.handler.codec.EncoderException;
20 | import java.nio.charset.StandardCharsets;
21 | import io.netty5.util.NetUtil;
22 |
23 | /**
24 | * Encodes a SOCKS5 address into binary representation.
25 | *
26 | * @see Socks5ClientEncoder
27 | * @see Socks5ServerEncoder
28 | */
29 | public interface Socks5AddressEncoder {
30 |
31 | Socks5AddressEncoder DEFAULT = (addrType, addrValue, out) -> {
32 | final byte typeVal = addrType.byteValue();
33 | if (typeVal == Socks5AddressType.IPv4.byteValue()) {
34 | if (addrValue != null) {
35 | out.writeBytes(NetUtil.createByteArrayFromIpAddressString(addrValue));
36 | } else {
37 | out.writeInt(0);
38 | }
39 | } else if (typeVal == Socks5AddressType.DOMAIN.byteValue()) {
40 | if (addrValue != null) {
41 | out.writeByte((byte) addrValue.length());
42 | out.writeCharSequence(addrValue, StandardCharsets.US_ASCII);
43 | } else {
44 | out.writeByte((byte) 0);
45 | }
46 | } else if (typeVal == Socks5AddressType.IPv6.byteValue()) {
47 | if (addrValue != null) {
48 | out.writeBytes(NetUtil.createByteArrayFromIpAddressString(addrValue));
49 | } else {
50 | out.writeLong(0);
51 | out.writeLong(0);
52 | }
53 | } else {
54 | throw new EncoderException("unsupported addrType: " + (addrType.byteValue() & 0xFF));
55 | }
56 | };
57 |
58 | /**
59 | * Encodes a SOCKS5 address.
60 | *
61 | * @param addrType the type of the address
62 | * @param addrValue the string representation of the address
63 | * @param out the output buffer where the encoded SOCKS5 address field will be written to
64 | */
65 | void encodeAddress(Socks5AddressType addrType, String addrValue, Buffer out) throws Exception;
66 | }
67 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v4/Socks4ServerDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.channel.embedded.EmbeddedChannel;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 | import org.junit.jupiter.api.Test;
22 |
23 | import java.util.Arrays;
24 |
25 | import static org.junit.jupiter.api.Assertions.assertEquals;
26 | import static org.junit.jupiter.api.Assertions.assertNull;
27 | import static org.junit.jupiter.api.Assertions.assertSame;
28 |
29 | public class Socks4ServerDecoderTest {
30 | private static final Logger logger = LoggerFactory.getLogger(Socks4ServerDecoderTest.class);
31 |
32 | private static void test(String userId, Socks4CommandType type, String dstAddr, int dstPort) {
33 | logger.debug(
34 | "Testing type: " + type + " dstAddr: " + dstAddr + " dstPort: " + dstPort +
35 | " userId: " + userId);
36 |
37 | Socks4CommandRequest msg = new DefaultSocks4CommandRequest(type, dstAddr, dstPort, userId);
38 | EmbeddedChannel embedder = new EmbeddedChannel(new Socks4ServerDecoder());
39 | Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
40 | msg = embedder.readInbound();
41 | assertSame(msg.type(), type);
42 | assertEquals(msg.dstAddr(), dstAddr);
43 | assertEquals(msg.dstPort(), dstPort);
44 | assertEquals(msg.userId(), userId);
45 | assertNull(embedder.readInbound());
46 | }
47 |
48 | @Test
49 | public void testCmdRequestDecoder() {
50 | String[] hosts = { "127.0.0.1", };
51 | String[] userIds = { "test", };
52 | int[] ports = {1, 32769, 65535};
53 |
54 | for (Socks4CommandType cmdType : Arrays.asList(Socks4CommandType.BIND,
55 | Socks4CommandType.CONNECT)) {
56 | for (String userId : userIds) {
57 | for (String host : hosts) {
58 | for (int port : ports) {
59 | test(userId, cmdType, host, port);
60 | }
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5CommandType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The type of {@link Socks5CommandRequest}.
22 | */
23 | public class Socks5CommandType implements Comparable {
24 |
25 | public static final Socks5CommandType CONNECT = new Socks5CommandType(0x01, "CONNECT");
26 | public static final Socks5CommandType BIND = new Socks5CommandType(0x02, "BIND");
27 | public static final Socks5CommandType UDP_ASSOCIATE = new Socks5CommandType(0x03, "UDP_ASSOCIATE");
28 |
29 | public static Socks5CommandType valueOf(byte b) {
30 | switch (b) {
31 | case 0x01:
32 | return CONNECT;
33 | case 0x02:
34 | return BIND;
35 | case 0x03:
36 | return UDP_ASSOCIATE;
37 | }
38 |
39 | return new Socks5CommandType(b);
40 | }
41 |
42 | private final byte byteValue;
43 | private final String name;
44 | private String text;
45 |
46 | public Socks5CommandType(int byteValue) {
47 | this(byteValue, "UNKNOWN");
48 | }
49 |
50 | public Socks5CommandType(int byteValue, String name) {
51 | requireNonNull(name, "name");
52 |
53 | this.byteValue = (byte) byteValue;
54 | this.name = name;
55 | }
56 |
57 | public byte byteValue() {
58 | return byteValue;
59 | }
60 |
61 | @Override
62 | public int hashCode() {
63 | return byteValue;
64 | }
65 |
66 | @Override
67 | public boolean equals(Object obj) {
68 | if (!(obj instanceof Socks5CommandType)) {
69 | return false;
70 | }
71 |
72 | return byteValue == ((Socks5CommandType) obj).byteValue;
73 | }
74 |
75 | @Override
76 | public int compareTo(Socks5CommandType o) {
77 | return byteValue - o.byteValue;
78 | }
79 |
80 | @Override
81 | public String toString() {
82 | String text = this.text;
83 | if (text == null) {
84 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
85 | }
86 | return text;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5AddressType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The type of address in {@link Socks5CommandRequest} and {@link Socks5CommandResponse}.
22 | */
23 | public class Socks5AddressType implements Comparable {
24 |
25 | public static final Socks5AddressType IPv4 = new Socks5AddressType(0x01, "IPv4");
26 | public static final Socks5AddressType DOMAIN = new Socks5AddressType(0x03, "DOMAIN");
27 | public static final Socks5AddressType IPv6 = new Socks5AddressType(0x04, "IPv6");
28 |
29 | public static Socks5AddressType valueOf(byte b) {
30 | switch (b) {
31 | case 0x01:
32 | return IPv4;
33 | case 0x03:
34 | return DOMAIN;
35 | case 0x04:
36 | return IPv6;
37 | }
38 |
39 | return new Socks5AddressType(b);
40 | }
41 |
42 | private final byte byteValue;
43 | private final String name;
44 | private String text;
45 |
46 | public Socks5AddressType(int byteValue) {
47 | this(byteValue, "UNKNOWN");
48 | }
49 |
50 | public Socks5AddressType(int byteValue, String name) {
51 | requireNonNull(name, "name");
52 |
53 | this.byteValue = (byte) byteValue;
54 | this.name = name;
55 | }
56 |
57 | public byte byteValue() {
58 | return byteValue;
59 | }
60 |
61 | @Override
62 | public int hashCode() {
63 | return byteValue;
64 | }
65 |
66 | @Override
67 | public boolean equals(Object obj) {
68 | if (!(obj instanceof Socks5AddressType)) {
69 | return false;
70 | }
71 |
72 | return byteValue == ((Socks5AddressType) obj).byteValue;
73 | }
74 |
75 | @Override
76 | public int compareTo(Socks5AddressType o) {
77 | return byteValue - o.byteValue;
78 | }
79 |
80 | @Override
81 | public String toString() {
82 | String text = this.text;
83 | if (text == null) {
84 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
85 | }
86 | return text;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The status of {@link Socks5PasswordAuthResponse}.
22 | */
23 | public class Socks5PasswordAuthStatus implements Comparable {
24 |
25 | public static final Socks5PasswordAuthStatus SUCCESS = new Socks5PasswordAuthStatus(0x00, "SUCCESS");
26 | public static final Socks5PasswordAuthStatus FAILURE = new Socks5PasswordAuthStatus(0xFF, "FAILURE");
27 |
28 | public static Socks5PasswordAuthStatus valueOf(byte b) {
29 | switch (b) {
30 | case 0x00:
31 | return SUCCESS;
32 | case (byte) 0xFF:
33 | return FAILURE;
34 | }
35 |
36 | return new Socks5PasswordAuthStatus(b);
37 | }
38 |
39 | private final byte byteValue;
40 | private final String name;
41 | private String text;
42 |
43 | public Socks5PasswordAuthStatus(int byteValue) {
44 | this(byteValue, "UNKNOWN");
45 | }
46 |
47 | public Socks5PasswordAuthStatus(int byteValue, String name) {
48 | requireNonNull(name, "name");
49 |
50 | this.byteValue = (byte) byteValue;
51 | this.name = name;
52 | }
53 |
54 | public byte byteValue() {
55 | return byteValue;
56 | }
57 |
58 | public boolean isSuccess() {
59 | return byteValue == 0;
60 | }
61 |
62 | @Override
63 | public int hashCode() {
64 | return byteValue;
65 | }
66 |
67 | @Override
68 | public boolean equals(Object obj) {
69 | if (!(obj instanceof Socks5PasswordAuthStatus)) {
70 | return false;
71 | }
72 |
73 | return byteValue == ((Socks5PasswordAuthStatus) obj).byteValue;
74 | }
75 |
76 | @Override
77 | public int compareTo(Socks5PasswordAuthStatus o) {
78 | return byteValue - o.byteValue;
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | String text = this.text;
84 | if (text == null) {
85 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
86 | }
87 | return text;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/codec-socks/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.netty.contrib
7 | netty-socks-proxy-parent
8 | 5.0.0.Alpha3-SNAPSHOT
9 |
10 |
11 | netty-codec-socks
12 | 5.0.0.Alpha3-SNAPSHOT
13 | Netty/Codec/Socks
14 | jar
15 |
16 |
17 | io.netty.contrib.codec.socks
18 |
19 |
20 |
21 |
22 | io.netty
23 | netty5-common
24 | ${netty.version}
25 |
26 |
27 | io.netty
28 | netty5-buffer
29 | ${netty.version}
30 |
31 |
32 | io.netty
33 | netty5-transport
34 | ${netty.version}
35 |
36 |
37 | io.netty
38 | netty5-codec
39 | ${netty.version}
40 |
41 |
42 |
43 | org.junit.jupiter
44 | junit-jupiter-engine
45 | test
46 |
47 |
48 | org.assertj
49 | assertj-core
50 | test
51 |
52 |
53 | org.slf4j
54 | slf4j-api
55 | 1.7.32
56 |
57 |
58 |
59 |
60 | org.reflections
61 | reflections
62 |
63 |
64 | com.google.code.gson
65 | gson
66 |
67 |
68 | com.google.guava
69 | guava
70 |
71 |
72 | io.netty
73 | netty5-transport
74 | test-jar
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksAuthRequestDecoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.embedded.EmbeddedChannel;
20 | import org.junit.jupiter.api.Test;
21 |
22 | import static org.junit.jupiter.api.Assertions.assertEquals;
23 | import static org.junit.jupiter.api.Assertions.assertFalse;
24 | import static org.junit.jupiter.api.Assertions.assertNull;
25 |
26 | public class SocksAuthRequestDecoderTest {
27 |
28 | private static final String username = "testUserName";
29 | private static final String password = "testPassword";
30 |
31 | @Test
32 | public void testAuthRequestDecoder() {
33 | SocksAuthRequest msg = new SocksAuthRequest(username, password);
34 | SocksAuthRequestDecoder decoder = new SocksAuthRequestDecoder();
35 | EmbeddedChannel embedder = new EmbeddedChannel(decoder);
36 | SocksCommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
37 | msg = embedder.readInbound();
38 | assertEquals(username, msg.username());
39 | assertEquals(password, msg.password());
40 | assertNull(embedder.readInbound());
41 | }
42 |
43 | @Test
44 | public void testAuthRequestDecoderPartialSend() {
45 | EmbeddedChannel ch = new EmbeddedChannel(new SocksAuthRequestDecoder());
46 | Buffer buffer = ch.bufferAllocator().allocate(16);
47 |
48 | // Send username and password size
49 | buffer.writeByte(SocksSubnegotiationVersion.AUTH_PASSWORD.byteValue());
50 | buffer.writeByte((byte) username.length());
51 | buffer.writeBytes(username.getBytes());
52 | buffer.writeByte((byte) password.length());
53 | ch.writeInbound(buffer);
54 |
55 | // Check that channel is empty
56 | assertNull(ch.readInbound());
57 |
58 | // Send password
59 | Buffer buffer2 = ch.bufferAllocator().allocate(16);
60 | buffer2.writeBytes(password.getBytes());
61 | ch.writeInbound(buffer2);
62 |
63 | // Read message from channel
64 | SocksAuthRequest msg = ch.readInbound();
65 |
66 | // Check message
67 | assertEquals(username, msg.username());
68 | assertEquals(password, msg.password());
69 |
70 | assertFalse(ch.finishAndReleaseAll());
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5InitialRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.internal.StringUtil;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Collections;
23 | import java.util.List;
24 |
25 | import static io.netty5.util.internal.ObjectUtil.checkNonEmpty;
26 | import static java.util.Objects.requireNonNull;
27 |
28 | /**
29 | * The default {@link Socks5InitialRequest}.
30 | */
31 | public class DefaultSocks5InitialRequest extends AbstractSocks5Message implements Socks5InitialRequest {
32 |
33 | private final List authMethods;
34 |
35 | public DefaultSocks5InitialRequest(Socks5AuthMethod... authMethods) {
36 | requireNonNull(authMethods, "authMethods");
37 |
38 | List list = new ArrayList<>(authMethods.length);
39 | for (Socks5AuthMethod m: authMethods) {
40 | if (m == null) {
41 | break;
42 | }
43 | list.add(m);
44 | }
45 |
46 | this.authMethods = Collections.unmodifiableList(checkNonEmpty(list, "list"));
47 | }
48 |
49 | public DefaultSocks5InitialRequest(Iterable authMethods) {
50 | requireNonNull(authMethods, "authMethods");
51 |
52 | List list = new ArrayList<>();
53 | for (Socks5AuthMethod m: authMethods) {
54 | if (m == null) {
55 | break;
56 | }
57 | list.add(m);
58 | }
59 |
60 | this.authMethods = Collections.unmodifiableList(checkNonEmpty(list, "list"));
61 | }
62 |
63 | @Override
64 | public List authMethods() {
65 | return authMethods;
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | StringBuilder buf = new StringBuilder(StringUtil.simpleClassName(this));
71 |
72 | DecoderResult decoderResult = decoderResult();
73 | if (!decoderResult.isSuccess()) {
74 | buf.append("(decoderResult: ");
75 | buf.append(decoderResult);
76 | buf.append(", authMethods: ");
77 | } else {
78 | buf.append("(authMethods: ");
79 | }
80 | buf.append(authMethods());
81 | buf.append(')');
82 |
83 | return buf.toString();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5AuthMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The authentication method of SOCKS5.
22 | */
23 | public class Socks5AuthMethod implements Comparable {
24 |
25 | public static final Socks5AuthMethod NO_AUTH = new Socks5AuthMethod(0x00, "NO_AUTH");
26 | public static final Socks5AuthMethod GSSAPI = new Socks5AuthMethod(0x01, "GSSAPI");
27 | public static final Socks5AuthMethod PASSWORD = new Socks5AuthMethod(0x02, "PASSWORD");
28 |
29 | /**
30 | * Indicates that the server does not accept any authentication methods the client proposed.
31 | */
32 | public static final Socks5AuthMethod UNACCEPTED = new Socks5AuthMethod(0xff, "UNACCEPTED");
33 |
34 | public static Socks5AuthMethod valueOf(byte b) {
35 | switch (b) {
36 | case 0x00:
37 | return NO_AUTH;
38 | case 0x01:
39 | return GSSAPI;
40 | case 0x02:
41 | return PASSWORD;
42 | case (byte) 0xFF:
43 | return UNACCEPTED;
44 | }
45 |
46 | return new Socks5AuthMethod(b);
47 | }
48 |
49 | private final byte byteValue;
50 | private final String name;
51 | private String text;
52 |
53 | public Socks5AuthMethod(int byteValue) {
54 | this(byteValue, "UNKNOWN");
55 | }
56 |
57 | public Socks5AuthMethod(int byteValue, String name) {
58 | requireNonNull(name, "name");
59 |
60 | this.byteValue = (byte) byteValue;
61 | this.name = name;
62 | }
63 |
64 | public byte byteValue() {
65 | return byteValue;
66 | }
67 |
68 | @Override
69 | public int hashCode() {
70 | return byteValue;
71 | }
72 |
73 | @Override
74 | public boolean equals(Object obj) {
75 | if (!(obj instanceof Socks5AuthMethod)) {
76 | return false;
77 | }
78 |
79 | return byteValue == ((Socks5AuthMethod) obj).byteValue;
80 | }
81 |
82 | @Override
83 | public int compareTo(Socks5AuthMethod o) {
84 | return byteValue - o.byteValue;
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | String text = this.text;
90 | if (text == null) {
91 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
92 | }
93 | return text;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/handler-proxy/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | io.netty.contrib
7 | netty-socks-proxy-parent
8 | 5.0.0.Alpha3-SNAPSHOT
9 |
10 |
11 | netty-handler-proxy
12 | 5.0.0.Alpha3-SNAPSHOT
13 |
14 |
15 |
16 |
17 | kr.motd.maven
18 | os-maven-plugin
19 | 1.7.0
20 |
21 |
22 |
23 |
24 |
25 |
26 | io.netty.contrib
27 | netty-codec-socks
28 | ${project.version}
29 |
30 |
31 | io.netty
32 | netty5-handler
33 | ${netty.version}
34 |
35 |
36 | io.netty
37 | netty5-codec-http
38 | ${netty.version}
39 |
40 |
41 |
42 | org.junit.jupiter
43 | junit-jupiter-engine
44 | test
45 |
46 |
47 | org.junit.jupiter
48 | junit-jupiter-params
49 | test
50 |
51 |
52 | org.assertj
53 | assertj-core
54 | test
55 |
56 |
57 | org.mockito
58 | mockito-core
59 | 4.1.0
60 | test
61 |
62 |
63 |
64 |
65 | org.reflections
66 | reflections
67 |
68 |
69 | com.google.code.gson
70 | gson
71 |
72 |
73 | com.google.guava
74 | guava
75 |
76 |
77 | io.netty
78 | netty5-transport
79 | test-jar
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksInitRequestDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 |
22 | import java.util.ArrayList;
23 | import java.util.Collections;
24 | import java.util.List;
25 |
26 | /**
27 | * Decodes {@link Buffer}s into {@link SocksInitRequest}.
28 | * Before returning SocksRequest decoder removes itself from pipeline.
29 | */
30 | public class SocksInitRequestDecoder extends ByteToMessageDecoder {
31 |
32 | private enum State {
33 | CHECK_PROTOCOL_VERSION,
34 | READ_AUTH_SCHEMES
35 | }
36 | private State state = State.CHECK_PROTOCOL_VERSION;
37 |
38 | @Override
39 | protected void decode(ChannelHandlerContext ctx, Buffer buffer) throws Exception {
40 | switch (state) {
41 | case CHECK_PROTOCOL_VERSION: {
42 | if (buffer.readableBytes() < 1) {
43 | return;
44 | }
45 | if (buffer.readByte() != SocksProtocolVersion.SOCKS5.byteValue()) {
46 | ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST);
47 | break;
48 | }
49 | state = State.READ_AUTH_SCHEMES;
50 | }
51 | case READ_AUTH_SCHEMES: {
52 | if (buffer.readableBytes() < 1) {
53 | return;
54 | }
55 | final byte authSchemeNum = buffer.getByte(buffer.readerOffset());
56 | if (buffer.readableBytes() < 1 + authSchemeNum) {
57 | return;
58 | }
59 | buffer.skipReadableBytes(1);
60 | final List authSchemes;
61 | if (authSchemeNum > 0) {
62 | authSchemes = new ArrayList<>(authSchemeNum);
63 | for (int i = 0; i < authSchemeNum; i++) {
64 | authSchemes.add(SocksAuthScheme.valueOf(buffer.readByte()));
65 | }
66 | } else {
67 | authSchemes = Collections.emptyList();
68 | }
69 | ctx.fireChannelRead(new SocksInitRequest(authSchemes));
70 | break;
71 | }
72 | default: {
73 | throw new Error();
74 | }
75 | }
76 | ctx.pipeline().remove(this);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5AddressDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.handler.codec.DecoderException;
20 | import java.nio.charset.StandardCharsets;
21 | import io.netty5.util.NetUtil;
22 |
23 | /**
24 | * Decodes a SOCKS5 address field into its string representation.
25 | *
26 | * @see Socks5CommandRequestDecoder
27 | * @see Socks5CommandResponseDecoder
28 | */
29 | public interface Socks5AddressDecoder {
30 |
31 | Socks5AddressDecoder DEFAULT = new Socks5AddressDecoder() {
32 |
33 | private static final int IPv6_LEN = 16;
34 |
35 | @Override
36 | public String decodeAddress(Socks5AddressType addrType, Buffer in) {
37 | int readableBytes = in.readableBytes();
38 | if (addrType == Socks5AddressType.IPv4) {
39 | if (readableBytes < 4) {
40 | return null;
41 | }
42 | return NetUtil.intToIpAddress(in.readInt());
43 | }
44 | if (addrType == Socks5AddressType.DOMAIN) {
45 | if (readableBytes < 1) {
46 | return null;
47 | }
48 | final int length = in.getUnsignedByte(in.readerOffset());
49 | if (readableBytes - 1 < length) {
50 | return null;
51 | }
52 | in.skipReadableBytes(1);
53 | return in.readCharSequence(length, StandardCharsets.US_ASCII).toString();
54 | }
55 | if (addrType == Socks5AddressType.IPv6) {
56 | if (readableBytes < IPv6_LEN) {
57 | return null;
58 | }
59 | byte[] tmp = new byte[IPv6_LEN];
60 | in.readBytes(tmp, 0, tmp.length);
61 | return NetUtil.bytesToIpAddress(tmp);
62 | } else {
63 | throw new DecoderException("unsupported address type: " + (addrType.byteValue() & 0xFF));
64 | }
65 | }
66 | };
67 |
68 | /**
69 | * Decodes a SOCKS5 address field into its string representation.
70 | *
71 | * @param addrType the type of the address
72 | * @param in the input buffer which contains the SOCKS5 address field at its reader index
73 | * @return the address or {@code null} if not enough bytes are readable yet.
74 | */
75 | String decodeAddress(Socks5AddressType addrType, Buffer in) throws Exception;
76 | }
77 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4CommandStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The status of {@link Socks4CommandResponse}.
22 | */
23 | public class Socks4CommandStatus implements Comparable {
24 |
25 | public static final Socks4CommandStatus SUCCESS = new Socks4CommandStatus(0x5a, "SUCCESS");
26 | public static final Socks4CommandStatus REJECTED_OR_FAILED = new Socks4CommandStatus(0x5b, "REJECTED_OR_FAILED");
27 | public static final Socks4CommandStatus IDENTD_UNREACHABLE = new Socks4CommandStatus(0x5c, "IDENTD_UNREACHABLE");
28 | public static final Socks4CommandStatus IDENTD_AUTH_FAILURE = new Socks4CommandStatus(0x5d, "IDENTD_AUTH_FAILURE");
29 |
30 | public static Socks4CommandStatus valueOf(byte b) {
31 | switch (b) {
32 | case 0x5a:
33 | return SUCCESS;
34 | case 0x5b:
35 | return REJECTED_OR_FAILED;
36 | case 0x5c:
37 | return IDENTD_UNREACHABLE;
38 | case 0x5d:
39 | return IDENTD_AUTH_FAILURE;
40 | }
41 |
42 | return new Socks4CommandStatus(b);
43 | }
44 |
45 | private final byte byteValue;
46 | private final String name;
47 | private String text;
48 |
49 | public Socks4CommandStatus(int byteValue) {
50 | this(byteValue, "UNKNOWN");
51 | }
52 |
53 | public Socks4CommandStatus(int byteValue, String name) {
54 | requireNonNull(name, "name");
55 |
56 | this.byteValue = (byte) byteValue;
57 | this.name = name;
58 | }
59 |
60 | public byte byteValue() {
61 | return byteValue;
62 | }
63 |
64 | public boolean isSuccess() {
65 | return byteValue == 0x5a;
66 | }
67 |
68 | @Override
69 | public int hashCode() {
70 | return byteValue;
71 | }
72 |
73 | @Override
74 | public boolean equals(Object obj) {
75 | if (!(obj instanceof Socks4CommandStatus)) {
76 | return false;
77 | }
78 |
79 | return byteValue == ((Socks4CommandStatus) obj).byteValue;
80 | }
81 |
82 | @Override
83 | public int compareTo(Socks4CommandStatus o) {
84 | return byteValue - o.byteValue;
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | String text = this.text;
90 | if (text == null) {
91 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
92 | }
93 | return text;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.util.CharsetUtil;
20 |
21 | import java.nio.charset.StandardCharsets;
22 | import java.nio.charset.CharsetEncoder;
23 |
24 | import static java.util.Objects.requireNonNull;
25 |
26 | /**
27 | * An socks auth request.
28 | *
29 | * @see SocksAuthResponse
30 | * @see SocksAuthRequestDecoder
31 | */
32 | public final class SocksAuthRequest extends SocksRequest {
33 | private static final SocksSubnegotiationVersion SUBNEGOTIATION_VERSION = SocksSubnegotiationVersion.AUTH_PASSWORD;
34 | private final String username;
35 | private final String password;
36 |
37 | public SocksAuthRequest(String username, String password) {
38 | super(SocksRequestType.AUTH);
39 | requireNonNull(username, "username");
40 | requireNonNull(password, "password");
41 |
42 | final CharsetEncoder asciiEncoder = CharsetUtil.encoder(StandardCharsets.US_ASCII);
43 | if (!asciiEncoder.canEncode(username) || !asciiEncoder.canEncode(password)) {
44 | throw new IllegalArgumentException(
45 | "username: " + username + " or password: **** values should be in pure ascii");
46 | }
47 | if (username.length() > 255) {
48 | throw new IllegalArgumentException("username: " + username + " exceeds 255 char limit");
49 | }
50 | if (password.length() > 255) {
51 | throw new IllegalArgumentException("password: **** exceeds 255 char limit");
52 | }
53 | this.username = username;
54 | this.password = password;
55 | }
56 |
57 | /**
58 | * Returns username that needs to be authenticated
59 | *
60 | * @return username that needs to be authenticated
61 | */
62 | public String username() {
63 | return username;
64 | }
65 |
66 | /**
67 | * Returns password that needs to be validated
68 | *
69 | * @return password that needs to be validated
70 | */
71 | public String password() {
72 | return password;
73 | }
74 |
75 | @Override
76 | public void encodeAsBuffer(Buffer buffer) {
77 | buffer.writeByte(SUBNEGOTIATION_VERSION.byteValue());
78 | buffer.writeByte((byte) username.length());
79 | buffer.writeCharSequence(username, StandardCharsets.US_ASCII);
80 | buffer.writeByte((byte) password.length());
81 | buffer.writeCharSequence(password, StandardCharsets.US_ASCII);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5PasswordAuthRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.internal.StringUtil;
20 |
21 | import static java.util.Objects.requireNonNull;
22 |
23 | /**
24 | * The default {@link Socks5PasswordAuthRequest}.
25 | */
26 | public class DefaultSocks5PasswordAuthRequest extends AbstractSocks5Message implements Socks5PasswordAuthRequest {
27 |
28 | private final String username;
29 | private final String password;
30 |
31 | public DefaultSocks5PasswordAuthRequest(String username, String password) {
32 | requireNonNull(username, "username");
33 | requireNonNull(password, "password");
34 |
35 | if (username.length() > 255) {
36 | throw new IllegalArgumentException("username: **** (expected: less than 256 chars)");
37 | }
38 | if (password.length() > 255) {
39 | throw new IllegalArgumentException("password: **** (expected: less than 256 chars)");
40 | }
41 | if (containNonAscii(username)) {
42 | throw new IllegalArgumentException("username: **** (contains non-ASCII characters, which is not allowed)");
43 | }
44 | if (containNonAscii(password)) {
45 | throw new IllegalArgumentException("password: **** (contains non-ASCII characters, which is not allowed)");
46 | }
47 |
48 | this.username = username;
49 | this.password = password;
50 | }
51 |
52 | private static boolean containNonAscii(String string) {
53 | int length = string.length();
54 | for (int i = 0; i < length; i++) {
55 | char c = string.charAt(i);
56 | if (c > 127) {
57 | return true;
58 | }
59 | }
60 | return false;
61 | }
62 |
63 | @Override
64 | public String username() {
65 | return username;
66 | }
67 |
68 | @Override
69 | public String password() {
70 | return password;
71 | }
72 |
73 | @Override
74 | public String toString() {
75 | StringBuilder buf = new StringBuilder(StringUtil.simpleClassName(this));
76 |
77 | DecoderResult decoderResult = decoderResult();
78 | if (!decoderResult.isSuccess()) {
79 | buf.append("(decoderResult: ");
80 | buf.append(decoderResult);
81 | buf.append(", username: ");
82 | } else {
83 | buf.append("(username: ");
84 | }
85 | buf.append(username());
86 | buf.append(", password: ****)");
87 |
88 | return buf.toString();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/handler-proxy/src/main/java/io/netty/contrib/handler/proxy/ProxyConnectionEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.proxy;
17 |
18 | import io.netty5.util.internal.StringUtil;
19 |
20 | import java.net.SocketAddress;
21 |
22 | import static java.util.Objects.requireNonNull;
23 |
24 | public final class ProxyConnectionEvent {
25 |
26 | private final String protocol;
27 | private final String authScheme;
28 | private final SocketAddress proxyAddress;
29 | private final SocketAddress destinationAddress;
30 | private String strVal;
31 |
32 | /**
33 | * Creates a new event that indicates a successful connection attempt to the destination address.
34 | */
35 | public ProxyConnectionEvent(
36 | String protocol, String authScheme, SocketAddress proxyAddress, SocketAddress destinationAddress) {
37 | requireNonNull(protocol, "protocol");
38 | requireNonNull(authScheme, "authScheme");
39 | requireNonNull(proxyAddress, "proxyAddress");
40 | requireNonNull(destinationAddress, "destinationAddress");
41 |
42 | this.protocol = protocol;
43 | this.authScheme = authScheme;
44 | this.proxyAddress = proxyAddress;
45 | this.destinationAddress = destinationAddress;
46 | }
47 |
48 | /**
49 | * Returns the name of the proxy protocol in use.
50 | */
51 | public String protocol() {
52 | return protocol;
53 | }
54 |
55 | /**
56 | * Returns the name of the authentication scheme in use.
57 | */
58 | public String authScheme() {
59 | return authScheme;
60 | }
61 |
62 | /**
63 | * Returns the address of the proxy server.
64 | */
65 | @SuppressWarnings("unchecked")
66 | public T proxyAddress() {
67 | return (T) proxyAddress;
68 | }
69 |
70 | /**
71 | * Returns the address of the destination.
72 | */
73 | @SuppressWarnings("unchecked")
74 | public T destinationAddress() {
75 | return (T) destinationAddress;
76 | }
77 |
78 | @Override
79 | public String toString() {
80 | if (strVal != null) {
81 | return strVal;
82 | }
83 |
84 | StringBuilder buf = new StringBuilder(128)
85 | .append(StringUtil.simpleClassName(this))
86 | .append('(')
87 | .append(protocol)
88 | .append(", ")
89 | .append(authScheme)
90 | .append(", ")
91 | .append(proxyAddress)
92 | .append(" => ")
93 | .append(destinationAddress)
94 | .append(')');
95 |
96 | return strVal = buf.toString();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socks/SocksAuthRequestDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import java.nio.charset.StandardCharsets;
22 |
23 | /**
24 | * Decodes {@link Buffer}s into {@link SocksAuthRequest}.
25 | * Before returning SocksRequest decoder removes itself from pipeline.
26 | */
27 | public class SocksAuthRequestDecoder extends ByteToMessageDecoder {
28 |
29 | private enum State {
30 | CHECK_PROTOCOL_VERSION,
31 | READ_USERNAME,
32 | READ_PASSWORD
33 | }
34 | private State state = State.CHECK_PROTOCOL_VERSION;
35 | private String username;
36 |
37 | @Override
38 | protected void decode(ChannelHandlerContext ctx, Buffer buffer) throws Exception {
39 | switch (state) {
40 | case CHECK_PROTOCOL_VERSION: {
41 | if (buffer.readableBytes() < 1) {
42 | return;
43 | }
44 | if (buffer.readByte() != SocksSubnegotiationVersion.AUTH_PASSWORD.byteValue()) {
45 | ctx.fireChannelRead(SocksCommonUtils.UNKNOWN_SOCKS_REQUEST);
46 | break;
47 | }
48 | state = State.READ_USERNAME;
49 | }
50 | case READ_USERNAME: {
51 | if (buffer.readableBytes() < 1) {
52 | return;
53 | }
54 | int fieldLength = buffer.getByte(buffer.readerOffset());
55 | if (buffer.readableBytes() < 1 + fieldLength) {
56 | return;
57 | }
58 | buffer.skipReadableBytes(1);
59 | username = buffer.readCharSequence(fieldLength, StandardCharsets.US_ASCII).toString();
60 | state = State.READ_PASSWORD;
61 | }
62 | case READ_PASSWORD: {
63 | if (buffer.readableBytes() < 1) {
64 | return;
65 | }
66 | int fieldLength = buffer.getByte(buffer.readerOffset());
67 | if (buffer.readableBytes() < 1 + fieldLength) {
68 | return;
69 | }
70 | buffer.skipReadableBytes(1);
71 | String password = buffer.readCharSequence(fieldLength, StandardCharsets.US_ASCII).toString();
72 | ctx.fireChannelRead(new SocksAuthRequest(username, password));
73 | break;
74 | }
75 | default: {
76 | throw new Error();
77 | }
78 | }
79 | ctx.pipeline().remove(this);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5PasswordAuthRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class DefaultSocks5PasswordAuthRequestTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class, () -> new DefaultSocks5PasswordAuthRequest(null, ""));
26 | assertThrows(NullPointerException.class, () -> new DefaultSocks5PasswordAuthRequest("", null));
27 | }
28 |
29 | @Test
30 | public void testUsernameOrPasswordIsNotAscii() {
31 | assertThrows(IllegalArgumentException.class,
32 | () -> new DefaultSocks5PasswordAuthRequest("παράδειγμα.δοκιμή", "password"));
33 | assertThrows(IllegalArgumentException.class,
34 | () -> new DefaultSocks5PasswordAuthRequest("username", "παράδειγμα.δοκιμή"));
35 | }
36 |
37 | @Test
38 | public void testUsernameOrPasswordLengthIsLessThan255Chars() {
39 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5PasswordAuthRequest(
40 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
41 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
42 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
43 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
44 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
45 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
46 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
47 | "passwordpasswordpasswordpasswordpasswordpasswordpassword",
48 | "password"));
49 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5PasswordAuthRequest("password",
50 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
51 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
52 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
53 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
54 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
55 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
56 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
57 | "passwordpasswordpasswordpasswordpasswordpasswordpassword"));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthResponseDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import io.netty5.handler.codec.DecoderException;
22 | import io.netty5.handler.codec.DecoderResult;
23 |
24 | /**
25 | * Decodes a single {@link Socks5PasswordAuthResponse} from the inbound {@link Buffer}s.
26 | * On successful decode, this decoder will forward the received data to the next handler, so that
27 | * other handler can remove or replace this decoder later. On failed decode, this decoder will
28 | * discard the received data, so that other handler closes the connection later.
29 | */
30 | public class Socks5PasswordAuthResponseDecoder extends ByteToMessageDecoder {
31 |
32 | private enum State {
33 | INIT,
34 | SUCCESS,
35 | FAILURE
36 | }
37 |
38 | private State state = State.INIT;
39 |
40 | @Override
41 | protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
42 | try {
43 | switch (state) {
44 | case INIT: {
45 | if (in.readableBytes() < 2) {
46 | return;
47 | }
48 | final byte version = in.readByte();
49 | if (version != 1) {
50 | throw new DecoderException("unsupported subnegotiation version: " + version + " (expected: 1)");
51 | }
52 |
53 | ctx.fireChannelRead(
54 | new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.valueOf(in.readByte())));
55 | state = State.SUCCESS;
56 | }
57 | case SUCCESS: {
58 | int readableBytes = actualReadableBytes();
59 | if (readableBytes > 0) {
60 | ctx.fireChannelRead(in.readSplit(readableBytes));
61 | }
62 | break;
63 | }
64 | case FAILURE: {
65 | in.skipReadableBytes(actualReadableBytes());
66 | break;
67 | }
68 | }
69 | } catch (Exception e) {
70 | fail(ctx, e);
71 | }
72 | }
73 |
74 | private void fail(ChannelHandlerContext ctx, Exception cause) {
75 | if (!(cause instanceof DecoderException)) {
76 | cause = new DecoderException(cause);
77 | }
78 |
79 | state = State.FAILURE;
80 |
81 | Socks5Message m = new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.FAILURE);
82 | m.setDecoderResult(DecoderResult.failure(cause));
83 | ctx.fireChannelRead(m);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5CommandRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertThrows;
21 |
22 | public class DefaultSocks5CommandRequestTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | assertThrows(NullPointerException.class,
26 | () -> new DefaultSocks5CommandRequest(null, Socks5AddressType.DOMAIN, "", 1));
27 | assertThrows(NullPointerException.class,
28 | () -> new DefaultSocks5CommandRequest(Socks5CommandType.CONNECT, null, "", 1));
29 | assertThrows(NullPointerException.class,
30 | () -> new DefaultSocks5CommandRequest(Socks5CommandType.CONNECT, Socks5AddressType.DOMAIN, null, 1));
31 | }
32 |
33 | @Test
34 | public void testIPv4CorrectAddress() {
35 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5CommandRequest(
36 | Socks5CommandType.BIND, Socks5AddressType.IPv4, "54.54.1111.253", 1));
37 | }
38 |
39 | @Test
40 | public void testIPv6CorrectAddress() {
41 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5CommandRequest(
42 | Socks5CommandType.BIND, Socks5AddressType.IPv6, "xxx:xxx:xxx", 1));
43 | }
44 |
45 | @Test
46 | public void testIDNNotExceeds255CharsLimit() {
47 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5CommandRequest(
48 | Socks5CommandType.BIND, Socks5AddressType.DOMAIN,
49 | "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
50 | "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
51 | "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
52 | "παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή", 1));
53 | }
54 |
55 | @Test
56 | public void testValidPortRange() {
57 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5CommandRequest(
58 | Socks5CommandType.BIND, Socks5AddressType.DOMAIN, "παράδειγμα.δοκιμήπαράδει", -1));
59 | assertThrows(IllegalArgumentException.class, () -> new DefaultSocks5CommandRequest(
60 | Socks5CommandType.BIND, Socks5AddressType.DOMAIN, "παράδειγμα.δοκιμήπαράδει", 65536));
61 |
62 | new DefaultSocks5CommandRequest(Socks5CommandType.BIND, Socks5AddressType.DOMAIN,
63 | "παράδειγμα.δοκιμήπαράδει", 0);
64 | new DefaultSocks5CommandRequest(Socks5CommandType.BIND, Socks5AddressType.DOMAIN,
65 | "παράδειγμα.δοκιμήπαράδει", 65535);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5InitialResponseDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import io.netty5.handler.codec.DecoderException;
22 | import io.netty5.handler.codec.DecoderResult;
23 | import io.netty.contrib.handler.codec.socksx.SocksVersion;
24 |
25 | /**
26 | * Decodes a single {@link Socks5InitialResponse} from the inbound {@link Buffer}s.
27 | * On successful decode, this decoder will forward the received data to the next handler, so that
28 | * other handler can remove or replace this decoder later. On failed decode, this decoder will
29 | * discard the received data, so that other handler closes the connection later.
30 | */
31 | public class Socks5InitialResponseDecoder extends ByteToMessageDecoder {
32 |
33 | private enum State {
34 | INIT,
35 | SUCCESS,
36 | FAILURE
37 | }
38 |
39 | private State state = State.INIT;
40 |
41 | @Override
42 | protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
43 | try {
44 | switch (state) {
45 | case INIT: {
46 | if (in.readableBytes() < 2) {
47 | return;
48 | }
49 | final byte version = in.readByte();
50 | if (version != SocksVersion.SOCKS5.byteValue()) {
51 | throw new DecoderException(
52 | "unsupported version: " + version + " (expected: " + SocksVersion.SOCKS5.byteValue() + ')');
53 | }
54 |
55 | final Socks5AuthMethod authMethod = Socks5AuthMethod.valueOf(in.readByte());
56 | ctx.fireChannelRead(new DefaultSocks5InitialResponse(authMethod));
57 | state = State.SUCCESS;
58 | }
59 | case SUCCESS: {
60 | int readableBytes = actualReadableBytes();
61 | if (readableBytes > 0) {
62 | ctx.fireChannelRead(in.readSplit(readableBytes));
63 | }
64 | break;
65 | }
66 | case FAILURE: {
67 | in.skipReadableBytes(actualReadableBytes());
68 | break;
69 | }
70 | }
71 | } catch (Exception e) {
72 | fail(ctx, e);
73 | }
74 | }
75 |
76 | private void fail(ChannelHandlerContext ctx, Exception cause) {
77 | if (!(cause instanceof DecoderException)) {
78 | cause = new DecoderException(cause);
79 | }
80 |
81 | state = State.FAILURE;
82 |
83 | Socks5Message m = new DefaultSocks5InitialResponse(Socks5AuthMethod.UNACCEPTED);
84 | m.setDecoderResult(DecoderResult.failure(cause));
85 | ctx.fireChannelRead(m);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/DefaultSocks4CommandResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.NetUtil;
20 | import io.netty5.util.internal.StringUtil;
21 |
22 | import static java.util.Objects.requireNonNull;
23 |
24 | /**
25 | * The default {@link Socks4CommandResponse}.
26 | */
27 | public class DefaultSocks4CommandResponse extends AbstractSocks4Message implements Socks4CommandResponse {
28 |
29 | private final Socks4CommandStatus status;
30 | private final String dstAddr;
31 | private final int dstPort;
32 |
33 | /**
34 | * Creates a new instance.
35 | *
36 | * @param status the status of the response
37 | */
38 | public DefaultSocks4CommandResponse(Socks4CommandStatus status) {
39 | this(status, null, 0);
40 | }
41 |
42 | /**
43 | * Creates a new instance.
44 | *
45 | * @param status the status of the response
46 | * @param dstAddr the {@code DSTIP} field of the response
47 | * @param dstPort the {@code DSTPORT} field of the response
48 | */
49 | public DefaultSocks4CommandResponse(Socks4CommandStatus status, String dstAddr, int dstPort) {
50 | requireNonNull(status, "status");
51 | if (dstAddr != null) {
52 | if (!NetUtil.isValidIpV4Address(dstAddr)) {
53 | throw new IllegalArgumentException(
54 | "dstAddr: " + dstAddr + " (expected: a valid IPv4 address)");
55 | }
56 | }
57 | if (dstPort < 0 || dstPort > 65535) {
58 | throw new IllegalArgumentException("dstPort: " + dstPort + " (expected: 0~65535)");
59 | }
60 |
61 | this.status = status;
62 | this.dstAddr = dstAddr;
63 | this.dstPort = dstPort;
64 | }
65 |
66 | @Override
67 | public Socks4CommandStatus status() {
68 | return status;
69 | }
70 |
71 | @Override
72 | public String dstAddr() {
73 | return dstAddr;
74 | }
75 |
76 | @Override
77 | public int dstPort() {
78 | return dstPort;
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | StringBuilder buf = new StringBuilder(96);
84 | buf.append(StringUtil.simpleClassName(this));
85 |
86 | DecoderResult decoderResult = decoderResult();
87 | if (!decoderResult.isSuccess()) {
88 | buf.append("(decoderResult: ");
89 | buf.append(decoderResult);
90 | buf.append(", dstAddr: ");
91 | } else {
92 | buf.append("(dstAddr: ");
93 | }
94 | buf.append(dstAddr());
95 | buf.append(", dstPort: ");
96 | buf.append(dstPort());
97 | buf.append(')');
98 |
99 | return buf.toString();
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/codec-socks/src/test/java/io/netty/contrib/handler/codec/socks/SocksAuthRequestTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socks;
17 |
18 | import org.junit.jupiter.api.Test;
19 |
20 | import static org.junit.jupiter.api.Assertions.assertTrue;
21 |
22 | public class SocksAuthRequestTest {
23 | @Test
24 | public void testConstructorParamsAreNotNull() {
25 | try {
26 | new SocksAuthRequest(null, "");
27 | } catch (Exception e) {
28 | assertTrue(e instanceof NullPointerException);
29 | }
30 | try {
31 | new SocksAuthRequest("", null);
32 | } catch (Exception e) {
33 | assertTrue(e instanceof NullPointerException);
34 | }
35 | }
36 |
37 | @Test
38 | public void testUsernameOrPasswordIsNotAscii() {
39 | try {
40 | new SocksAuthRequest("παράδειγμα.δοκιμή", "password");
41 | } catch (Exception e) {
42 | assertTrue(e instanceof IllegalArgumentException);
43 | }
44 | try {
45 | new SocksAuthRequest("username", "παράδειγμα.δοκιμή");
46 | } catch (Exception e) {
47 | assertTrue(e instanceof IllegalArgumentException);
48 | }
49 | }
50 |
51 | @Test
52 | public void testUsernameOrPasswordLengthIsLessThan255Chars() {
53 | try {
54 | new SocksAuthRequest(
55 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
56 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
57 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
58 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
59 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
60 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
61 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
62 | "passwordpasswordpasswordpasswordpasswordpasswordpassword",
63 | "password");
64 | } catch (Exception e) {
65 | assertTrue(e instanceof IllegalArgumentException);
66 | }
67 | try {
68 | new SocksAuthRequest("password",
69 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
70 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
71 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
72 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
73 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
74 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
75 | "passwordpasswordpasswordpasswordpasswordpasswordpassword" +
76 | "passwordpasswordpasswordpasswordpasswordpasswordpassword");
77 | } catch (Exception e) {
78 | assertTrue(e instanceof IllegalArgumentException);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/Socks4ClientDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import io.netty5.handler.codec.DecoderException;
22 | import io.netty5.handler.codec.DecoderResult;
23 | import io.netty5.util.NetUtil;
24 |
25 | /**
26 | * Decodes a single {@link Socks4CommandResponse} from the inbound {@link Buffer}s.
27 | * On successful decode, this decoder will forward the received data to the next handler, so that
28 | * other handler can remove this decoder later. On failed decode, this decoder will discard the
29 | * received data, so that other handler closes the connection later.
30 | */
31 | public class Socks4ClientDecoder extends ByteToMessageDecoder {
32 |
33 | private enum State {
34 | START,
35 | SUCCESS,
36 | FAILURE
37 | }
38 |
39 | private State state = State.START;
40 |
41 | public Socks4ClientDecoder() {
42 | setSingleDecode(true);
43 | }
44 |
45 | @Override
46 | protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
47 | try {
48 | switch (state) {
49 | case START: {
50 | if (in.readableBytes() < 8) {
51 | // Not enough data to read.
52 | return;
53 | }
54 | final int version = in.readUnsignedByte();
55 | if (version != 0) {
56 | throw new DecoderException("unsupported reply version: " + version + " (expected: 0)");
57 | }
58 |
59 | final Socks4CommandStatus status = Socks4CommandStatus.valueOf(in.readByte());
60 | final int dstPort = in.readUnsignedShort();
61 | final String dstAddr = NetUtil.intToIpAddress(in.readInt());
62 |
63 | ctx.fireChannelRead(new DefaultSocks4CommandResponse(status, dstAddr, dstPort));
64 | state = State.SUCCESS;
65 | // fall-through
66 | }
67 | case SUCCESS: {
68 | int readableBytes = actualReadableBytes();
69 | if (readableBytes > 0) {
70 | ctx.fireChannelRead(in.readSplit(readableBytes));
71 | }
72 | break;
73 | }
74 | case FAILURE: {
75 | in.skipReadableBytes(actualReadableBytes());
76 | break;
77 | }
78 | }
79 | } catch (Exception e) {
80 | fail(ctx, e);
81 | }
82 | }
83 |
84 | private void fail(ChannelHandlerContext ctx, Exception cause) {
85 | if (!(cause instanceof DecoderException)) {
86 | cause = new DecoderException(cause);
87 | }
88 |
89 | Socks4CommandResponse m = new DefaultSocks4CommandResponse(Socks4CommandStatus.REJECTED_OR_FAILED);
90 | m.setDecoderResult(DecoderResult.failure(cause));
91 | ctx.fireChannelRead(m);
92 |
93 | state = State.FAILURE;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v4/DefaultSocks4CommandRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v4;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.internal.StringUtil;
20 |
21 | import java.net.IDN;
22 |
23 | import static java.util.Objects.requireNonNull;
24 |
25 | /**
26 | * The default {@link Socks4CommandRequest}.
27 | */
28 | public class DefaultSocks4CommandRequest extends AbstractSocks4Message implements Socks4CommandRequest {
29 |
30 | private final Socks4CommandType type;
31 | private final String dstAddr;
32 | private final int dstPort;
33 | private final String userId;
34 |
35 | /**
36 | * Creates a new instance.
37 | *
38 | * @param type the type of the request
39 | * @param dstAddr the {@code DSTIP} field of the request
40 | * @param dstPort the {@code DSTPORT} field of the request
41 | */
42 | public DefaultSocks4CommandRequest(Socks4CommandType type, String dstAddr, int dstPort) {
43 | this(type, dstAddr, dstPort, "");
44 | }
45 |
46 | /**
47 | * Creates a new instance.
48 | *
49 | * @param type the type of the request
50 | * @param dstAddr the {@code DSTIP} field of the request
51 | * @param dstPort the {@code DSTPORT} field of the request
52 | * @param userId the {@code USERID} field of the request
53 | */
54 | public DefaultSocks4CommandRequest(Socks4CommandType type, String dstAddr, int dstPort, String userId) {
55 | requireNonNull(type, "type");
56 | requireNonNull(dstAddr, "dstAddr");
57 | if (dstPort <= 0 || dstPort >= 65536) {
58 | throw new IllegalArgumentException("dstPort: " + dstPort + " (expected: 1~65535)");
59 | }
60 | requireNonNull(userId, "userId");
61 |
62 | this.userId = userId;
63 | this.type = type;
64 | this.dstAddr = IDN.toASCII(dstAddr);
65 | this.dstPort = dstPort;
66 | }
67 |
68 | @Override
69 | public Socks4CommandType type() {
70 | return type;
71 | }
72 |
73 | @Override
74 | public String dstAddr() {
75 | return dstAddr;
76 | }
77 |
78 | @Override
79 | public int dstPort() {
80 | return dstPort;
81 | }
82 |
83 | @Override
84 | public String userId() {
85 | return userId;
86 | }
87 |
88 | @Override
89 | public String toString() {
90 | StringBuilder buf = new StringBuilder(128);
91 | buf.append(StringUtil.simpleClassName(this));
92 |
93 | DecoderResult decoderResult = decoderResult();
94 | if (!decoderResult.isSuccess()) {
95 | buf.append("(decoderResult: ");
96 | buf.append(decoderResult);
97 | buf.append(", type: ");
98 | } else {
99 | buf.append("(type: ");
100 | }
101 | buf.append(type());
102 | buf.append(", dstAddr: ");
103 | buf.append(dstAddr());
104 | buf.append(", dstPort: ");
105 | buf.append(dstPort());
106 | buf.append(", userId: ");
107 | buf.append(userId());
108 | buf.append(')');
109 |
110 | return buf.toString();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5InitialRequestDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import io.netty5.handler.codec.DecoderException;
22 | import io.netty5.handler.codec.DecoderResult;
23 | import io.netty.contrib.handler.codec.socksx.SocksVersion;
24 |
25 | /**
26 | * Decodes a single {@link Socks5InitialRequest} from the inbound {@link Buffer}s.
27 | * On successful decode, this decoder will forward the received data to the next handler, so that
28 | * other handler can remove or replace this decoder later. On failed decode, this decoder will
29 | * discard the received data, so that other handler closes the connection later.
30 | */
31 | public class Socks5InitialRequestDecoder extends ByteToMessageDecoder {
32 |
33 | private enum State {
34 | INIT,
35 | SUCCESS,
36 | FAILURE
37 | }
38 |
39 | private State state = State.INIT;
40 |
41 | @Override
42 | protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
43 | try {
44 | switch (state) {
45 | case INIT: {
46 | if (in.readableBytes() < 2) {
47 | return;
48 | }
49 | int readerIndex = in.readerOffset();
50 | final byte version = in.readByte();
51 | if (version != SocksVersion.SOCKS5.byteValue()) {
52 | throw new DecoderException(
53 | "unsupported version: " + version + " (expected: " + SocksVersion.SOCKS5.byteValue() + ')');
54 | }
55 |
56 | final int authMethodCnt = in.readUnsignedByte();
57 |
58 | if (in.readableBytes() < authMethodCnt) {
59 | in.readerOffset(readerIndex);
60 | return;
61 | }
62 | final Socks5AuthMethod[] authMethods = new Socks5AuthMethod[authMethodCnt];
63 | for (int i = 0; i < authMethodCnt; i++) {
64 | authMethods[i] = Socks5AuthMethod.valueOf(in.readByte());
65 | }
66 |
67 | ctx.fireChannelRead(new DefaultSocks5InitialRequest(authMethods));
68 | state = State.SUCCESS;
69 | }
70 | case SUCCESS: {
71 | int readableBytes = actualReadableBytes();
72 | if (readableBytes > 0) {
73 | ctx.fireChannelRead(in.readSplit(readableBytes));
74 | }
75 | break;
76 | }
77 | case FAILURE: {
78 | in.skipReadableBytes(actualReadableBytes());
79 | break;
80 | }
81 | }
82 | } catch (Exception e) {
83 | fail(ctx, e);
84 | }
85 | }
86 |
87 | private void fail(ChannelHandlerContext ctx, Exception cause) {
88 | if (!(cause instanceof DecoderException)) {
89 | cause = new DecoderException(cause);
90 | }
91 |
92 | state = State.FAILURE;
93 |
94 | Socks5Message m = new DefaultSocks5InitialRequest(Socks5AuthMethod.NO_AUTH);
95 | m.setDecoderResult(DecoderResult.failure(cause));
96 | ctx.fireChannelRead(m);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5PasswordAuthRequestDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.ByteToMessageDecoder;
21 | import io.netty5.handler.codec.DecoderException;
22 | import io.netty5.handler.codec.DecoderResult;
23 | import java.nio.charset.StandardCharsets;
24 |
25 | /**
26 | * Decodes a single {@link Socks5PasswordAuthRequest} from the inbound {@link Buffer}s.
27 | * On successful decode, this decoder will forward the received data to the next handler, so that
28 | * other handler can remove or replace this decoder later. On failed decode, this decoder will
29 | * discard the received data, so that other handler closes the connection later.
30 | */
31 | public class Socks5PasswordAuthRequestDecoder extends ByteToMessageDecoder {
32 |
33 | private enum State {
34 | INIT,
35 | SUCCESS,
36 | FAILURE
37 | }
38 |
39 | private State state = State.INIT;
40 |
41 | @Override
42 | protected void decode(ChannelHandlerContext ctx, Buffer in) throws Exception {
43 | try {
44 | switch (state) {
45 | case INIT: {
46 | if (in.readableBytes() < 3) {
47 | return;
48 | }
49 | final int startOffset = in.readerOffset();
50 | final byte version = in.getByte(startOffset);
51 | if (version != 1) {
52 | throw new DecoderException("unsupported subnegotiation version: " + version + " (expected: 1)");
53 | }
54 |
55 | final int usernameLength = in.getUnsignedByte(startOffset + 1);
56 | final int passwordLength = in.getUnsignedByte(startOffset + 2 + usernameLength);
57 | final int totalLength = usernameLength + passwordLength + 3;
58 | if (in.readableBytes() < totalLength) {
59 | return;
60 | }
61 | in.skipReadableBytes(2);
62 | String username = in.readCharSequence(usernameLength, StandardCharsets.US_ASCII).toString();
63 | in.skipReadableBytes(1);
64 | String password = in.readCharSequence(passwordLength, StandardCharsets.US_ASCII).toString();
65 | ctx.fireChannelRead(new DefaultSocks5PasswordAuthRequest(username, password));
66 |
67 | state = State.SUCCESS;
68 | }
69 | case SUCCESS: {
70 | int readableBytes = actualReadableBytes();
71 | if (readableBytes > 0) {
72 | ctx.fireChannelRead(in.readSplit(readableBytes));
73 | }
74 | break;
75 | }
76 | case FAILURE: {
77 | in.skipReadableBytes(actualReadableBytes());
78 | break;
79 | }
80 | }
81 | } catch (Exception e) {
82 | fail(ctx, e);
83 | }
84 | }
85 |
86 | private void fail(ChannelHandlerContext ctx, Exception cause) {
87 | if (!(cause instanceof DecoderException)) {
88 | cause = new DecoderException(cause);
89 | }
90 |
91 | state = State.FAILURE;
92 |
93 | Socks5Message m = new DefaultSocks5PasswordAuthRequest("", "");
94 | m.setDecoderResult(DecoderResult.failure(cause));
95 | ctx.fireChannelRead(m);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/DefaultSocks5CommandRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.handler.codec.DecoderResult;
19 | import io.netty5.util.NetUtil;
20 | import io.netty5.util.internal.StringUtil;
21 |
22 | import java.net.IDN;
23 |
24 | import static java.util.Objects.requireNonNull;
25 |
26 | /**
27 | * The default {@link Socks5CommandRequest}.
28 | */
29 | public final class DefaultSocks5CommandRequest extends AbstractSocks5Message implements Socks5CommandRequest {
30 |
31 | private final Socks5CommandType type;
32 | private final Socks5AddressType dstAddrType;
33 | private final String dstAddr;
34 | private final int dstPort;
35 |
36 | public DefaultSocks5CommandRequest(
37 | Socks5CommandType type, Socks5AddressType dstAddrType, String dstAddr, int dstPort) {
38 | requireNonNull(type, "type");
39 | requireNonNull(dstAddrType, "dstAddrType");
40 | requireNonNull(dstAddr, "dstAddr");
41 |
42 | if (dstAddrType == Socks5AddressType.IPv4) {
43 | if (!NetUtil.isValidIpV4Address(dstAddr)) {
44 | throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv4 address)");
45 | }
46 | } else if (dstAddrType == Socks5AddressType.DOMAIN) {
47 | dstAddr = IDN.toASCII(dstAddr);
48 | if (dstAddr.length() > 255) {
49 | throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: less than 256 chars)");
50 | }
51 | } else if (dstAddrType == Socks5AddressType.IPv6) {
52 | if (!NetUtil.isValidIpV6Address(dstAddr)) {
53 | throw new IllegalArgumentException("dstAddr: " + dstAddr + " (expected: a valid IPv6 address");
54 | }
55 | }
56 |
57 | if (dstPort < 0 || dstPort > 65535) {
58 | throw new IllegalArgumentException("dstPort: " + dstPort + " (expected: 0~65535)");
59 | }
60 |
61 | this.type = type;
62 | this.dstAddrType = dstAddrType;
63 | this.dstAddr = dstAddr;
64 | this.dstPort = dstPort;
65 | }
66 |
67 | @Override
68 | public Socks5CommandType type() {
69 | return type;
70 | }
71 |
72 | @Override
73 | public Socks5AddressType dstAddrType() {
74 | return dstAddrType;
75 | }
76 |
77 | @Override
78 | public String dstAddr() {
79 | return dstAddr;
80 | }
81 |
82 | @Override
83 | public int dstPort() {
84 | return dstPort;
85 | }
86 |
87 | @Override
88 | public String toString() {
89 | StringBuilder buf = new StringBuilder(128);
90 | buf.append(StringUtil.simpleClassName(this));
91 |
92 | DecoderResult decoderResult = decoderResult();
93 | if (!decoderResult.isSuccess()) {
94 | buf.append("(decoderResult: ");
95 | buf.append(decoderResult);
96 | buf.append(", type: ");
97 | } else {
98 | buf.append("(type: ");
99 | }
100 | buf.append(type());
101 | buf.append(", dstAddrType: ");
102 | buf.append(dstAddrType());
103 | buf.append(", dstAddr: ");
104 | buf.append(dstAddr());
105 | buf.append(", dstPort: ");
106 | buf.append(dstPort());
107 | buf.append(')');
108 |
109 | return buf.toString();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5CommandStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import static java.util.Objects.requireNonNull;
19 |
20 | /**
21 | * The status of {@link Socks5CommandResponse}.
22 | */
23 | public class Socks5CommandStatus implements Comparable {
24 |
25 | public static final Socks5CommandStatus SUCCESS = new Socks5CommandStatus(0x00, "SUCCESS");
26 | public static final Socks5CommandStatus FAILURE = new Socks5CommandStatus(0x01, "FAILURE");
27 | public static final Socks5CommandStatus FORBIDDEN = new Socks5CommandStatus(0x02, "FORBIDDEN");
28 | public static final Socks5CommandStatus NETWORK_UNREACHABLE = new Socks5CommandStatus(0x03, "NETWORK_UNREACHABLE");
29 | public static final Socks5CommandStatus HOST_UNREACHABLE = new Socks5CommandStatus(0x04, "HOST_UNREACHABLE");
30 | public static final Socks5CommandStatus CONNECTION_REFUSED = new Socks5CommandStatus(0x05, "CONNECTION_REFUSED");
31 | public static final Socks5CommandStatus TTL_EXPIRED = new Socks5CommandStatus(0x06, "TTL_EXPIRED");
32 | public static final Socks5CommandStatus COMMAND_UNSUPPORTED = new Socks5CommandStatus(0x07, "COMMAND_UNSUPPORTED");
33 | public static final Socks5CommandStatus ADDRESS_UNSUPPORTED = new Socks5CommandStatus(0x08, "ADDRESS_UNSUPPORTED");
34 |
35 | public static Socks5CommandStatus valueOf(byte b) {
36 | switch (b) {
37 | case 0x00:
38 | return SUCCESS;
39 | case 0x01:
40 | return FAILURE;
41 | case 0x02:
42 | return FORBIDDEN;
43 | case 0x03:
44 | return NETWORK_UNREACHABLE;
45 | case 0x04:
46 | return HOST_UNREACHABLE;
47 | case 0x05:
48 | return CONNECTION_REFUSED;
49 | case 0x06:
50 | return TTL_EXPIRED;
51 | case 0x07:
52 | return COMMAND_UNSUPPORTED;
53 | case 0x08:
54 | return ADDRESS_UNSUPPORTED;
55 | }
56 |
57 | return new Socks5CommandStatus(b);
58 | }
59 |
60 | private final byte byteValue;
61 | private final String name;
62 | private String text;
63 |
64 | public Socks5CommandStatus(int byteValue) {
65 | this(byteValue, "UNKNOWN");
66 | }
67 |
68 | public Socks5CommandStatus(int byteValue, String name) {
69 | requireNonNull(name, "name");
70 |
71 | this.byteValue = (byte) byteValue;
72 | this.name = name;
73 | }
74 |
75 | public byte byteValue() {
76 | return byteValue;
77 | }
78 |
79 | public boolean isSuccess() {
80 | return byteValue == 0;
81 | }
82 |
83 | @Override
84 | public int hashCode() {
85 | return byteValue;
86 | }
87 |
88 | @Override
89 | public boolean equals(Object obj) {
90 | if (!(obj instanceof Socks5CommandStatus)) {
91 | return false;
92 | }
93 |
94 | return byteValue == ((Socks5CommandStatus) obj).byteValue;
95 | }
96 |
97 | @Override
98 | public int compareTo(Socks5CommandStatus o) {
99 | return byteValue - o.byteValue;
100 | }
101 |
102 | @Override
103 | public String toString() {
104 | String text = this.text;
105 | if (text == null) {
106 | this.text = text = name + '(' + (byteValue & 0xFF) + ')';
107 | }
108 | return text;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/codec-socks/src/main/java/io/netty/contrib/handler/codec/socksx/v5/Socks5ServerEncoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 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.contrib.handler.codec.socksx.v5;
17 |
18 | import io.netty5.buffer.Buffer;
19 | import io.netty5.channel.ChannelHandlerContext;
20 | import io.netty5.handler.codec.EncoderException;
21 | import io.netty5.handler.codec.MessageToByteEncoder;
22 | import io.netty5.util.internal.StringUtil;
23 |
24 | import static java.util.Objects.requireNonNull;
25 |
26 | /**
27 | * Encodes a server-side {@link Socks5Message} into a {@link Buffer}.
28 | */
29 | public class Socks5ServerEncoder extends MessageToByteEncoder {
30 |
31 | public static final Socks5ServerEncoder DEFAULT = new Socks5ServerEncoder(Socks5AddressEncoder.DEFAULT);
32 |
33 | private final Socks5AddressEncoder addressEncoder;
34 |
35 | /**
36 | * Creates a new instance with the default {@link Socks5AddressEncoder}.
37 | */
38 | protected Socks5ServerEncoder() {
39 | this(Socks5AddressEncoder.DEFAULT);
40 | }
41 |
42 | @Override
43 | protected Buffer allocateBuffer(ChannelHandlerContext ctx, Socks5Message msg) {
44 | return ctx.bufferAllocator().allocate(256);
45 | }
46 |
47 | /**
48 | * Creates a new instance with the specified {@link Socks5AddressEncoder}.
49 | */
50 | public Socks5ServerEncoder(Socks5AddressEncoder addressEncoder) {
51 | requireNonNull(addressEncoder, "addressEncoder");
52 |
53 | this.addressEncoder = addressEncoder;
54 | }
55 |
56 | /**
57 | * Returns the {@link Socks5AddressEncoder} of this encoder.
58 | */
59 | protected final Socks5AddressEncoder addressEncoder() {
60 | return addressEncoder;
61 | }
62 |
63 | @Override
64 | protected void encode(ChannelHandlerContext ctx, Socks5Message msg, Buffer out) throws Exception {
65 | if (msg instanceof Socks5InitialResponse) {
66 | encodeAuthMethodResponse((Socks5InitialResponse) msg, out);
67 | } else if (msg instanceof Socks5PasswordAuthResponse) {
68 | encodePasswordAuthResponse((Socks5PasswordAuthResponse) msg, out);
69 | } else if (msg instanceof Socks5CommandResponse) {
70 | encodeCommandResponse((Socks5CommandResponse) msg, out);
71 | } else {
72 | throw new EncoderException("unsupported message type: " + StringUtil.simpleClassName(msg));
73 | }
74 | }
75 |
76 | private static void encodeAuthMethodResponse(Socks5InitialResponse msg, Buffer out) {
77 | out.writeByte(msg.version().byteValue());
78 | out.writeByte(msg.authMethod().byteValue());
79 | }
80 |
81 | private static void encodePasswordAuthResponse(Socks5PasswordAuthResponse msg, Buffer out) {
82 | out.writeByte((byte) 0x01);
83 | out.writeByte(msg.status().byteValue());
84 | }
85 |
86 | private void encodeCommandResponse(Socks5CommandResponse msg, Buffer out) throws Exception {
87 | out.writeByte(msg.version().byteValue());
88 | out.writeByte(msg.status().byteValue());
89 | out.writeByte((byte) 0x00);
90 |
91 | final Socks5AddressType bndAddrType = msg.bndAddrType();
92 | out.writeByte(bndAddrType.byteValue());
93 | addressEncoder.encodeAddress(bndAddrType, msg.bndAddr(), out);
94 |
95 | out.writeShort((short) msg.bndPort());
96 | }
97 |
98 | @Override
99 | public boolean isSharable() {
100 | return true;
101 | }
102 | }
103 |
--------------------------------------------------------------------------------