Skip to content

Commit

Permalink
Add authorized user list
Browse files Browse the repository at this point in the history
  • Loading branch information
Jackarain committed Oct 18, 2023
1 parent 5dad44d commit b3b7ff3
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 49 deletions.
108 changes: 61 additions & 47 deletions proxy/include/proxy/proxy_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ namespace proxy {
// 指定当前proxy server认证密码.
std::string passwd_;

// 授权信息.
using auth_users = std::tuple<std::string, std::string>;
std::vector<auth_users> auth_users_;

// 指定当前proxy server向外发起连接时, 绑定到哪个本地地址.
std::string bind_addr_;

Expand Down Expand Up @@ -275,7 +279,7 @@ namespace proxy {
auto self = shared_from_this();

net::co_spawn(m_local_socket.get_executor(),
[self, this]() -> net::awaitable<void>
[this, self, server]() -> net::awaitable<void>
{
co_await start_socks_proxy();
}, net::detached);
Expand All @@ -293,9 +297,6 @@ namespace proxy {
private:
inline net::awaitable<void> start_socks_proxy()
{
// 保持整个生命周期在协程栈上.
auto self = shared_from_this();

// read
// +----+----------+----------+
// |VER | NMETHODS | METHODS |
Expand Down Expand Up @@ -407,13 +408,8 @@ namespace proxy {
co_return;
}

auto server = m_proxy_server.lock();
if (!server)
co_return;

// 服务端是否需要认证.
const auto& srv_opt = server->option();
auto auth_required = !srv_opt.usrdid_.empty();
auto auth_required = !m_option.usrdid_.empty();

// 循环读取客户端支持的代理方式.
p = net::buffer_cast<const char*>(m_local_buffer.data());
Expand Down Expand Up @@ -1088,23 +1084,29 @@ namespace proxy {
<< (socks4a ? hostname : dst_endpoint.address().to_string());

// 用户认证逻辑.
bool verify_passed = false;
auto server = m_proxy_server.lock();
bool verify_passed = m_option.usrdid_ == userid;

if (server)
if (!verify_passed || userid.empty())
{
const auto& srv_opt = server->option();
verify_passed = false;

verify_passed = srv_opt.usrdid_ == userid;
if (verify_passed)
LOG_DBG << "socks id: " << m_connection_id
<< ", auth passed";
else
LOG_WARN << "socks id: " << m_connection_id
<< ", auth no pass";
server = {};
for (auto [user, pwd] : m_option.auth_users_)
{
if (user == userid)
{
verify_passed = true;
break;
}
}
}

if (verify_passed)
LOG_DBG << "socks id: " << m_connection_id
<< ", auth passed";
else
LOG_WARN << "socks id: " << m_connection_id
<< ", auth no pass";

if (!verify_passed)
{
// +----+----+----+----+----+----+----+----+
Expand Down Expand Up @@ -1213,7 +1215,7 @@ namespace proxy {

inline bool http_proxy_authorization(std::string_view pa)
{
if (m_option.usrdid_.empty())
if (m_option.usrdid_.empty() && m_option.auth_users_.empty())
return true;

if (pa.empty())
Expand Down Expand Up @@ -1266,15 +1268,27 @@ namespace proxy {
m_option.usrdid_ == uname &&
m_option.passwd_ == passwd;

if (!verify_passed || uname.empty())
{
verify_passed = false;

for (auto [user, pwd] : m_option.auth_users_)
{
if (uname == user && passwd == pwd)
{
verify_passed = true;
break;
}
}
}

auto endp = m_local_socket.remote_endpoint();
auto client = endp.address().to_string();
client += ":" + std::to_string(endp.port());

LOG_DBG << "socks id: " << m_connection_id
<< ", auth: " << m_option.usrdid_
<< " := " << uname
<< ", passwd: " << m_option.passwd_
<< " := " << passwd
<< ", auth: " << uname
<< ", passwd: " << passwd
<< ", client: " << client;

if (!verify_passed)
Expand Down Expand Up @@ -1584,25 +1598,29 @@ namespace proxy {
client += ":" + std::to_string(endp.port());

// 用户认证逻辑.
bool verify_passed = false;
auto server = m_proxy_server.lock();
bool verify_passed =
m_option.usrdid_ == uname &&
m_option.passwd_ == passwd;

if (server)
if (!verify_passed || uname.empty())
{
const auto& srv_opt = server->option();
verify_passed = false;

verify_passed =
srv_opt.usrdid_ == uname && srv_opt.passwd_ == passwd;
server.reset();

LOG_DBG << "socks id: " << m_connection_id
<< ", auth: " << srv_opt.usrdid_
<< " := " << uname
<< ", passwd: " << srv_opt.passwd_
<< " := " << passwd
<< ", client: " << client;
for (auto [user, pwd] : m_option.auth_users_)
{
if (uname == user && passwd == pwd)
{
verify_passed = true;
break;
}
}
}

LOG_DBG << "socks id: " << m_connection_id
<< ", auth: " << uname
<< ", passwd: " << passwd
<< ", client: " << client;

net::streambuf wbuf;
auto wp = net::buffer_cast<char*>(wbuf.prepare(16));
write<uint8_t>(0x01, wp); // version 只能是1.
Expand Down Expand Up @@ -1804,12 +1822,8 @@ namespace proxy {
ssl_stream& ssl_socket =
boost::variant2::get<ssl_stream>(socks_stream);

auto server = m_proxy_server.lock();
BOOST_ASSERT(server && "server is nullptr!");
auto opt = server->option();

std::string sni =
opt.ssl_sni_.empty() ? proxy_host : opt.ssl_sni_;
std::string sni = m_option.ssl_sni_.empty()
? proxy_host : m_option.ssl_sni_;

// Set SNI Hostname.
if (!SSL_set_tlsext_host_name(
Expand Down
20 changes: 18 additions & 2 deletions server/proxy_server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ inline int platform_init()

std::string socks_userid;
std::string socks_passwd;
std::vector<std::string> auth_users;
std::string proxy_pass;
bool proxy_pass_ssl = false;
bool ssl_prefer_server_ciphers = false;
Expand Down Expand Up @@ -158,6 +159,19 @@ start_proxy_server(net::io_context& ioc, server_ptr& server)
opt.usrdid_ = socks_userid;
opt.passwd_ = socks_passwd;

for (const auto& user : auth_users)
{
if (user.empty())
continue;

auto pos = user.find(':');
if (pos == std::string::npos)
opt.auth_users_.emplace_back(user, "");
else
opt.auth_users_.emplace_back(
user.substr(0, pos), user.substr(pos + 1));
}

opt.proxy_pass_ = proxy_pass;
opt.proxy_pass_use_ssl_ = proxy_pass_ssl;

Expand Down Expand Up @@ -295,8 +309,10 @@ int main(int argc, char** argv)

("reuse_port", po::value<bool>(&reuse_port)->default_value(false), "TCP reuse port option(SO_REUSEPORT since Linux 3.9).")

("socks_userid", po::value<std::string>(&socks_userid)->default_value("jack")->value_name("userid"), "Socks4/5 auth user id.")
("socks_passwd", po::value<std::string>(&socks_passwd)->default_value("1111")->value_name("passwd"), "Socks4/5 auth password.")
("socks_userid", po::value<std::string>(&socks_userid)->default_value("jack")->value_name("userid"), "Auth user id (Deprecated)")
("socks_passwd", po::value<std::string>(&socks_passwd)->default_value("1111")->value_name("passwd"), "Auth password (Deprecated)")

("auth_users", po::value<std::vector<std::string>>(&auth_users)->multitoken()->value_name("authorization"), "Authorized user list (e.g: user:passwd)")

("proxy_pass", po::value<std::string>(&proxy_pass)->default_value("")->value_name(""), "Next proxy pass. (e.g: socks5://user:passwd@ip:port)")
("proxy_pass_ssl", po::value<bool>(&proxy_pass_ssl)->default_value(false, "false")->value_name(""), "Next proxy pass with ssl.")
Expand Down

0 comments on commit b3b7ff3

Please sign in to comment.