Skip to content

Commit 1faa497

Browse files
committed
feat: support configurable password encryption algorithms
Added support for configurable password encryption algorithms through dconfig settings. The system now supports multiple encryption algorithms including SM3, yescrypt, SHA512, and SHA256. The default algorithm is set to SM3 but can be changed via configuration. Key changes include: 1. Added dconfig key for password encryption algorithm selection 2. Implemented algorithm lookup and fallback mechanism in C code 3. Created new function for password encryption with algorithm parameter 4. Added configuration change monitoring to update algorithm dynamically 5. Maintained backward compatibility with existing password encoding Log: Added configurable password encryption algorithm support Influence: 1. Test password creation with different algorithm configurations 2. Verify algorithm fallback when configured algorithm fails 3. Test configuration change detection and algorithm switching 4. Verify backward compatibility with existing passwords 5. Test all supported algorithms: SM3, yescrypt, SHA512, SHA256 6. Check system behavior when invalid algorithm is configured feat: 支持可配置的密码加密算法 通过 dconfig 设置添加了对可配置密码加密算法的支持。系统现在支持多种加密 算法,包括 SM3、yescrypt、SHA512 和 SHA256。默认算法设置为 SM3,但可以通 过配置进行更改。 主要变更包括: 1. 添加了用于密码加密算法选择的 dconfig 键 2. 在 C 代码中实现了算法查找和回退机制 3. 创建了带算法参数的新密码加密函数 4. 添加了配置变更监控以动态更新算法 5. 保持与现有密码编码的向后兼容性 Log: 新增可配置密码加密算法支持 PMS: BUG-346165 Influence: 1. 测试使用不同算法配置的密码创建功能 2. 验证配置算法失败时的回退机制 3. 测试配置变更检测和算法切换功能 4. 验证与现有密码的向后兼容性 5. 测试所有支持的算法:SM3、yescrypt、SHA512、SHA256 6. 检查配置无效算法时的系统行为
1 parent 52f6ed4 commit 1faa497

5 files changed

Lines changed: 129 additions & 21 deletions

File tree

accounts1/manager.go

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ type InterfaceConfig struct {
6060
}
6161

6262
const (
63-
dsettingsAppID = "org.deepin.dde.daemon"
64-
dsettingsAccountName = "org.deepin.dde.daemon.account"
65-
dsettingsIsTerminalLocked = "isTerminalLocked"
66-
gsSchemaDdeControlCenter = "com.deepin.dde.control-center"
67-
settingKeyAutoLoginVisable = "auto-login-visable"
63+
dsettingsAppID = "org.deepin.dde.daemon"
64+
dsettingsAccountName = "org.deepin.dde.daemon.account"
65+
dsettingsIsTerminalLocked = "isTerminalLocked"
66+
gsSchemaDdeControlCenter = "com.deepin.dde.control-center"
67+
settingKeyAutoLoginVisable = "auto-login-visable"
68+
keyPasswordEncryptionAlgorithm = "passwordEncryptionAlgorithm"
6869
)
6970

7071
//go:generate dbusutil-gen -type Manager,User manager.go user.go
@@ -668,6 +669,23 @@ func (m *Manager) checkGroupCanChange(name string) bool {
668669
return gid >= 1000
669670
}
670671

672+
// 从 dconfig 获取 密码加密算法的配置
673+
func (m *Manager) getDConfigPasswdEncryptionAlgorithm() (string, error) {
674+
if m.dsAccount == nil {
675+
return "", errors.New("get accounts dconfig failed")
676+
}
677+
algoVar, err := m.dsAccount.Value(0, keyPasswordEncryptionAlgorithm)
678+
if err != nil {
679+
return "", fmt.Errorf("get accounts dconfig passwordEncryptionAlgorithm failed, err: %v", err)
680+
}
681+
682+
alg, ok := algoVar.Value().(string)
683+
if !ok {
684+
return "", errors.New("algoVar.Value() is not string type")
685+
}
686+
return alg, nil
687+
}
688+
671689
func (m *Manager) initAccountDSettings() {
672690
m.cfgManager = configManager.NewConfigManager(m.sysSigLoop.Conn())
673691

@@ -692,6 +710,16 @@ func (m *Manager) initAccountDSettings() {
692710
if data, ok := v.Value().(bool); ok {
693711
m.IsTerminalLocked = data
694712
}
713+
users.PasswdAlgoDefault, _ = m.getDConfigPasswdEncryptionAlgorithm()
714+
m.dsAccount.InitSignalExt(m.sysSigLoop, true)
715+
m.dsAccount.ConnectValueChanged(func(key string) {
716+
switch key {
717+
case keyPasswordEncryptionAlgorithm:
718+
users.PasswdAlgoDefault, _ = m.getDConfigPasswdEncryptionAlgorithm()
719+
logger.Warning("password encrypt algo changed:", users.PasswdAlgoDefault)
720+
}
721+
})
722+
695723
}
696724

697725
const (

accounts1/users/passwd.c

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,78 @@
1616
#define ERROR_NULLPOINTER -1;
1717
#define ERROR_NOERROR 0;
1818

19-
char *mkpasswd(const char *words) {
20-
unsigned long seed[2];
21-
char salt[] = "$6$........";
22-
const char *const seedchars = "./0123456789ABCDEFGHIJKLMNOPQRST"
23-
"UVWXYZabcdefghijklmnopqrstuvwxyz";
19+
#ifndef CRYPT_GENSALT_OUTPUT_SIZE
20+
#define CRYPT_GENSALT_OUTPUT_SIZE 192
21+
#endif
22+
23+
typedef struct {
24+
const char *name;
25+
const char *prefix;
26+
} PasswordAlgorithm;
27+
28+
static const PasswordAlgorithm SUPPORTED_ALGORITHMS[] = {
29+
{"sm3", "$sm3$"},
30+
{"yescrypt", "$y$"},
31+
{"sha512", "$6$"},
32+
{"sha256", "$5$"},
33+
{NULL, NULL}
34+
};
35+
36+
#define DEFAULT_ALGORITHM 0
37+
38+
static char *try_encrypt_password(const char *words, const char *prefix) {
39+
char output[CRYPT_GENSALT_OUTPUT_SIZE];
40+
char *setting;
41+
char *password;
42+
43+
setting = crypt_gensalt_rn(prefix, 0, NULL, 0, output, sizeof(output));
44+
if (setting == NULL || setting[0] == '*') {
45+
return NULL;
46+
}
47+
48+
password = crypt(words, setting);
49+
if (password == NULL || password[0] == '*') {
50+
return NULL;
51+
}
52+
53+
return password;
54+
}
55+
56+
char *mkpasswd_with_algo(const char *words, const char *algo) {
2457
char *password;
2558
int i;
59+
const PasswordAlgorithm *selected_algo = NULL;
60+
61+
if (algo != NULL && algo[0] != '\0') {
62+
for (i = 0; SUPPORTED_ALGORITHMS[i].name != NULL; i++) {
63+
if (strcmp(algo, SUPPORTED_ALGORITHMS[i].name) == 0) {
64+
selected_algo = &SUPPORTED_ALGORITHMS[i];
65+
break;
66+
}
67+
}
68+
}
2669

27-
// Generate a (not very) random seed. You should do it better than this...
28-
seed[0] = time(NULL);
29-
seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
70+
if (selected_algo == NULL) {
71+
selected_algo = &SUPPORTED_ALGORITHMS[DEFAULT_ALGORITHM];
72+
}
3073

31-
// Turn it into printable characters from `seedchars'.
32-
for (i = 0; i < 8; i++) {
33-
salt[3 + i] = seedchars[(seed[i / 5] >> (i % 5) * 6) & 0x3f];
74+
password = try_encrypt_password(words, selected_algo->prefix);
75+
if (password != NULL) {
76+
return password;
3477
}
3578

36-
// DES Encrypt
37-
password = crypt(words, salt);
79+
for (i = 0; SUPPORTED_ALGORITHMS[i].name != NULL; i++) {
80+
if (&SUPPORTED_ALGORITHMS[i] == selected_algo) {
81+
continue;
82+
}
3883

39-
return password;
84+
password = try_encrypt_password(words, SUPPORTED_ALGORITHMS[i].prefix);
85+
if (password != NULL) {
86+
return password;
87+
}
88+
}
89+
90+
return NULL;
4091
}
4192

4293
int lock_shadow_file() {

accounts1/users/passwd.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,25 @@ var (
3232
wLocker sync.Mutex
3333
)
3434

35+
var PasswdAlgoDefault = "sm3"
36+
3537
func EncodePasswd(words string) string {
38+
return CryptUserPassword(words, PasswdAlgoDefault)
39+
}
40+
41+
func CryptUserPassword(words string, algo string) string {
3642
cwords := C.CString(words)
3743
defer C.free(unsafe.Pointer(cwords))
3844

39-
return C.GoString(C.mkpasswd(cwords))
45+
calgo := C.CString(algo)
46+
defer C.free(unsafe.Pointer(calgo))
47+
48+
result := C.mkpasswd_with_algo(cwords, calgo)
49+
if result == nil {
50+
return ""
51+
}
52+
53+
return C.GoString(result)
4054
}
4155

4256
func ExistPwUid(uid uint32) int {

accounts1/users/passwd.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
#ifndef __PASSWORD_H__
66
#define __PASSWORD_H__
77

8-
char *mkpasswd(const char *words);
8+
#define PASSWD_ALGO_SHA512 "sha512"
9+
#define PASSWD_ALGO_SHA256 "sha256"
10+
#define PASSWD_ALGO_YESCRYPT "yescrypt"
11+
#define PASSWD_ALGO_SM3 "sm3"
12+
13+
char *mkpasswd_with_algo(const char *words, const char *algo);
914

1015
int lock_shadow_file();
1116
int unlock_shadow_file();

misc/dsg-configs/org.deepin.dde.daemon.account.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@
2121
"description": "Whether to allow local unlocking of the terminal",
2222
"permissions": "readwrite",
2323
"visibility": "private"
24+
},
25+
"passwordEncryptionAlgorithm": {
26+
"value": "sm3",
27+
"serial": 0,
28+
"flags": ["global"],
29+
"name": "passwordEncryptionAlgorithm",
30+
"name[zh_CN]": "密码加密算法",
31+
"description": "Password encryption algorithm (sha512, sha256, yescrypt, sm3(default))",
32+
"permissions": "readonly",
33+
"visibility": "private"
2434
}
2535
}
2636
}

0 commit comments

Comments
 (0)