Skip to content

Commit

Permalink
feat: Inital Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
juic3b0x committed Mar 28, 2024
0 parents commit 4cd022c
Show file tree
Hide file tree
Showing 9 changed files with 1,178 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*~
23 changes: 23 additions & 0 deletions CMakeLists.txt
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)
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
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.
129 changes: 129 additions & 0 deletions neoterm-auth.c
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;
}
38 changes: 38 additions & 0 deletions neoterm-auth.h
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
97 changes: 97 additions & 0 deletions passwd.c
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;
}
Loading

0 comments on commit 4cd022c

Please # to comment.