Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ add_library(jsonxx STATIC third_party/jsonxx/jsonxx.cc)
include_directories("third_party/curi/src")
add_subdirectory(third_party/curi/src)

add_executable(ahpc src/http_proxy_client_main.cpp src/http_proxy_client.cpp src/http_proxy_client_config.cpp src/http_proxy_client_connection.cpp)
add_executable(ahpc src/http_proxy_client_main.cpp src/http_proxy_client.cpp src/http_proxy_client_config.cpp src/http_proxy_client_connection.cpp src/hash_utils.cpp)
target_link_libraries(ahpc ${OPENSSL_LIBRARIES} jsonxx)

add_executable(ahps src/http_proxy_server_main.cpp src/http_proxy_server.cpp src/http_proxy_server_config.cpp src/http_proxy_server_connection.cpp src/http_header_parser.cpp src/base64.cpp src/authentication.cpp)
add_executable(ahps src/http_proxy_server_main.cpp src/http_proxy_server.cpp src/http_proxy_server_config.cpp src/http_proxy_server_connection.cpp src/http_header_parser.cpp src/hash_utils.cpp src/authentication.cpp)
target_link_libraries(ahps ${OPENSSL_LIBRARIES} jsonxx curi)

if(UNIX)
Expand Down
26 changes: 11 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ AHP(Azure Http Proxy)是一款高速、安全、轻量级和跨平台的HTTP代
- 对目标域名的解析在服务端进行,可以解决本地DNS污染的问题
- 服务端同时支持多种数据加密方式,数据加密方式可由客户端任意指定,客户端可以权衡机器性能以及安全需求选择合适的加密方式
- 多线程并发处理,充分利用多处理器的优势,能同时处理成千上万的并发连接
- 多用户支持,允许为每个用户使用独立的帐号和密码
- 多用户支持,允许为每个用户使用独立的auth_key `(1.1及以上版本)`

## 编译和安装

Expand All @@ -24,7 +24,7 @@ AHP使用了部分C++17特性,所以对编译器的版本有较高要求,下

### 安装依赖

- OpenSSL
- OpenSSL >= 3.0

#### Linux

Expand Down Expand Up @@ -56,7 +56,6 @@ AHP使用自动化构建工具CMake来实现跨平台构建

- CMake >= 2.8

Windows下可以使用cmake-gui.exe,Linux或其他类Unix系统可以使用下面的命令编译
```shell
$ cd azure-http-proxy
$ mkdir build
Expand Down Expand Up @@ -94,15 +93,10 @@ $ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
"timeout": 240,
"workers": 4,
"auth": true,
"users": [
{
"username": "username1",
"password": "password1"
},
{
"username": "foobar",
"password": "bazqux"
}
"auth_key_list": [
"testing_key",
"Bob",
"Alice"
]
}
```
Expand All @@ -111,11 +105,11 @@ $ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
----------------|--------------------|------------------|-----------|
bind_address | 服务端绑定的IP地址 | 否 | "0.0.0.0" |
listen_port | 服务端绑定的端口 | 否 | 8090 |
rsa_private_key | RSA私钥 | 是 | 无 |
rsa_private_key | RSA私钥 | 是 | 无 |
timeout | 超时时间(秒) | 否 | 240 |
workers | 并发工作线程数 | 否 | 4 |
auth | 启用代理身份验证 | 否 | false |
users | 用户列表 | auth为true时必选 | 无 |
auth_key_list | auth_key列表 | auth为true时必选 | 无 |

### 配置客户端

Expand All @@ -129,7 +123,8 @@ users | 用户列表 | auth为true时必选 | 无 |
"rsa_public_key": "-----BEGIN PUBLIC KEY----- ...... -----END PUBLIC KEY-----",
"cipher": "aes-256-cfb",
"timeout": 240,
"workers": 2
"workers": 2,
"auth_key": "testing_key"
}
```

Expand All @@ -143,6 +138,7 @@ rsa_public_key | RSA公钥 | 是 | 无
cipher | 加密方法 | 否 | "aes-256-cfb" |
timeout | 超时时间(秒) | 否 | 240 |
workers | 并发工作线程数 | 否 | 2 |
auth_key | 用于身份验证的字符串 | 否 | 值为空字符串或没有这个字段时,请求不携带auth_key,仅当server的auth为false时才能成功建立连接|

#### 支持的加密方法

Expand Down
3 changes: 2 additions & 1 deletion example/client.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"rsa_public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxPbPBU61RYBI0rUDVso+\nTzkQ7bXO1j4GWxbYZ3nEL6sLbrftv7rpYq5uPLi9DdJ3ZoEUjxlnO+VUOOtm7LpR\nGmWqUQdNnYHuiZU1UuH7pDIXejQwwSC698FB1kwnoxV4LICkiA1a4qucqlnG8nN6\ngBFs3/1K2DuUs0Hg1hZKlkOq/ONR82XGhXkB/HVwmfgQlZpVbWHQDsZiOv1SUnQW\n8Zs6E/JmW6llBkWtsQT9nQ2uzcV1JGzV0ltB4N0CMC8u2zv/LLTSgS4IKrVicAqO\n9TWkGOFmGowV7PpEAEQC1WcBXThLpUYk2QqiSvTTLTdFNmwEH+hKa1ZBPqOcaTA1\ndQIDAQAB\n-----END PUBLIC KEY-----",
"cipher": "aes-256-cfb",
"timeout": 240,
"workers": 2
"workers": 2,
"auth_key": "testing_key"
}
15 changes: 6 additions & 9 deletions example/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
"timeout": 240,
"workers": 4,
"auth": true,
"users": [
{
"username": "username1",
"password": "password1"
},
{
"username": "foobar",
"password": "bazqux"
}
"auth_key_list": [
"testing_key",
"Bob",
"Alice",
"+ZI1w$u9N65lTw*nL@$",
"SoHPa4xNMBWoXxSOp+6snUtqtdXFH(MO"
]
}
42 changes: 8 additions & 34 deletions src/authentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,28 @@
#include <iterator>

#include "authentication.hpp"
#include "base64.hpp"
#include "hash_utils.hpp"

namespace azure_proxy {

authentication::authentication()
{
}

auth_result authentication::auth_basic(const std::string::const_iterator begin, const std::string::const_iterator end) const
bool authentication::auth(const auth_key_hash_t& auth_key_hash) const
{
std::string authorization;
try {
azure_proxy::encoding::base64_decode(begin, end, std::back_inserter(authorization));
}
catch (const azure_proxy::encoding::decode_base64_error&) {
return auth_result::error;
}
auto colon_pos = authorization.find(':');
if (colon_pos == std::string::npos) {
return auth_result::error;
}
std::string username(authorization.begin(), authorization.begin() + colon_pos);
std::string password(authorization.begin() + colon_pos + 1, authorization.end());
auto iter = this->users_map.find(username);
if (iter != this->users_map.end() && std::get<1>(*iter) == password) {
return auth_result::ok;
}
return auth_result::incorrect;
return this->auth_keys_map.find(auth_key_hash) != this->auth_keys_map.end();
}

auth_result authentication::auth(const std::string& value) const
void authentication::add_auth_key(const std::string& auth_key)
{
if (value.size() > 6 && std::equal(value.begin(), value.begin() + 6, "Basic ")) {
return this->auth_basic(value.begin() + 6, value.end());
}
else {
return auth_result::error;
}
auto auth_key_hash = hash_utils::sha256(reinterpret_cast<const unsigned char*>(auth_key.data()), auth_key.size());
this->auth_keys_map[auth_key_hash] = auth_key;
}

void authentication::add_user(const std::string& username, const std::string& password)
void authentication::remove_all_auth_keys()
{
this->users_map[username] = password;
}

void authentication::remove_all_users()
{
this->users_map.clear();
this->auth_keys_map.clear();
}

authentication& authentication::get_instance()
Expand Down
16 changes: 6 additions & 10 deletions src/authentication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,22 @@
#ifndef AZURE_AUTHENTICATION_HPP
#define AZURE_AUTHENTICATION_HPP

#include <array>
#include <map>
#include <string>

namespace azure_proxy {

enum class auth_result {
ok,
incorrect,
error
};
using auth_key_hash_t = std::array<unsigned char, 32>;

class authentication {
std::map<std::string, std::string> users_map;
std::map<auth_key_hash_t, std::string> auth_keys_map;
private:
authentication();
auth_result auth_basic(const std::string::const_iterator begin, const std::string::const_iterator end) const;
public:
auth_result auth(const std::string& value) const;
void add_user(const std::string& username, const std::string& password);
void remove_all_users();
bool auth(const auth_key_hash_t& auth_key_hash) const;
void add_auth_key(const std::string& auth_key);
void remove_all_auth_keys();

static authentication& get_instance();
};
Expand Down
43 changes: 0 additions & 43 deletions src/base64.cpp

This file was deleted.

106 changes: 0 additions & 106 deletions src/base64.hpp

This file was deleted.

21 changes: 21 additions & 0 deletions src/hash_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* hash_utils.cpp:
*
* Copyright (C) 2023 Light Lin <lxrite@gmail.com> All Rights Reserved.
*
*/

#include "hash_utils.hpp"
#include <openssl/sha.h>

namespace azure_proxy {
namespace hash_utils {

std::array<unsigned char, 32> sha256(const unsigned char* data, std::size_t count) {
std::array<unsigned char, 32> result;
SHA256(data, count, result.data());
return result;
}

} // namespace hash_utils
} // namespace azure_proxy
Loading