Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
291b7c27
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
291b7c27
编写于
2月 06, 2020
作者:
V
Vitaly Baranov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move some part of the Authentication class to header to allow using in the parser.
上级
1e8f04b5
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
144 addition
and
159 deletion
+144
-159
dbms/src/Access/Authentication.cpp
dbms/src/Access/Authentication.cpp
+3
-156
dbms/src/Access/Authentication.h
dbms/src/Access/Authentication.h
+130
-3
dbms/src/Common/OpenSSLHelpers.cpp
dbms/src/Common/OpenSSLHelpers.cpp
+9
-0
dbms/src/Common/OpenSSLHelpers.h
dbms/src/Common/OpenSSLHelpers.h
+2
-0
未找到文件。
dbms/src/Access/Authentication.cpp
浏览文件 @
291b7c27
#include <Access/Authentication.h>
#include <Common/Exception.h>
#include <common/StringRef.h>
#include <Core/Defines.h>
#include <Poco/SHA1Engine.h>
#include <boost/algorithm/hex.hpp>
#include "config_core.h"
#if USE_SSL
# include <openssl/sha.h>
#endif
namespace
DB
{
namespace
ErrorCodes
{
extern
const
int
SUPPORT_IS_DISABLED
;
extern
const
int
REQUIRED_PASSWORD
;
extern
const
int
WRONG_PASSWORD
;
extern
const
int
BAD_ARGUMENTS
;
extern
const
int
LOGICAL_ERROR
;
}
namespace
{
using
Digest
=
Authentication
::
Digest
;
Digest
encodePlainText
(
const
StringRef
&
text
)
{
return
Digest
(
text
.
data
,
text
.
data
+
text
.
size
);
}
Digest
encodeSHA256
(
const
StringRef
&
text
)
{
#if USE_SSL
Digest
hash
;
hash
.
resize
(
32
);
SHA256_CTX
ctx
;
SHA256_Init
(
&
ctx
);
SHA256_Update
(
&
ctx
,
reinterpret_cast
<
const
UInt8
*>
(
text
.
data
),
text
.
size
);
SHA256_Final
(
hash
.
data
(),
&
ctx
);
return
hash
;
#else
UNUSED
(
text
);
throw
DB
::
Exception
(
"SHA256 passwords support is disabled, because ClickHouse was built without SSL library"
,
DB
::
ErrorCodes
::
SUPPORT_IS_DISABLED
);
#endif
}
Digest
encodeSHA1
(
const
StringRef
&
text
)
{
Poco
::
SHA1Engine
engine
;
engine
.
update
(
text
.
data
,
text
.
size
);
return
engine
.
digest
();
}
Digest
encodeSHA1
(
const
Digest
&
text
)
{
return
encodeSHA1
(
StringRef
{
reinterpret_cast
<
const
char
*>
(
text
.
data
()),
text
.
size
()});
}
Digest
encodeDoubleSHA1
(
const
StringRef
&
text
)
{
return
encodeSHA1
(
encodeSHA1
(
text
));
}
}
Authentication
::
Authentication
(
Authentication
::
Type
type_
)
:
type
(
type_
)
{
}
void
Authentication
::
setPassword
(
const
String
&
password_
)
{
switch
(
type
)
{
case
NO_PASSWORD
:
throw
Exception
(
"Cannot specify password for the 'NO_PASSWORD' authentication type"
,
ErrorCodes
::
LOGICAL_ERROR
);
case
PLAINTEXT_PASSWORD
:
setPasswordHashBinary
(
encodePlainText
(
password_
));
return
;
case
SHA256_PASSWORD
:
setPasswordHashBinary
(
encodeSHA256
(
password_
));
return
;
case
DOUBLE_SHA1_PASSWORD
:
setPasswordHashBinary
(
encodeDoubleSHA1
(
password_
));
return
;
}
throw
Exception
(
"Unknown authentication type: "
+
std
::
to_string
(
static_cast
<
int
>
(
type
)),
ErrorCodes
::
LOGICAL_ERROR
);
}
String
Authentication
::
getPassword
()
const
{
if
(
type
!=
PLAINTEXT_PASSWORD
)
throw
Exception
(
"Cannot decode the password"
,
ErrorCodes
::
LOGICAL_ERROR
);
return
String
(
password_hash
.
data
(),
password_hash
.
data
()
+
password_hash
.
size
());
}
void
Authentication
::
setPasswordHashHex
(
const
String
&
hash
)
{
Digest
digest
;
digest
.
resize
(
hash
.
size
()
/
2
);
boost
::
algorithm
::
unhex
(
hash
.
begin
(),
hash
.
end
(),
digest
.
data
());
setPasswordHashBinary
(
digest
);
}
String
Authentication
::
getPasswordHashHex
()
const
{
String
hex
;
hex
.
resize
(
password_hash
.
size
()
*
2
);
boost
::
algorithm
::
hex
(
password_hash
.
begin
(),
password_hash
.
end
(),
hex
.
data
());
return
hex
;
}
void
Authentication
::
setPasswordHashBinary
(
const
Digest
&
hash
)
{
switch
(
type
)
{
case
NO_PASSWORD
:
throw
Exception
(
"Cannot specify password for the 'NO_PASSWORD' authentication type"
,
ErrorCodes
::
LOGICAL_ERROR
);
case
PLAINTEXT_PASSWORD
:
{
password_hash
=
hash
;
return
;
}
case
SHA256_PASSWORD
:
{
if
(
hash
.
size
()
!=
32
)
throw
Exception
(
"Password hash for the 'SHA256_PASSWORD' authentication type has length "
+
std
::
to_string
(
hash
.
size
())
+
" but must be exactly 32 bytes."
,
ErrorCodes
::
BAD_ARGUMENTS
);
password_hash
=
hash
;
return
;
}
case
DOUBLE_SHA1_PASSWORD
:
{
if
(
hash
.
size
()
!=
20
)
throw
Exception
(
"Password hash for the 'DOUBLE_SHA1_PASSWORD' authentication type has length "
+
std
::
to_string
(
hash
.
size
())
+
" but must be exactly 20 bytes."
,
ErrorCodes
::
BAD_ARGUMENTS
);
password_hash
=
hash
;
return
;
}
}
throw
Exception
(
"Unknown authentication type: "
+
std
::
to_string
(
static_cast
<
int
>
(
type
)),
ErrorCodes
::
LOGICAL_ERROR
);
}
Digest
Authentication
::
getPasswordDoubleSHA1
()
const
Authentication
::
Digest
Authentication
::
getPasswordDoubleSHA1
()
const
{
switch
(
type
)
{
...
...
@@ -198,12 +50,12 @@ bool Authentication::isCorrectPassword(const String & password_) const
case
PLAINTEXT_PASSWORD
:
{
if
(
password_
==
StringRef
{
reinterpret_cast
<
const
char
*>
(
password_hash
.
data
()),
password_hash
.
size
()})
if
(
password_
==
std
::
string_view
{
reinterpret_cast
<
const
char
*>
(
password_hash
.
data
()),
password_hash
.
size
()})
return
true
;
// For compatibility with MySQL clients which support only native authentication plugin, SHA1 can be passed instead of password.
auto
password_sha1
=
encodeSHA1
(
password_hash
);
return
password_
==
StringRef
{
reinterpret_cast
<
const
char
*>
(
password_sha1
.
data
()),
password_sha1
.
size
()};
return
password_
==
std
::
string_view
{
reinterpret_cast
<
const
char
*>
(
password_sha1
.
data
()),
password_sha1
.
size
()};
}
case
SHA256_PASSWORD
:
...
...
@@ -234,10 +86,5 @@ void Authentication::checkPassword(const String & password_, const String & user
throw
Exception
(
"Wrong password"
+
info_about_user_name
(),
ErrorCodes
::
WRONG_PASSWORD
);
}
bool
operator
==
(
const
Authentication
&
lhs
,
const
Authentication
&
rhs
)
{
return
(
lhs
.
type
==
rhs
.
type
)
&&
(
lhs
.
password_hash
==
rhs
.
password_hash
);
}
}
dbms/src/Access/Authentication.h
浏览文件 @
291b7c27
#pragma once
#include <Core/Types.h>
#include <Common/Exception.h>
#include <Common/OpenSSLHelpers.h>
#include <Poco/SHA1Engine.h>
#include <boost/algorithm/hex.hpp>
namespace
DB
{
namespace
ErrorCodes
{
extern
const
int
SUPPORT_IS_DISABLED
;
extern
const
int
BAD_ARGUMENTS
;
extern
const
int
LOGICAL_ERROR
;
}
/// Authentication type and encrypted password for checking when an user logins.
class
Authentication
{
...
...
@@ -27,7 +39,7 @@ public:
using
Digest
=
std
::
vector
<
UInt8
>
;
Authentication
(
Authentication
::
Type
type
=
NO_PASSWORD
);
Authentication
(
Authentication
::
Type
type
_
=
NO_PASSWORD
)
:
type
(
type_
)
{}
Authentication
(
const
Authentication
&
src
)
=
default
;
Authentication
&
operator
=
(
const
Authentication
&
src
)
=
default
;
Authentication
(
Authentication
&&
src
)
=
default
;
...
...
@@ -36,17 +48,19 @@ public:
Type
getType
()
const
{
return
type
;
}
/// Sets the password and encrypt it using the authentication type set in the constructor.
void
setPassword
(
const
String
&
password
);
void
setPassword
(
const
String
&
password
_
);
/// Returns the password. Allowed to use only for Type::PLAINTEXT_PASSWORD.
String
getPassword
()
const
;
/// Sets the password as a string of hexadecimal digits.
void
setPasswordHashHex
(
const
String
&
hash
);
String
getPasswordHashHex
()
const
;
/// Sets the password in binary form.
void
setPasswordHashBinary
(
const
Digest
&
hash
);
const
Digest
&
getPasswordHashBinary
()
const
{
return
password_hash
;
}
/// Returns SHA1(SHA1(password)) used by MySQL compatibility server for authentication.
...
...
@@ -60,11 +74,124 @@ public:
/// `user_name` is only used for generating an error message if the password is incorrect.
void
checkPassword
(
const
String
&
password
,
const
String
&
user_name
=
String
())
const
;
friend
bool
operator
==
(
const
Authentication
&
lhs
,
const
Authentication
&
rhs
)
;
friend
bool
operator
==
(
const
Authentication
&
lhs
,
const
Authentication
&
rhs
)
{
return
(
lhs
.
type
==
rhs
.
type
)
&&
(
lhs
.
password_hash
==
rhs
.
password_hash
);
}
friend
bool
operator
!=
(
const
Authentication
&
lhs
,
const
Authentication
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
private:
static
Digest
encodePlainText
(
const
std
::
string_view
&
text
)
{
return
Digest
(
text
.
data
(),
text
.
data
()
+
text
.
size
());
}
static
Digest
encodeSHA256
(
const
std
::
string_view
&
text
);
static
Digest
encodeSHA1
(
const
std
::
string_view
&
text
);
static
Digest
encodeSHA1
(
const
Digest
&
text
)
{
return
encodeSHA1
(
std
::
string_view
{
reinterpret_cast
<
const
char
*>
(
text
.
data
()),
text
.
size
()});
}
static
Digest
encodeDoubleSHA1
(
const
std
::
string_view
&
text
)
{
return
encodeSHA1
(
encodeSHA1
(
text
));
}
Type
type
=
Type
::
NO_PASSWORD
;
Digest
password_hash
;
};
inline
Authentication
::
Digest
Authentication
::
encodeSHA256
(
const
std
::
string_view
&
text
[[
maybe_unused
]])
{
#if USE_SSL
Digest
hash
;
hash
.
resize
(
32
);
::
DB
::
encodeSHA256
(
text
,
hash
.
data
());
return
hash
;
#else
throw
DB
::
Exception
(
"SHA256 passwords support is disabled, because ClickHouse was built without SSL library"
,
DB
::
ErrorCodes
::
SUPPORT_IS_DISABLED
);
#endif
}
inline
Authentication
::
Digest
Authentication
::
encodeSHA1
(
const
std
::
string_view
&
text
)
{
Poco
::
SHA1Engine
engine
;
engine
.
update
(
text
.
data
(),
text
.
size
());
return
engine
.
digest
();
}
inline
void
Authentication
::
setPassword
(
const
String
&
password_
)
{
switch
(
type
)
{
case
NO_PASSWORD
:
throw
Exception
(
"Cannot specify password for the 'NO_PASSWORD' authentication type"
,
ErrorCodes
::
LOGICAL_ERROR
);
case
PLAINTEXT_PASSWORD
:
return
setPasswordHashBinary
(
encodePlainText
(
password_
));
case
SHA256_PASSWORD
:
return
setPasswordHashBinary
(
encodeSHA256
(
password_
));
case
DOUBLE_SHA1_PASSWORD
:
return
setPasswordHashBinary
(
encodeDoubleSHA1
(
password_
));
}
throw
Exception
(
"Unknown authentication type: "
+
std
::
to_string
(
static_cast
<
int
>
(
type
)),
ErrorCodes
::
LOGICAL_ERROR
);
}
inline
String
Authentication
::
getPassword
()
const
{
if
(
type
!=
PLAINTEXT_PASSWORD
)
throw
Exception
(
"Cannot decode the password"
,
ErrorCodes
::
LOGICAL_ERROR
);
return
String
(
password_hash
.
data
(),
password_hash
.
data
()
+
password_hash
.
size
());
}
inline
void
Authentication
::
setPasswordHashHex
(
const
String
&
hash
)
{
Digest
digest
;
digest
.
resize
(
hash
.
size
()
/
2
);
boost
::
algorithm
::
unhex
(
hash
.
begin
(),
hash
.
end
(),
digest
.
data
());
setPasswordHashBinary
(
digest
);
}
inline
String
Authentication
::
getPasswordHashHex
()
const
{
String
hex
;
hex
.
resize
(
password_hash
.
size
()
*
2
);
boost
::
algorithm
::
hex
(
password_hash
.
begin
(),
password_hash
.
end
(),
hex
.
data
());
return
hex
;
}
inline
void
Authentication
::
setPasswordHashBinary
(
const
Digest
&
hash
)
{
switch
(
type
)
{
case
NO_PASSWORD
:
throw
Exception
(
"Cannot specify password for the 'NO_PASSWORD' authentication type"
,
ErrorCodes
::
LOGICAL_ERROR
);
case
PLAINTEXT_PASSWORD
:
{
password_hash
=
hash
;
return
;
}
case
SHA256_PASSWORD
:
{
if
(
hash
.
size
()
!=
32
)
throw
Exception
(
"Password hash for the 'SHA256_PASSWORD' authentication type has length "
+
std
::
to_string
(
hash
.
size
())
+
" but must be exactly 32 bytes."
,
ErrorCodes
::
BAD_ARGUMENTS
);
password_hash
=
hash
;
return
;
}
case
DOUBLE_SHA1_PASSWORD
:
{
if
(
hash
.
size
()
!=
20
)
throw
Exception
(
"Password hash for the 'DOUBLE_SHA1_PASSWORD' authentication type has length "
+
std
::
to_string
(
hash
.
size
())
+
" but must be exactly 20 bytes."
,
ErrorCodes
::
BAD_ARGUMENTS
);
password_hash
=
hash
;
return
;
}
}
throw
Exception
(
"Unknown authentication type: "
+
std
::
to_string
(
static_cast
<
int
>
(
type
)),
ErrorCodes
::
LOGICAL_ERROR
);
}
}
dbms/src/Common/OpenSSLHelpers.cpp
浏览文件 @
291b7c27
...
...
@@ -3,11 +3,20 @@
#include "OpenSSLHelpers.h"
#include <ext/scope_guard.h>
#include <openssl/err.h>
#include <openssl/sha.h>
namespace
DB
{
#pragma GCC diagnostic warning "-Wold-style-cast"
void
encodeSHA256
(
const
std
::
string_view
&
text
,
unsigned
char
*
out
)
{
SHA256_CTX
ctx
;
SHA256_Init
(
&
ctx
);
SHA256_Update
(
&
ctx
,
reinterpret_cast
<
const
UInt8
*>
(
text
.
data
()),
text
.
size
());
SHA256_Final
(
out
,
&
ctx
);
}
String
getOpenSSLErrors
()
{
BIO
*
mem
=
BIO_new
(
BIO_s_mem
());
...
...
dbms/src/Common/OpenSSLHelpers.h
浏览文件 @
291b7c27
...
...
@@ -7,6 +7,8 @@
namespace
DB
{
/// Encodes `text` and puts the result to `out` which must be at least 32 bytes long.
void
encodeSHA256
(
const
std
::
string_view
&
text
,
unsigned
char
*
out
);
/// Returns concatenation of error strings for all errors that OpenSSL has recorded, emptying the error queue.
String
getOpenSSLErrors
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录