-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4cd022c
Showing
9 changed files
with
1,178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
cmake_minimum_required(VERSION 3.2) | ||
project(neoterm-auth VERSION 1.3) | ||
|
||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") | ||
include_directories(${PROJECT_SOURCE_DIR}) | ||
|
||
find_library(LIB_CRYPTO crypto) | ||
|
||
add_library(neoterm-auth SHARED neoterm-auth.c) | ||
target_link_libraries(neoterm-auth ${LIB_CRYPTO}) | ||
install(TARGETS neoterm-auth DESTINATION lib) | ||
install(FILES ${PROJECT_SOURCE_DIR}/neoterm-auth.h DESTINATION include) | ||
|
||
add_executable(passwd passwd.c) | ||
target_link_libraries(passwd neoterm-auth) | ||
install(TARGETS passwd DESTINATION bin) | ||
|
||
add_executable(pwlogin pwlogin.c) | ||
target_link_libraries(pwlogin neoterm-auth) | ||
install(TARGETS pwlogin DESTINATION bin) | ||
|
||
add_executable(testauth testauth.c) | ||
target_link_libraries(testauth neoterm-auth) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# neoterm-auth | ||
This package contains functions which are used to allow password authentication in openssh and dropbear, in neoterm. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// | ||
// Password authentication utilities for NeoTerm | ||
// Copyright (C) 2018-2020 Leonid Plyushch <leonid.plyushch@gmail.com> | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
// | ||
|
||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <termios.h> | ||
#include <unistd.h> | ||
|
||
#include <openssl/sha.h> | ||
#include <openssl/evp.h> | ||
|
||
#include "neoterm-auth.h" | ||
|
||
static void erase_ptr(void *ptr, unsigned int len) { | ||
volatile char *p = ptr; | ||
|
||
if (ptr == NULL) { | ||
return; | ||
} | ||
|
||
while (len--) { | ||
*p++ = 0x0; | ||
} | ||
} | ||
|
||
// Hash password using PBKDF function. | ||
// Returns digest (in binary form) or NULL if failed. | ||
unsigned char *neoterm_passwd_hash(const char *password) { | ||
const unsigned char *salt = (const unsigned char *) "NeoTerm!"; | ||
unsigned char *pbkdf_digest; | ||
|
||
if ((pbkdf_digest = (unsigned char *) malloc(SHA_DIGEST_LENGTH * sizeof(unsigned char))) == NULL) { | ||
fprintf(stderr, "%s(): failed to allocate memory.\n", __func__); | ||
return NULL; | ||
} | ||
|
||
if (!PKCS5_PBKDF2_HMAC_SHA1(password, strlen(password), salt, | ||
strlen((const char *)salt), 65536, SHA_DIGEST_LENGTH, pbkdf_digest)) { | ||
return NULL; | ||
} | ||
|
||
return pbkdf_digest; | ||
} | ||
|
||
// Update file that stores password hash | ||
// Return true on success, false otherwise. | ||
bool neoterm_change_passwd(const char *new_password) { | ||
FILE *neoterm_auth_file; | ||
bool is_password_changed = false; | ||
|
||
unsigned char *hashed_password = neoterm_passwd_hash(new_password); | ||
if (!hashed_password) { | ||
return false; | ||
} | ||
|
||
if ((neoterm_auth_file = fopen(AUTH_HASH_FILE_PATH, "w")) != NULL) { | ||
int n = fwrite(hashed_password, sizeof(unsigned char), SHA_DIGEST_LENGTH, neoterm_auth_file); | ||
fflush(neoterm_auth_file); | ||
fclose(neoterm_auth_file); | ||
|
||
erase_ptr(hashed_password, n); | ||
|
||
if (n == SHA_DIGEST_LENGTH) { | ||
is_password_changed = true; | ||
} else { | ||
fprintf(stderr, "%s(): password hash is truncated.\n", __func__); | ||
} | ||
} | ||
|
||
free(hashed_password); | ||
|
||
return is_password_changed; | ||
} | ||
|
||
// Check validity of password (user name is ignored). | ||
// Return true if password is ok, otherwise return false. | ||
bool neoterm_auth(const char *user, const char *password) { | ||
FILE *neoterm_auth_file; | ||
unsigned char *auth_info; | ||
unsigned char *hashed_password; | ||
bool is_authenticated = false; | ||
|
||
if ((auth_info = (unsigned char *)malloc(SHA_DIGEST_LENGTH * sizeof(unsigned char))) == NULL) { | ||
fprintf(stderr, "%s(): failed to allocate memory.\n", __func__); | ||
return false; | ||
} | ||
|
||
if ((hashed_password = neoterm_passwd_hash(password)) == NULL) { | ||
free(auth_info); | ||
return false; | ||
} | ||
|
||
if ((neoterm_auth_file = fopen(AUTH_HASH_FILE_PATH, "rb")) != NULL) { | ||
int n = fread(auth_info, sizeof(unsigned char), SHA_DIGEST_LENGTH, neoterm_auth_file); | ||
fclose(neoterm_auth_file); | ||
|
||
if (n == SHA_DIGEST_LENGTH) { | ||
if (memcmp(auth_info, hashed_password, SHA_DIGEST_LENGTH) == 0) { | ||
is_authenticated = true; | ||
} | ||
} else { | ||
fprintf(stderr, "%s(): password hash is truncated.\n", __func__); | ||
} | ||
} | ||
|
||
erase_ptr(auth_info, SHA_DIGEST_LENGTH); | ||
erase_ptr(hashed_password, SHA_DIGEST_LENGTH); | ||
free(auth_info); | ||
free(hashed_password); | ||
|
||
return is_authenticated; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef NEOTERM_AUTH_H | ||
#define NEOTERM_AUTH_H | ||
|
||
#include <stdbool.h> | ||
|
||
#ifdef __ANDROID__ | ||
# ifndef NEOTERM_HOME | ||
# define NEOTERM_HOME "/data/data/com.neoterm/files/home" | ||
# endif | ||
# ifndef NEOTERM_PREFIX | ||
# define NEOTERM_PREFIX "/data/data/com.neoterm/files/usr" | ||
# endif | ||
# define AUTH_HASH_FILE_PATH NEOTERM_HOME "/.neoterm_authinfo" | ||
#else | ||
# define AUTH_HASH_FILE_PATH "/tmp/access_hash" | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// Hash password using PBKDF function. | ||
// Returns digest (in binary form) or NULL if failed. | ||
unsigned char *neoterm_passwd_hash(const char *password); | ||
|
||
// Update file that stores password hash | ||
// Return true on success, false otherwise. | ||
bool neoterm_change_passwd(const char *new_password); | ||
|
||
// Check validity of password (user name is ignored). | ||
// Return true if password is ok, otherwise return false. | ||
bool neoterm_auth(const char *user, const char *password); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// | ||
// Password authentication utilities for NeoTerm | ||
// Copyright (C) 2018-2020 Leonid Plyushch <leonid.plyushch@gmail.com> | ||
// | ||
// This program is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// This program is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
// | ||
|
||
/** Utility for setting new password **/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "neoterm-auth.h" | ||
|
||
static void erase_ptr(void *ptr, unsigned int len) { | ||
volatile char *p = ptr; | ||
|
||
if (ptr == NULL) { | ||
return; | ||
} | ||
|
||
while (len--) { | ||
*p++ = 0x0; | ||
} | ||
} | ||
|
||
static char *read_password(const char *prompt) { | ||
char *password; | ||
|
||
password = strdup(getpass(prompt)); | ||
|
||
if (!password) { | ||
fprintf(stderr, "Failed to read password input.\n"); | ||
return NULL; | ||
} | ||
|
||
if (strlen(password) == 0) { | ||
fprintf(stderr, "Password cannot be empty.\n"); | ||
return NULL; | ||
} | ||
|
||
return password; | ||
} | ||
|
||
int main(void) { | ||
char *password; | ||
char *password_confirmation; | ||
int ret = EXIT_FAILURE; | ||
|
||
password = read_password("New password: "); | ||
if (!password) { | ||
return ret; | ||
} | ||
|
||
password_confirmation = read_password("Retype new password: "); | ||
if (!password_confirmation) { | ||
return ret; | ||
} | ||
|
||
if(strcmp(password, password_confirmation) != 0) { | ||
erase_ptr(password, strlen(password)); | ||
erase_ptr(password_confirmation, strlen(password_confirmation)); | ||
free(password); | ||
free(password_confirmation); | ||
|
||
puts("Sorry, passwords do not match."); | ||
|
||
return ret; | ||
} | ||
|
||
if (neoterm_change_passwd(password)) { | ||
puts("New password was successfully set."); | ||
ret = EXIT_SUCCESS; | ||
} else { | ||
puts("Failed to set new password."); | ||
} | ||
|
||
erase_ptr(password, strlen(password)); | ||
erase_ptr(password_confirmation, strlen(password_confirmation)); | ||
free(password); | ||
free(password_confirmation); | ||
|
||
return EXIT_SUCCESS; | ||
} |
Oops, something went wrong.