From 27bf5e3ac0562fad36877eebfa7504705297632e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 12 Jan 2021 04:16:32 -0800 Subject: [PATCH] Removing Deps updating Cargo for 0.1.0 Release --- .gitignore | 1 + .idea/.gitignore | 8 - .idea/misc.xml | 6 - .idea/modules.xml | 8 - .idea/tapir-rs.iml | 13 - .idea/vcs.xml | 6 - Cargo.toml | 6 +- deps/rust-socks/.circleci/config.yml | 42 -- deps/rust-socks/.circleci/danted_no_auth.conf | 17 - .../rust-socks/.circleci/danted_password.conf | 17 - deps/rust-socks/.gitignore | 4 - deps/rust-socks/Cargo.toml | 19 - deps/rust-socks/LICENSE-APACHE | 202 ------ deps/rust-socks/LICENSE-MIT | 19 - deps/rust-socks/README.md | 22 - deps/rust-socks/src/lib.rs | 158 ----- deps/rust-socks/src/v4.rs | 270 -------- deps/rust-socks/src/v5.rs | 627 ------------------ deps/rust-socks/src/writev.rs | 116 ---- 19 files changed, 3 insertions(+), 1558 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/tapir-rs.iml delete mode 100644 .idea/vcs.xml delete mode 100644 deps/rust-socks/.circleci/config.yml delete mode 100644 deps/rust-socks/.circleci/danted_no_auth.conf delete mode 100644 deps/rust-socks/.circleci/danted_password.conf delete mode 100644 deps/rust-socks/.gitignore delete mode 100644 deps/rust-socks/Cargo.toml delete mode 100644 deps/rust-socks/LICENSE-APACHE delete mode 100644 deps/rust-socks/LICENSE-MIT delete mode 100644 deps/rust-socks/README.md delete mode 100644 deps/rust-socks/src/lib.rs delete mode 100644 deps/rust-socks/src/v4.rs delete mode 100644 deps/rust-socks/src/v5.rs delete mode 100644 deps/rust-socks/src/writev.rs diff --git a/.gitignore b/.gitignore index 96ef6c0..026fb6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +.idea/* diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 73f69e0..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 38ff096..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/tapir-rs.iml b/.idea/tapir-rs.iml deleted file mode 100644 index 78dfac4..0000000 --- a/.idea/tapir-rs.iml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index ab162ce..6acce43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,13 +3,11 @@ name = "tapir" version = "0.1.0" authors = ["Sarah Jamie Lewis "] edition = "2018" +license = "MIT" +description = "Tapir is a small library for building p2p applications over anonymous communication systems" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[workspace] -members = ["deps/rust-socks"] - - [[test]] name = "simple_setup" diff --git a/deps/rust-socks/.circleci/config.yml b/deps/rust-socks/.circleci/config.yml deleted file mode 100644 index 1aa543e..0000000 --- a/deps/rust-socks/.circleci/config.yml +++ /dev/null @@ -1,42 +0,0 @@ -restore_registry: &RESTORE_REGISTRY - restore_cache: - key: registry -save_registry: &SAVE_REGISTRY - save_cache: - key: registry-{{ .BuildNum }} - paths: - - /usr/local/cargo/registry/index -deps_key: &DEPS_KEY - key: deps-{{ checksum "~/rust-version" }}-{{ checksum "Cargo.lock" }} -restore_deps: &RESTORE_DEPS - restore_cache: - <<: *DEPS_KEY -save_deps: &SAVE_DEPS - save_cache: - <<: *DEPS_KEY - paths: - - target - - /usr/local/cargo/registry/cache - -version: 2 -jobs: - build: - docker: - - image: rust:1.19.0 - working_directory: ~/build - environment: - RUSTFLAGS: -D warnings - steps: - - checkout - - run: apt-get update - - run: apt-get install -y --no-install-recommends dante-server - - run: danted -D -f .circleci/danted_no_auth.conf - - run: danted -D -f .circleci/danted_password.conf - - run: useradd testuser -p '$1$DLEVM6FQ$dNm6etLDprLfwWSLCUtQY/' # password: testpass - - *RESTORE_REGISTRY - - run: cargo generate-lockfile - - *SAVE_REGISTRY - - run: rustc --version > ~/rust-version - - *RESTORE_DEPS - - run: cargo test - - *SAVE_DEPS diff --git a/deps/rust-socks/.circleci/danted_no_auth.conf b/deps/rust-socks/.circleci/danted_no_auth.conf deleted file mode 100644 index 1789ec2..0000000 --- a/deps/rust-socks/.circleci/danted_no_auth.conf +++ /dev/null @@ -1,17 +0,0 @@ -logoutput: stdout - -internal: lo port = 1080 -external: eth0 - -socksmethod: none -clientmethod: none - -user.unprivileged: nobody - -client pass { - from: 127.0.0.1/0 port 1-65535 to: 0.0.0.0/0 -} - -socks pass { - from: 127.0.0.1/0 to: 0.0.0.0/0 -} diff --git a/deps/rust-socks/.circleci/danted_password.conf b/deps/rust-socks/.circleci/danted_password.conf deleted file mode 100644 index 43ace3c..0000000 --- a/deps/rust-socks/.circleci/danted_password.conf +++ /dev/null @@ -1,17 +0,0 @@ -logoutput: stdout - -internal: lo port = 1081 -external: eth0 - -socksmethod: username -clientmethod: none - -user.unprivileged: nobody - -client pass { - from: 127.0.0.1/0 port 1-65535 to: 0.0.0.0/0 -} - -socks pass { - from: 127.0.0.1/0 to: 0.0.0.0/0 -} diff --git a/deps/rust-socks/.gitignore b/deps/rust-socks/.gitignore deleted file mode 100644 index 3b874ca..0000000 --- a/deps/rust-socks/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -target -Cargo.lock -.idea -*.iml diff --git a/deps/rust-socks/Cargo.toml b/deps/rust-socks/Cargo.toml deleted file mode 100644 index e233fc9..0000000 --- a/deps/rust-socks/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "socks" -version = "0.3.2" -authors = ["Steven Fackler "] -license = "MIT/Apache-2.0" -description = "SOCKS proxy clients" -repository = "https://github.com/sfackler/rust-socks" -documentation = "https://docs.rs/socks/0.3.0/socks" -readme = "README.md" - -[dependencies] -byteorder = "1.0" - -[target.'cfg(unix)'.dependencies] -libc = "0.2" - -[target.'cfg(windows)'.dependencies] -winapi = "0.2.8" -ws2_32-sys = "0.2.1" diff --git a/deps/rust-socks/LICENSE-APACHE b/deps/rust-socks/LICENSE-APACHE deleted file mode 100644 index 8f71f43..0000000 --- a/deps/rust-socks/LICENSE-APACHE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/deps/rust-socks/LICENSE-MIT b/deps/rust-socks/LICENSE-MIT deleted file mode 100644 index e8b0041..0000000 --- a/deps/rust-socks/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 The rust-socks Developers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/rust-socks/README.md b/deps/rust-socks/README.md deleted file mode 100644 index d53cc3b..0000000 --- a/deps/rust-socks/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# rust-socks -[![Build Status](https://travis-ci.org/sfackler/rust-socks.svg?branch=master)](https://travis-ci.org/sfackler/rust-socks) - -[Documentation](https://docs.rs/socks/0.2.3/socks) - -SOCKS proxy support for Rust. - -## License - -Licensed under either of - - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally -submitted for inclusion in the work by you, as defined in the Apache-2.0 -license, shall be dual licensed as above, without any additional terms or -conditions. diff --git a/deps/rust-socks/src/lib.rs b/deps/rust-socks/src/lib.rs deleted file mode 100644 index 6c07649..0000000 --- a/deps/rust-socks/src/lib.rs +++ /dev/null @@ -1,158 +0,0 @@ -//! SOCKS proxy clients -#![doc(html_root_url = "https://docs.rs/socks/0.3.0")] -#![warn(missing_docs)] - -extern crate byteorder; - -#[cfg(unix)] -extern crate libc; -#[cfg(windows)] -extern crate winapi; -#[cfg(windows)] -extern crate ws2_32; - -use std::io; -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; -use std::vec; - -pub use v4::{Socks4Listener, Socks4Stream}; -pub use v5::{Socks5Datagram, Socks5Listener, Socks5Stream}; - -mod v4; -mod v5; -mod writev; - -/// A description of a connection target. -#[derive(Debug, Clone)] -pub enum TargetAddr { - /// Connect to an IP address. - Ip(SocketAddr), - /// Connect to a fully qualified domain name. - /// - /// The domain name will be passed along to the proxy server and DNS lookup - /// will happen there. - Domain(String, u16), -} - -impl ToSocketAddrs for TargetAddr { - type Iter = Iter; - - fn to_socket_addrs(&self) -> io::Result { - let inner = match *self { - TargetAddr::Ip(addr) => IterInner::Ip(Some(addr)), - TargetAddr::Domain(ref domain, port) => { - let it = (&**domain, port).to_socket_addrs()?; - IterInner::Domain(it) - } - }; - Ok(Iter(inner)) - } -} - -enum IterInner { - Ip(Option), - Domain(vec::IntoIter), -} - -/// An iterator over `SocketAddr`s associated with a `TargetAddr`. -pub struct Iter(IterInner); - -impl Iterator for Iter { - type Item = SocketAddr; - - fn next(&mut self) -> Option { - match self.0 { - IterInner::Ip(ref mut addr) => addr.take(), - IterInner::Domain(ref mut it) => it.next(), - } - } -} - -/// A trait for objects that can be converted to `TargetAddr`. -pub trait ToTargetAddr { - /// Converts the value of `self` to a `TargetAddr`. - fn to_target_addr(&self) -> io::Result; -} - -impl ToTargetAddr for TargetAddr { - fn to_target_addr(&self) -> io::Result { - Ok(self.clone()) - } -} - -impl ToTargetAddr for SocketAddr { - fn to_target_addr(&self) -> io::Result { - Ok(TargetAddr::Ip(*self)) - } -} - -impl ToTargetAddr for SocketAddrV4 { - fn to_target_addr(&self) -> io::Result { - SocketAddr::V4(*self).to_target_addr() - } -} - -impl ToTargetAddr for SocketAddrV6 { - fn to_target_addr(&self) -> io::Result { - SocketAddr::V6(*self).to_target_addr() - } -} - -impl ToTargetAddr for (Ipv4Addr, u16) { - fn to_target_addr(&self) -> io::Result { - SocketAddrV4::new(self.0, self.1).to_target_addr() - } -} - -impl ToTargetAddr for (Ipv6Addr, u16) { - fn to_target_addr(&self) -> io::Result { - SocketAddrV6::new(self.0, self.1, 0, 0).to_target_addr() - } -} - -impl<'a> ToTargetAddr for (&'a str, u16) { - fn to_target_addr(&self) -> io::Result { - // try to parse as an IP first - if let Ok(addr) = self.0.parse::() { - return (addr, self.1).to_target_addr(); - } - - if let Ok(addr) = self.0.parse::() { - return (addr, self.1).to_target_addr(); - } - - Ok(TargetAddr::Domain(self.0.to_owned(), self.1)) - } -} - -impl<'a> ToTargetAddr for &'a str { - fn to_target_addr(&self) -> io::Result { - // try to parse as an IP first - if let Ok(addr) = self.parse::() { - return addr.to_target_addr(); - } - - if let Ok(addr) = self.parse::() { - return addr.to_target_addr(); - } - - // split the string by ':' and convert the second part to u16 - let mut parts_iter = self.rsplitn(2, ':'); - let port_str = match parts_iter.next() { - Some(s) => s, - None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address")), - }; - - let host = match parts_iter.next() { - Some(s) => s, - None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid socket address")), - }; - - let port: u16 = match port_str.parse() { - Ok(p) => p, - Err(_) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid port value")), - }; - - (host, port).to_target_addr() - } -} diff --git a/deps/rust-socks/src/v4.rs b/deps/rust-socks/src/v4.rs deleted file mode 100644 index 0378367..0000000 --- a/deps/rust-socks/src/v4.rs +++ /dev/null @@ -1,270 +0,0 @@ -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use std::io::{self, Read, Write}; -use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, SocketAddrV6, TcpStream, ToSocketAddrs}; - -use {TargetAddr, ToTargetAddr}; - -fn read_response(socket: &mut TcpStream) -> io::Result { - let mut response = [0u8; 8]; - socket.read_exact(&mut response)?; - let mut response = &response[..]; - - if response.read_u8()? != 0 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid response version")); - } - - match response.read_u8()? { - 90 => {} - 91 => return Err(io::Error::new(io::ErrorKind::Other, "request rejected or failed")), - 92 => { - return Err(io::Error::new( - io::ErrorKind::PermissionDenied, - "request rejected because SOCKS server cannot connect to \ - idnetd on the client", - )) - } - 93 => { - return Err(io::Error::new( - io::ErrorKind::PermissionDenied, - "request rejected because the client program and identd \ - report different user-ids", - )) - } - _ => return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid response code")), - } - - let port = response.read_u16::()?; - let ip = Ipv4Addr::from(response.read_u32::()?); - - Ok(SocketAddrV4::new(ip, port)) -} - -/// A SOCKS4 client. -#[derive(Debug)] -pub struct Socks4Stream { - socket: TcpStream, - proxy_addr: SocketAddrV4, -} - -impl Socks4Stream { - /// Connects to a target server through a SOCKS4 proxy. - /// - /// # Note - /// - /// If `target` is a `TargetAddr::Domain`, the domain name will be forwarded - /// to the proxy server using the SOCKS4A protocol extension. If the proxy - /// server does not support SOCKS4A, consider performing the DNS lookup - /// locally and passing a `TargetAddr::Ip`. - pub fn connect(proxy: T, target: U, userid: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - Self::connect_raw(1, proxy, target, userid) - } - - fn connect_raw(command: u8, proxy: T, target: U, userid: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - let mut socket = TcpStream::connect(proxy)?; - - let target = target.to_target_addr()?; - - let mut packet = vec![]; - let _ = packet.write_u8(4); // version - let _ = packet.write_u8(command); // command code - match target.to_target_addr()? { - TargetAddr::Ip(addr) => { - let addr = match addr { - SocketAddr::V4(addr) => addr, - SocketAddr::V6(_) => { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "SOCKS4 does not support IPv6")); - } - }; - let _ = packet.write_u16::(addr.port()); - let _ = packet.write_u32::((*addr.ip()).into()); - let _ = packet.write_all(userid.as_bytes()); - let _ = packet.write_u8(0); - } - TargetAddr::Domain(ref host, port) => { - let _ = packet.write_u16::(port); - let _ = packet.write_u32::(Ipv4Addr::new(0, 0, 0, 1).into()); - let _ = packet.write_all(userid.as_bytes()); - let _ = packet.write_u8(0); - let _ = packet.extend(host.as_bytes()); - let _ = packet.write_u8(0); - } - } - - socket.write_all(&packet)?; - let proxy_addr = read_response(&mut socket)?; - - Ok(Socks4Stream { - socket: socket, - proxy_addr: proxy_addr, - }) - } - - /// Returns the proxy-side address of the connection between the proxy and - /// target server. - pub fn proxy_addr(&self) -> SocketAddrV4 { - self.proxy_addr - } - - /// Returns a shared reference to the inner `TcpStream`. - pub fn get_ref(&self) -> &TcpStream { - &self.socket - } - - /// Returns a mutable reference to the inner `TcpStream`. - pub fn get_mut(&mut self) -> &mut TcpStream { - &mut self.socket - } - - /// Consumes the `Socks4Stream`, returning the inner `TcpStream`. - pub fn into_inner(self) -> TcpStream { - self.socket - } -} - -impl Read for Socks4Stream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.socket.read(buf) - } -} - -impl<'a> Read for &'a Socks4Stream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (&self.socket).read(buf) - } -} - -impl Write for Socks4Stream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.socket.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.socket.flush() - } -} - -impl<'a> Write for &'a Socks4Stream { - fn write(&mut self, buf: &[u8]) -> io::Result { - (&self.socket).write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - (&self.socket).flush() - } -} - -/// A SOCKS4 BIND client. -#[derive(Debug)] -pub struct Socks4Listener(Socks4Stream); - -impl Socks4Listener { - /// Initiates a BIND request to the specified proxy. - /// - /// The proxy will filter incoming connections based on the value of - /// `target`. - pub fn bind(proxy: T, target: U, userid: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - Socks4Stream::connect_raw(2, proxy, target, userid).map(Socks4Listener) - } - - /// The address of the proxy-side TCP listener. - /// - /// This should be forwarded to the remote process, which should open a - /// connection to it. - pub fn proxy_addr(&self) -> io::Result { - if self.0.proxy_addr.ip().octets() != [0, 0, 0, 0] { - Ok(SocketAddr::V4(self.0.proxy_addr())) - } else { - let port = self.0.proxy_addr.port(); - let peer = match self.0.socket.peer_addr()? { - SocketAddr::V4(addr) => SocketAddr::V4(SocketAddrV4::new(*addr.ip(), port)), - SocketAddr::V6(addr) => SocketAddr::V6(SocketAddrV6::new(*addr.ip(), port, 0, 0)), - }; - Ok(peer) - } - } - - /// Waits for the remote process to connect to the proxy server. - /// - /// The value of `proxy_addr` should be forwarded to the remote process - /// before this method is called. - pub fn accept(mut self) -> io::Result { - self.0.proxy_addr = read_response(&mut self.0.socket)?; - Ok(self.0) - } -} - -#[cfg(test)] -mod test { - use std::io::{Read, Write}; - use std::net::{SocketAddr, SocketAddrV4, TcpStream, ToSocketAddrs}; - - use super::*; - - fn google_ip() -> SocketAddrV4 { - "google.com:80" - .to_socket_addrs() - .unwrap() - .filter_map(|a| match a { - SocketAddr::V4(a) => Some(a), - SocketAddr::V6(_) => None, - }) - .next() - .unwrap() - } - - #[test] - fn google() { - let mut socket = Socks4Stream::connect("127.0.0.1:1080", google_ip(), "").unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); - } - - #[test] - #[ignore] // dante doesn't support SOCKS4A - fn google_dns() { - let mut socket = Socks4Stream::connect("127.0.0.1:8080", "google.com:80", "").unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); - } - - #[test] - fn bind() { - // First figure out our local address that we'll be connecting from - let socket = Socks4Stream::connect("127.0.0.1:1080", google_ip(), "").unwrap(); - let addr = socket.proxy_addr(); - - let listener = Socks4Listener::bind("127.0.0.1:1080", addr, "").unwrap(); - let addr = listener.proxy_addr().unwrap(); - let mut end = TcpStream::connect(addr).unwrap(); - let mut conn = listener.accept().unwrap(); - conn.write_all(b"hello world").unwrap(); - drop(conn); - let mut result = vec![]; - end.read_to_end(&mut result).unwrap(); - assert_eq!(result, b"hello world"); - } -} diff --git a/deps/rust-socks/src/v5.rs b/deps/rust-socks/src/v5.rs deleted file mode 100644 index 44633bf..0000000 --- a/deps/rust-socks/src/v5.rs +++ /dev/null @@ -1,627 +0,0 @@ -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use std::cmp; -use std::io::{self, Read, Write}; -use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, TcpStream, ToSocketAddrs, UdpSocket}; -use std::ptr; - -use writev::WritevExt; -use {TargetAddr, ToTargetAddr}; - -const MAX_ADDR_LEN: usize = 260; - -fn read_addr(socket: &mut R) -> io::Result { - match socket.read_u8()? { - 1 => { - let ip = Ipv4Addr::from(socket.read_u32::()?); - let port = socket.read_u16::()?; - Ok(TargetAddr::Ip(SocketAddr::V4(SocketAddrV4::new(ip, port)))) - } - 3 => { - let len = socket.read_u8()?; - let mut domain = vec![0; len as usize]; - socket.read_exact(&mut domain)?; - let domain = String::from_utf8(domain).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; - let port = socket.read_u16::()?; - Ok(TargetAddr::Domain(domain, port)) - } - 4 => { - let mut ip = [0; 16]; - socket.read_exact(&mut ip)?; - let ip = Ipv6Addr::from(ip); - let port = socket.read_u16::()?; - Ok(TargetAddr::Ip(SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)))) - } - _ => Err(io::Error::new(io::ErrorKind::Other, "unsupported address type")), - } -} - -fn read_response(socket: &mut TcpStream) -> io::Result { - if socket.read_u8()? != 5 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid response version")); - } - - match socket.read_u8()? { - 0 => {} - 1 => return Err(io::Error::new(io::ErrorKind::Other, "general SOCKS server failure")), - 2 => return Err(io::Error::new(io::ErrorKind::Other, "connection not allowed by ruleset")), - 3 => return Err(io::Error::new(io::ErrorKind::Other, "network unreachable")), - 4 => return Err(io::Error::new(io::ErrorKind::Other, "host unreachable")), - 5 => return Err(io::Error::new(io::ErrorKind::Other, "connection refused")), - 6 => return Err(io::Error::new(io::ErrorKind::Other, "TTL expired")), - 7 => return Err(io::Error::new(io::ErrorKind::Other, "command not supported")), - 8 => return Err(io::Error::new(io::ErrorKind::Other, "address kind not supported")), - _ => return Err(io::Error::new(io::ErrorKind::Other, "unknown error")), - } - - if socket.read_u8()? != 0 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid reserved byte")); - } - - read_addr(socket) -} - -fn write_addr(mut packet: &mut [u8], target: &TargetAddr) -> io::Result { - let start_len = packet.len(); - match *target { - TargetAddr::Ip(SocketAddr::V4(addr)) => { - packet.write_u8(1).unwrap(); - packet.write_u32::((*addr.ip()).into()).unwrap(); - packet.write_u16::(addr.port()).unwrap(); - } - TargetAddr::Ip(SocketAddr::V6(addr)) => { - packet.write_u8(4).unwrap(); - packet.write_all(&addr.ip().octets()).unwrap(); - packet.write_u16::(addr.port()).unwrap(); - } - TargetAddr::Domain(ref domain, port) => { - packet.write_u8(3).unwrap(); - if domain.len() > u8::max_value() as usize { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "domain name too long")); - } - packet.write_u8(domain.len() as u8).unwrap(); - packet.write_all(domain.as_bytes()).unwrap(); - packet.write_u16::(port).unwrap(); - } - } - - Ok(start_len - packet.len()) -} - -/// Authentication methods -#[derive(Debug)] -enum Authentication<'a> { - Password { username: &'a str, password: &'a str }, - None, -} - -impl<'a> Authentication<'a> { - fn id(&self) -> u8 { - match *self { - Authentication::Password { .. } => 2, - Authentication::None => 0, - } - } - - fn is_no_auth(&self) -> bool { - if let Authentication::None = *self { - true - } else { - false - } - } -} - -/// A SOCKS5 client. -#[derive(Debug)] -pub struct Socks5Stream { - socket: TcpStream, - proxy_addr: TargetAddr, -} - -impl Socks5Stream { - /// Connects to a target server through a SOCKS5 proxy. - pub fn connect(proxy: T, target: U) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - Self::connect_raw(1, proxy, target, &Authentication::None) - } - - /// Connects to a target server through a SOCKS5 proxy using given - /// username and password. - pub fn connect_with_password(proxy: T, target: U, username: &str, password: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - let auth = Authentication::Password { username, password }; - Self::connect_raw(1, proxy, target, &auth) - } - - fn connect_raw(command: u8, proxy: T, target: U, auth: &Authentication) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - let mut socket = TcpStream::connect(proxy)?; - - let target = target.to_target_addr()?; - - let packet_len = if auth.is_no_auth() { 3 } else { 4 }; - let packet = [ - 5, // protocol version - if auth.is_no_auth() { 1 } else { 2 }, // method count - auth.id(), // method - 0, // no auth (always offered) - ]; - socket.write_all(&packet[..packet_len])?; - - let mut buf = [0; 2]; - socket.read_exact(&mut buf)?; - let response_version = buf[0]; - let selected_method = buf[1]; - - if response_version != 5 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid response version")); - } - - if selected_method == 0xff { - return Err(io::Error::new(io::ErrorKind::Other, "no acceptable auth methods")); - } - - if selected_method != auth.id() && selected_method != Authentication::None.id() { - return Err(io::Error::new(io::ErrorKind::Other, "unknown auth method")); - } - - match *auth { - Authentication::Password { username, password } if selected_method == auth.id() => Self::password_authentication(&mut socket, username, password)?, - _ => (), - } - - let mut packet = [0; MAX_ADDR_LEN + 3]; - packet[0] = 5; // protocol version - packet[1] = command; // command - packet[2] = 0; // reserved - let len = write_addr(&mut packet[3..], &target)?; - socket.write_all(&packet[..len + 3])?; - - let proxy_addr = read_response(&mut socket)?; - - Ok(Socks5Stream { - socket: socket, - proxy_addr: proxy_addr, - }) - } - - fn password_authentication(socket: &mut TcpStream, username: &str, password: &str) -> io::Result<()> { - if username.len() < 1 || username.len() > 255 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid username")); - }; - if password.len() < 1 || password.len() > 255 { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "invalid password")); - } - - let mut packet = [0; 515]; - let packet_size = 3 + username.len() + password.len(); - packet[0] = 1; // version - packet[1] = username.len() as u8; - packet[2..2 + username.len()].copy_from_slice(username.as_bytes()); - packet[2 + username.len()] = password.len() as u8; - packet[3 + username.len()..packet_size].copy_from_slice(password.as_bytes()); - socket.write_all(&packet[..packet_size])?; - - let mut buf = [0; 2]; - socket.read_exact(&mut buf)?; - if buf[0] != 1 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid response version")); - } - if buf[1] != 0 { - return Err(io::Error::new(io::ErrorKind::PermissionDenied, "password authentication failed")); - } - - Ok(()) - } - - /// Returns the proxy-side address of the connection between the proxy and - /// target server. - pub fn proxy_addr(&self) -> &TargetAddr { - &self.proxy_addr - } - - /// Returns a shared reference to the inner `TcpStream`. - pub fn get_ref(&self) -> &TcpStream { - &self.socket - } - - /// Returns a mutable reference to the inner `TcpStream`. - pub fn get_mut(&mut self) -> &mut TcpStream { - &mut self.socket - } - - /// Consumes the `Socks5Stream`, returning the inner `TcpStream`. - pub fn into_inner(self) -> TcpStream { - self.socket - } -} - -impl Read for Socks5Stream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.socket.read(buf) - } -} - -impl<'a> Read for &'a Socks5Stream { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (&self.socket).read(buf) - } -} - -impl Write for Socks5Stream { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.socket.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.socket.flush() - } -} - -impl<'a> Write for &'a Socks5Stream { - fn write(&mut self, buf: &[u8]) -> io::Result { - (&self.socket).write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - (&self.socket).flush() - } -} - -/// A SOCKS5 BIND client. -#[derive(Debug)] -pub struct Socks5Listener(Socks5Stream); - -impl Socks5Listener { - /// Initiates a BIND request to the specified proxy. - /// - /// The proxy will filter incoming connections based on the value of - /// `target`. - pub fn bind(proxy: T, target: U) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - Socks5Stream::connect_raw(2, proxy, target, &Authentication::None).map(Socks5Listener) - } - /// Initiates a BIND request to the specified proxy using given username - /// and password. - /// - /// The proxy will filter incoming connections based on the value of - /// `target`. - pub fn bind_with_password(proxy: T, target: U, username: &str, password: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToTargetAddr, - { - let auth = Authentication::Password { username, password }; - Socks5Stream::connect_raw(2, proxy, target, &auth).map(Socks5Listener) - } - - /// The address of the proxy-side TCP listener. - /// - /// This should be forwarded to the remote process, which should open a - /// connection to it. - pub fn proxy_addr(&self) -> &TargetAddr { - &self.0.proxy_addr - } - - /// Waits for the remote process to connect to the proxy server. - /// - /// The value of `proxy_addr` should be forwarded to the remote process - /// before this method is called. - pub fn accept(mut self) -> io::Result { - self.0.proxy_addr = read_response(&mut self.0.socket)?; - Ok(self.0) - } -} - -/// A SOCKS5 UDP client. -#[derive(Debug)] -pub struct Socks5Datagram { - socket: UdpSocket, - // keeps the session alive - stream: Socks5Stream, -} - -impl Socks5Datagram { - /// Creates a UDP socket bound to the specified address which will have its - /// traffic routed through the specified proxy. - pub fn bind(proxy: T, addr: U) -> io::Result - where - T: ToSocketAddrs, - U: ToSocketAddrs, - { - Self::bind_internal(proxy, addr, &Authentication::None) - } - /// Creates a UDP socket bound to the specified address which will have its - /// traffic routed through the specified proxy. The given username and password - /// is used to authenticate to the SOCKS proxy. - pub fn bind_with_password(proxy: T, addr: U, username: &str, password: &str) -> io::Result - where - T: ToSocketAddrs, - U: ToSocketAddrs, - { - let auth = Authentication::Password { username, password }; - Self::bind_internal(proxy, addr, &auth) - } - - fn bind_internal(proxy: T, addr: U, auth: &Authentication) -> io::Result - where - T: ToSocketAddrs, - U: ToSocketAddrs, - { - // we don't know what our IP is from the perspective of the proxy, so - // don't try to pass `addr` in here. - let dst = TargetAddr::Ip(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0))); - let stream = Socks5Stream::connect_raw(3, proxy, dst, auth)?; - - let socket = UdpSocket::bind(addr)?; - socket.connect(&stream.proxy_addr)?; - - Ok(Socks5Datagram { socket: socket, stream: stream }) - } - - /// Like `UdpSocket::send_to`. - /// - /// # Note - /// - /// The SOCKS protocol inserts a header at the beginning of the message. The - /// header will be 10 bytes for an IPv4 address, 22 bytes for an IPv6 - /// address, and 7 bytes plus the length of the domain for a domain address. - pub fn send_to(&self, buf: &[u8], addr: A) -> io::Result - where - A: ToTargetAddr, - { - let addr = addr.to_target_addr()?; - - let mut header = [0; MAX_ADDR_LEN + 3]; - // first two bytes are reserved at 0 - // third byte is the fragment id at 0 - let len = write_addr(&mut header[3..], &addr)?; - - self.socket.writev([&header[..len + 3], buf]) - } - - /// Like `UdpSocket::recv_from`. - pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, TargetAddr)> { - let mut header = [0; MAX_ADDR_LEN + 3]; - let len = self.socket.readv([&mut header, buf])?; - - let overflow = len.saturating_sub(header.len()); - - let header_len = cmp::min(header.len(), len); - let mut header = &mut &header[..header_len]; - - if header.read_u16::()? != 0 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid reserved bytes")); - } - if header.read_u8()? != 0 { - return Err(io::Error::new(io::ErrorKind::InvalidData, "invalid fragment id")); - } - let addr = read_addr(&mut header)?; - - unsafe { - ptr::copy(buf.as_ptr(), buf.as_mut_ptr().offset(header.len() as isize), overflow); - } - buf[..header.len()].copy_from_slice(header); - - Ok((header.len() + overflow, addr)) - } - - /// Returns the address of the proxy-side UDP socket through which all - /// messages will be routed. - pub fn proxy_addr(&self) -> &TargetAddr { - &self.stream.proxy_addr - } - - /// Returns a shared reference to the inner socket. - pub fn get_ref(&self) -> &UdpSocket { - &self.socket - } - - /// Returns a mutable reference to the inner socket. - pub fn get_mut(&mut self) -> &mut UdpSocket { - &mut self.socket - } -} - -#[cfg(test)] -mod test { - use std::error::Error; - use std::io::{Read, Write}; - use std::net::{TcpStream, ToSocketAddrs, UdpSocket}; - - use super::*; - - const SOCKS_PROXY_NO_AUTH_ONLY: &str = "127.0.0.1:1080"; - const SOCKS_PROXY_PASSWD_ONLY: &str = "127.0.0.1:1081"; - - #[test] - fn google_no_auth() { - let addr = "google.com:80".to_socket_addrs().unwrap().next().unwrap(); - let socket = Socks5Stream::connect(SOCKS_PROXY_NO_AUTH_ONLY, addr).unwrap(); - google(socket); - } - - #[test] - fn google_with_password() { - let addr = "google.com:80".to_socket_addrs().unwrap().next().unwrap(); - let socket = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, "testuser", "testpass").unwrap(); - google(socket); - } - - fn google(mut socket: Socks5Stream) { - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); - } - - #[test] - fn google_dns() { - let mut socket = Socks5Stream::connect(SOCKS_PROXY_NO_AUTH_ONLY, "google.com:80").unwrap(); - - socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap(); - let mut result = vec![]; - socket.read_to_end(&mut result).unwrap(); - - println!("{}", String::from_utf8_lossy(&result)); - assert!(result.starts_with(b"HTTP/1.0")); - assert!(result.ends_with(b"\r\n") || result.ends_with(b"")); - } - - #[test] - fn bind_no_auth() { - let addr = find_address(); - let listener = Socks5Listener::bind(SOCKS_PROXY_NO_AUTH_ONLY, addr).unwrap(); - bind(listener); - } - - #[test] - fn bind_with_password_supported_but_no_auth_used() { - let addr = find_address(); - let listener = Socks5Listener::bind_with_password(SOCKS_PROXY_NO_AUTH_ONLY, addr, "unused_and_invalid_username", "unused_and_invalid_password").unwrap(); - bind(listener); - } - - #[test] - fn bind_with_password() { - let addr = find_address(); - let listener = Socks5Listener::bind_with_password("127.0.0.1:1081", addr, "testuser", "testpass").unwrap(); - bind(listener); - } - - fn bind(listener: Socks5Listener) { - let addr = listener.proxy_addr().clone(); - let mut end = TcpStream::connect(addr).unwrap(); - let mut conn = listener.accept().unwrap(); - conn.write_all(b"hello world").unwrap(); - drop(conn); - let mut result = vec![]; - end.read_to_end(&mut result).unwrap(); - assert_eq!(result, b"hello world"); - } - - // First figure out our local address that we'll be connecting from - fn find_address() -> TargetAddr { - let socket = Socks5Stream::connect(SOCKS_PROXY_NO_AUTH_ONLY, "google.com:80").unwrap(); - socket.proxy_addr().to_owned() - } - - #[test] - fn associate_no_auth() { - let socks = Socks5Datagram::bind(SOCKS_PROXY_NO_AUTH_ONLY, "127.0.0.1:15410").unwrap(); - associate(socks, "127.0.0.1:15411"); - } - - #[test] - fn associate_with_password() { - let socks = Socks5Datagram::bind_with_password(SOCKS_PROXY_PASSWD_ONLY, "127.0.0.1:15414", "testuser", "testpass").unwrap(); - associate(socks, "127.0.0.1:15415"); - } - - fn associate(socks: Socks5Datagram, socket_addr: &str) { - let socket = UdpSocket::bind(socket_addr).unwrap(); - - socks.send_to(b"hello world!", socket_addr).unwrap(); - let mut buf = [0; 13]; - let (len, addr) = socket.recv_from(&mut buf).unwrap(); - assert_eq!(len, 12); - assert_eq!(&buf[..12], b"hello world!"); - - socket.send_to(b"hello world!", addr).unwrap(); - - let len = socks.recv_from(&mut buf).unwrap().0; - assert_eq!(len, 12); - assert_eq!(&buf[..12], b"hello world!"); - } - - #[test] - fn associate_long() { - let socks = Socks5Datagram::bind(SOCKS_PROXY_NO_AUTH_ONLY, "127.0.0.1:15412").unwrap(); - let socket_addr = "127.0.0.1:15413"; - let socket = UdpSocket::bind(socket_addr).unwrap(); - - let mut msg = vec![]; - for i in 0..(MAX_ADDR_LEN + 100) { - msg.push(i as u8); - } - - socks.send_to(&msg, socket_addr).unwrap(); - let mut buf = vec![0; msg.len() + 1]; - let (len, addr) = socket.recv_from(&mut buf).unwrap(); - assert_eq!(len, msg.len()); - assert_eq!(msg, &buf[..msg.len()]); - - socket.send_to(&msg, addr).unwrap(); - - let mut buf = vec![0; msg.len() + 1]; - let len = socks.recv_from(&mut buf).unwrap().0; - assert_eq!(len, msg.len()); - assert_eq!(msg, &buf[..msg.len()]); - } - - #[test] - fn incorrect_password() { - let addr = "google.com:80".to_socket_addrs().unwrap().next().unwrap(); - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, "testuser", "invalid").unwrap_err(); - - assert_eq!(err.kind(), io::ErrorKind::PermissionDenied); - assert_eq!(err.description(), "password authentication failed"); - } - - #[test] - fn auth_method_not_supported() { - let addr = "google.com:80".to_socket_addrs().unwrap().next().unwrap(); - let err = Socks5Stream::connect(SOCKS_PROXY_PASSWD_ONLY, addr).unwrap_err(); - - assert_eq!(err.kind(), io::ErrorKind::Other); - assert_eq!(err.description(), "no acceptable auth methods"); - } - - #[test] - fn username_and_password_length() { - let addr = "google.com:80".to_socket_addrs().unwrap().next().unwrap(); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(1), &string_of_size(1)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::PermissionDenied); - assert_eq!(err.description(), "password authentication failed"); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(255), &string_of_size(255)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::PermissionDenied); - assert_eq!(err.description(), "password authentication failed"); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(0), &string_of_size(255)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::InvalidInput); - assert_eq!(err.description(), "invalid username"); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(256), &string_of_size(255)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::InvalidInput); - assert_eq!(err.description(), "invalid username"); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(255), &string_of_size(0)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::InvalidInput); - assert_eq!(err.description(), "invalid password"); - - let err = Socks5Stream::connect_with_password(SOCKS_PROXY_PASSWD_ONLY, addr, &string_of_size(255), &string_of_size(256)).unwrap_err(); - assert_eq!(err.kind(), io::ErrorKind::InvalidInput); - assert_eq!(err.description(), "invalid password"); - } - - fn string_of_size(size: usize) -> String { - (0..size).map(|_| 'x').collect() - } -} diff --git a/deps/rust-socks/src/writev.rs b/deps/rust-socks/src/writev.rs deleted file mode 100644 index 95ab98e..0000000 --- a/deps/rust-socks/src/writev.rs +++ /dev/null @@ -1,116 +0,0 @@ -use std::io; -use std::net::UdpSocket; - -pub trait WritevExt { - fn writev(&self, bufs: [&[u8]; 2]) -> io::Result; - fn readv(&self, bufs: [&mut [u8]; 2]) -> io::Result; -} - -#[cfg(unix)] -mod imp { - use libc; - use std::os::unix::io::AsRawFd; - - use super::*; - - impl WritevExt for UdpSocket { - fn writev(&self, bufs: [&[u8]; 2]) -> io::Result { - unsafe { - let iovecs = [ - libc::iovec { - iov_base: bufs[0].as_ptr() as *const _ as *mut _, - iov_len: bufs[0].len(), - }, - libc::iovec { - iov_base: bufs[1].as_ptr() as *const _ as *mut _, - iov_len: bufs[1].len(), - }, - ]; - let r = libc::writev(self.as_raw_fd(), iovecs.as_ptr(), 2); - if r < 0 { - Err(io::Error::last_os_error()) - } else { - Ok(r as usize) - } - } - } - - fn readv(&self, bufs: [&mut [u8]; 2]) -> io::Result { - unsafe { - let mut iovecs = [ - libc::iovec { - iov_base: bufs[0].as_mut_ptr() as *mut _, - iov_len: bufs[0].len(), - }, - libc::iovec { - iov_base: bufs[1].as_mut_ptr() as *mut _, - iov_len: bufs[1].len(), - }, - ]; - let r = libc::readv(self.as_raw_fd(), iovecs.as_mut_ptr(), 2); - if r < 0 { - Err(io::Error::last_os_error()) - } else { - Ok(r as usize) - } - } - } - } -} - -#[cfg(windows)] -mod imp { - use std::os::windows::io::AsRawSocket; - use std::ptr; - use winapi; - use ws2_32; - - use super::*; - - impl WritevExt for UdpSocket { - fn writev(&self, bufs: [&[u8]; 2]) -> io::Result { - unsafe { - let mut wsabufs = [ - winapi::WSABUF { - len: bufs[0].len() as winapi::u_long, - buf: bufs[0].as_ptr() as *const _ as *mut _, - }, - winapi::WSABUF { - len: bufs[1].len() as winapi::u_long, - buf: bufs[1].as_ptr() as *const _ as *mut _, - }, - ]; - let mut sent = 0; - let r = ws2_32::WSASend(self.as_raw_socket(), wsabufs.as_mut_ptr(), bufs.len() as winapi::DWORD, &mut sent, 0, ptr::null_mut(), None); - if r == 0 { - Ok(sent as usize) - } else { - Err(io::Error::last_os_error()) - } - } - } - - fn readv(&self, bufs: [&mut [u8]; 2]) -> io::Result { - unsafe { - let mut wsabufs = [ - winapi::WSABUF { - len: bufs[0].len() as winapi::u_long, - buf: bufs[0].as_mut_ptr() as *mut _, - }, - winapi::WSABUF { - len: bufs[1].len() as winapi::u_long, - buf: bufs[1].as_mut_ptr() as *mut _, - }, - ]; - let mut recved = 0; - let mut flags = 0; - let r = ws2_32::WSARecv(self.as_raw_socket(), wsabufs.as_mut_ptr(), bufs.len() as winapi::DWORD, &mut recved, &mut flags, ptr::null_mut(), None); - if r == 0 { - Ok(recved as usize) - } else { - Err(io::Error::last_os_error()) - } - } - } - } -}