Skip to content

Commit

Permalink
提供 fon9::auth::AddSaslClientCreator(); 可增加 Client 自訂 SASL 的認證機制。
Browse files Browse the repository at this point in the history
  • Loading branch information
fonwin committed Feb 11, 2023
1 parent 85d5ba1 commit 67aaa58
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
32 changes: 27 additions & 5 deletions fon9/auth/SaslClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 15,42 @@ SaslClient::~SaslClient() {
//--------------------------------------------------------------------------//

// 使用 Password 機制的 SaslClient 定義.
typedef SaslClientSP (*FnSaslClientCreator) (const StrView& authz, const StrView& authc, const StrView& pass);
struct SaslClientMech_Password {
StrView Name_;
FnSaslClientCreator Creator_;
};
static SaslClientMech_Password SaslClientMech_Password_[]{
static std::vector<SaslClientMech_Password> SaslClientMech_Password_ {
{StrView{"SCRAM-SHA-256"}, &SaslScramSha256ClientCreator}
};
static const SaslClientMech_Password* FindSaslClientCreator(fon9::StrView name) {
for (SaslClientMech_Password& c : SaslClientMech_Password_) {
if (c.Name_ == name)
return &c;
}
return nullptr;
}

fon9_API bool AddSaslClientCreator(fon9::StrView name, FnSaslClientCreator fnCreator) {
if (FindSaslClientCreator(name))
return false;
SaslClientMech_Password_.push_back(SaslClientMech_Password{name, fnCreator});
return true;
}

fon9_API SaslClientR CreateSaslClient(StrView saslMechList, char chSplitter,
const StrView& authz, const StrView& authc, const StrView& pass) {
for (SaslClientMech_Password& c : SaslClientMech_Password_) {
if (StrSearchSubstr(saslMechList, c.Name_, chSplitter))
return SaslClientR{c.Name_, c.Creator_(authz, authc, pass)};
if (const char* pspl = authc.Find('/')) {
fon9::StrView mechName{authc.begin(), pspl};
if (StrSearchSubstr(saslMechList, mechName, chSplitter)) {
if (const SaslClientMech_Password* mech = FindSaslClientCreator(mechName))
return SaslClientR{mech->Name_, mech->Creator_(authz, fon9::StrView{pspl 1, authc.end()}, pass)};
}
}
else {
for (SaslClientMech_Password& c : SaslClientMech_Password_) {
if (StrSearchSubstr(saslMechList, c.Name_, chSplitter))
return SaslClientR{c.Name_, c.Creator_(authz, authc, pass)};
}
}
return SaslClientR{StrView{}, SaslClientSP{}};
}
Expand Down
12 changes: 12 additions & 0 deletions fon9/auth/SaslClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 48,20 @@ struct SaslClientR {
SaslClientSP SaslClient_;
};

typedef SaslClientSP (*FnSaslClientCreator) (const StrView& authz, const StrView& authc, const StrView& pass);

/// \ingroup auth
/// 額外增加自訂的 SaslClientCreator;
/// - 不是 thread safe, 通常必須在系統啟動階段呼叫.
/// - name 的內容必須是常數(系統結束前必須有效), 不能用 std::string 的內容.
///
/// \retval false 表示該名稱已存在.
fon9_API bool AddSaslClientCreator(fon9::StrView name, FnSaslClientCreator fnCreator);

/// \ingroup auth
/// 從 saslMechList 裡面選一個有支援的 sasl mech, 並建立 SaslClient.
/// - authc 填入 "UserId", 或 "SaslMeth/UserId";
/// - authz, 則為[訪問權限]的資源Id, 例: 在 UNIX 上使用 sudo, 則 authz="root"; authc=登入Id;
fon9_API SaslClientR CreateSaslClient(StrView saslMechList, char chSplitter,
const StrView& authz, const StrView& authc, const StrView& pass);

Expand Down

0 comments on commit 67aaa58

Please sign in to comment.