* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* DSS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* dsscmd_encrypt.c
*
*
* IDENTIFICATION
* src/cmd/dsscmd_encrypt.c
*
* -------------------------------------------------------------------------
*/
#include "dsscmd_encrypt.h"
#include "cm_utils.h"
#include "dss_malloc.h"
#ifdef WIN32
#include <conio.h>
#else
#include <termios.h>
#endif
static int32 dss_get_one_char()
{
#ifdef WIN32
return _getch();
#else
size_t count;
int32 char_ascii;
struct termios oldt;
struct termios newt;
(void)tcgetattr(STDIN_FILENO, &oldt);
count = sizeof(newt);
MEMS_RETURN_IFERR(memcpy_s(&newt, count, &oldt, count));
newt.c_lflag &= ~(ECHO | ICANON | ECHOE | ECHOK | ECHONL | ICRNL);
newt.c_cc[VMIN] = 1;
newt.c_cc[VTIME] = 0;
(void)tcsetattr(STDIN_FILENO, TCSANOW, &newt);
char_ascii = getchar();
(void)tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return char_ascii;
#endif
}
status_t dss_receive_info_from_terminal(char *buff, int32 buff_size, bool32 is_plain_text)
{
int32 pos = 0;
char char_ascii;
int32 key = 0;
bool32 len_exceed = CM_FALSE;
CM_POINTER(buff);
do {
key = dss_get_one_char();
if (key < 0) {
(void)printf("invalid char which may be EOF found");
return CM_ERROR;
}
char_ascii = (char)key;
#ifdef WIN32
if (char_ascii == KEY_BS) {
#else
if (char_ascii == KEY_BS || char_ascii == KEY_BS_LNX) {
#endif
if (pos > 0) {
buff[pos] = '\0';
pos--;
* Recv a key of backspace, print a '\b' backing a char
and printing
* a space replacing the char displayed to screen
with the space.
*/
(void)printf("\b");
(void)printf(" ");
(void)printf("\b");
} else {
continue;
}
} else if (char_ascii == KEY_LF || char_ascii == KEY_CR) {
break;
} else {
* Only recv the limited length of pswd characters, on beyond,
* contine to get a next char entered by user.
*/
if (pos >= buff_size - 1) {
len_exceed = CM_TRUE;
continue;
}
if (is_plain_text) {
(void)printf("%c", char_ascii);
} else {
(void)printf("*");
}
buff[pos] = char_ascii;
pos++;
}
} while (CM_TRUE);
int32 end = pos < buff_size - 1 ? pos : buff_size - 1;
buff[end] = '\0';
(void)printf("\n");
if (len_exceed == CM_TRUE) {
(void)printf("invalid password, maximum length is %d\n", buff_size - 1);
return CM_ERROR;
}
return CM_SUCCESS;
}
status_t dss_verify_password_str(const char *text, const char *rptext)
{
uint32 len, rlen;
char *name = "sys";
CM_POINTER2(text, rptext);
len = (uint32)strlen(text);
rlen = (uint32)strlen(rptext);
if (len != rlen || strcmp(text, rptext) != 0) {
(void)printf("Input twice passwords are inconsistent.\n");
return CM_ERROR;
}
uint32 pwd_len = CM_PASSWD_MIN_LEN;
return cm_verify_password_str(name, text, pwd_len);
}
status_t dss_catch_input_text(char *plain, uint32 plain_size)
{
char first[CM_PASSWD_MAX_LEN + 1] = {0};
char second[CM_PASSWD_MAX_LEN + 1] = {0};
status_t ret;
errno_t errcode;
do {
(void)printf("Please enter password to encrypt: \n");
ret = dss_receive_info_from_terminal(first, (int32)sizeof(first), CM_FALSE);
DSS_BREAK_IF_ERROR(ret);
(void)printf("Please input password again: \n");
ret = dss_receive_info_from_terminal(second, (int32)sizeof(second), CM_FALSE);
DSS_BREAK_IF_ERROR(ret);
ret = dss_verify_password_str(first, second);
if (ret != CM_SUCCESS) {
(void)printf("1.password can't be more than 64 characters\n"
"2:password can't be less than %d characters\n"
"3.password should contain at least "
"three type the following characters:\n"
"A. at least one lowercase letter\n"
"B. at least one uppercase letter\n"
"C. at least one digit\n"
"D. at least one special character: `~!@#$%%^&*()-_=+\\|[{}]:\'\",<.>/? and space\n",
CM_PASSWD_MIN_LEN);
break;
}
errcode = memcpy_s(plain, plain_size, first, CM_PASSWD_MAX_LEN + 1);
if (errcode != EOK) {
ret = CM_ERROR;
CM_THROW_ERROR(ERR_SYSTEM_CALL, errcode);
break;
}
} while (0);
MEMS_RETURN_IFERR(memset_s(first, CM_PASSWD_MAX_LEN + 1, 0, CM_PASSWD_MAX_LEN + 1));
MEMS_RETURN_IFERR(memset_s(second, CM_PASSWD_MAX_LEN + 1, 0, CM_PASSWD_MAX_LEN + 1));
return ret;
}