remove VS sln
This commit is contained in:
308
source/arg_func.cpp
Normal file
308
source/arg_func.cpp
Normal file
@@ -0,0 +1,308 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include "arg_func.h"
|
||||
#include "func.h"
|
||||
#include "win.h"
|
||||
#include "func.h"
|
||||
#include "buffer.h"
|
||||
#include "cryptography.h"
|
||||
|
||||
void print_args()
|
||||
{
|
||||
printf_s(" Usage:\n\n");
|
||||
printf_s(" password_manager.exe [flags]\n\n");
|
||||
printf_s(" Flags:\n\n");
|
||||
printf_s(" -h print this message\n");
|
||||
printf_s(" <label> get password of this label can use GLOB\n");
|
||||
printf_s(" -g <label> generate password of this label (or update if exists)\n");
|
||||
printf_s(" -i <label> input new password for this label (or update if exists)\n");
|
||||
printf_s(" -d <label> delete password of this label\n");
|
||||
printf_s(" -s <label> show password for this label\n");
|
||||
printf_s(" -u <label> update username for this label\n");
|
||||
printf_s(" -n <label> update label name\n");
|
||||
printf_s(" -l list all labels\n");
|
||||
printf_s(" -p print all passwords\n");
|
||||
printf_s(" -c change master password\n");
|
||||
printf_s(" -f <folder path> select save folder\n");
|
||||
}
|
||||
|
||||
Arg get_args(int argc, char** argv, char** label) {
|
||||
if (argc < 2)
|
||||
{
|
||||
print_args();
|
||||
return Arg::Error;
|
||||
}
|
||||
|
||||
if (!strcmp("-h", argv[1]))
|
||||
{
|
||||
print_args();
|
||||
return Arg::Error;
|
||||
}
|
||||
|
||||
if (!strcmp("-l", argv[1])) return Arg::List;
|
||||
if (!strcmp("-p", argv[1])) return Arg::Print_all_p;
|
||||
if (!strcmp("-c", argv[1])) return Arg::Change;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
*label = argv[1];
|
||||
return Arg::Get;
|
||||
}
|
||||
|
||||
*label = argv[2];
|
||||
|
||||
if (!strcmp("-g", argv[1])) return Arg::Generate;
|
||||
if (!strcmp("-d", argv[1])) return Arg::Delete;
|
||||
if (!strcmp("-i", argv[1])) return Arg::Input;
|
||||
if (!strcmp("-s", argv[1])) return Arg::Show;
|
||||
if (!strcmp("-u", argv[1])) return Arg::Username;
|
||||
if (!strcmp("-n", argv[1])) return Arg::Name;
|
||||
if (!strcmp("-f", argv[1])) return Arg::File;
|
||||
|
||||
return Arg::Error;
|
||||
}
|
||||
|
||||
std::optional<LoginInfoPointer> arg_get(Buffer& decrypted_buffer, const char* label)
|
||||
{
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
|
||||
if (pass < 0) {
|
||||
printf_s("Password not found\n");
|
||||
return {};
|
||||
}
|
||||
return get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
|
||||
}
|
||||
|
||||
std::optional<LoginInfoPointer> arg_new_password(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto, bool generate)
|
||||
{
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
|
||||
std::string username = "";
|
||||
std::string name = label;
|
||||
std::string password = "";
|
||||
|
||||
if (pass >= 0) {
|
||||
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
|
||||
username = lip.username;
|
||||
name = lip.label;
|
||||
delete_logininfo_from_buffer(decrypted_buffer, pass);
|
||||
}
|
||||
|
||||
printf_s("New password for %s: \n", name.c_str());
|
||||
|
||||
if (pass < 0)
|
||||
{
|
||||
printf_s("Input username: ");
|
||||
std::getline(std::cin, username);
|
||||
}
|
||||
|
||||
if (generate)
|
||||
{
|
||||
int default_length = 15;
|
||||
printf_s("Input password length [%d]: ", default_length);
|
||||
std::string input;
|
||||
int length = default_length;
|
||||
|
||||
std::getline(std::cin, input);
|
||||
if (!input.empty())
|
||||
{
|
||||
std::istringstream iss(input);
|
||||
if (!(iss >> length)) length = default_length;
|
||||
}
|
||||
|
||||
generate_password(password, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_s("Input new password: \n");
|
||||
password = get_user_password();
|
||||
if (password.empty())
|
||||
{
|
||||
printf_s("error getting password\n");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file();
|
||||
Index* index = (Index*)decrypted_buffer.buffer;
|
||||
return get_logininfo_pointer_from_buffer(decrypted_buffer, index->count - 1);
|
||||
}
|
||||
|
||||
void arg_username(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto)
|
||||
{
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
|
||||
if (pass < 0)
|
||||
{
|
||||
printf_s("LoginInfo not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
|
||||
std::string password = lip.password;
|
||||
std::string name = lip.label;
|
||||
|
||||
printf_s("Input username for %s: ", name.c_str());
|
||||
std::string username;
|
||||
std::getline(std::cin, username);
|
||||
|
||||
delete_logininfo_from_buffer(decrypted_buffer, pass);
|
||||
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file();
|
||||
}
|
||||
|
||||
void arg_label_name(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto)
|
||||
{
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
|
||||
|
||||
if (pass < 0)
|
||||
{
|
||||
printf_s("LoginInfo not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
|
||||
std::string password = lip.password;
|
||||
std::string username = lip.username;
|
||||
|
||||
printf_s("Input new label name for %s:", lip.label);
|
||||
std::string name;
|
||||
std::getline(std::cin, name);
|
||||
|
||||
delete_logininfo_from_buffer(decrypted_buffer, pass);
|
||||
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file();
|
||||
}
|
||||
|
||||
void arg_list(Buffer& decrypted_buffer)
|
||||
{
|
||||
Index* index = (Index*)decrypted_buffer.buffer;
|
||||
LoginInfo* pass = (LoginInfo*)(decrypted_buffer.buffer + sizeof(Index));
|
||||
|
||||
for (size_t i = 0; i < index->count; i++)
|
||||
{
|
||||
printf_s("label: %s\n", decrypted_buffer.buffer + pass[i].label + index->offset);
|
||||
}
|
||||
}
|
||||
|
||||
void arg_delete(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label_to_del, Cryptography& crypto)
|
||||
{
|
||||
printf_s("Deleting password for %s\n", label_to_del);
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label_to_del);
|
||||
if (pass < 0)
|
||||
{
|
||||
printf_s("Password not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
delete_logininfo_from_buffer(decrypted_buffer, pass);
|
||||
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file();
|
||||
printf_s("Password deleted\n");
|
||||
}
|
||||
|
||||
void arg_print_all_p(Buffer& decrypted_buffer, std::string& user_pass)
|
||||
{
|
||||
printf_s("Input main password for confirmation:");
|
||||
std::string new_string = get_user_password();
|
||||
if (new_string.empty())
|
||||
{
|
||||
printf_s("Error getting password\n");
|
||||
return;
|
||||
}
|
||||
if (new_string != user_pass)
|
||||
{
|
||||
printf_s("Wrong password\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Index* index = (Index*)decrypted_buffer.buffer;
|
||||
LoginInfo* pass = (LoginInfo*)(decrypted_buffer.buffer + sizeof(Index));
|
||||
|
||||
printf_s("\n");
|
||||
for (size_t i = 0; i < index->count; i++)
|
||||
{
|
||||
printf_s("label: %-10s\t\t", decrypted_buffer.buffer + pass[i].label + index->offset);
|
||||
printf_s("username: %-10s\t\t", decrypted_buffer.buffer + pass[i].username + index->offset);
|
||||
printf_s("password: %s\n", decrypted_buffer.buffer + pass[i].password + index->offset);
|
||||
}
|
||||
}
|
||||
|
||||
void arg_change(Buffer& decrypted_buffer, Buffer& encrypted_buffer, std::string& user_pass, Cryptography& crypto)
|
||||
{
|
||||
printf_s("Input main password for confirmation:");
|
||||
|
||||
std::string new_string = get_user_password();
|
||||
if (new_string.empty())
|
||||
{
|
||||
printf_s("Error getting password\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_string != user_pass)
|
||||
{
|
||||
printf_s("Passwords don't match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf_s("Input new password:");
|
||||
new_string = get_user_password();
|
||||
if (new_string.empty())
|
||||
{
|
||||
printf_s("Error getting password\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf_s("Input new password again:");
|
||||
user_pass = get_user_password();
|
||||
if (user_pass.empty())
|
||||
{
|
||||
printf_s("Error getting password\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_string != user_pass)
|
||||
{
|
||||
printf_s("Passwords don't match\n");
|
||||
return;
|
||||
}
|
||||
|
||||
crypto.generate_key_and_iv_from_password(new_string.c_str(), new_string.size());
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file();
|
||||
printf_s("Password changed\n");
|
||||
}
|
||||
|
||||
void arg_show(Buffer& decrypted_buffer, const char* label) {
|
||||
|
||||
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
|
||||
|
||||
if (pass < 0)
|
||||
printf_s("Password not found\n");
|
||||
else
|
||||
{
|
||||
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
|
||||
printf_s("Username: %s\n", lip.username);
|
||||
printf_s("Password: %s\n", lip.password);
|
||||
}
|
||||
}
|
||||
|
||||
void arg_file(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto, std::string& save_location_path)
|
||||
{
|
||||
std::string save(label);
|
||||
save.append("\\passwords.bin");
|
||||
|
||||
std::ofstream file(save_location_path, std::ios::binary);
|
||||
file << save << std::endl;
|
||||
file.close();
|
||||
|
||||
if (decrypted_buffer.taken <= sizeof(Index)) return;
|
||||
|
||||
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
|
||||
encrypted_buffer.save_to_file(save);
|
||||
}
|
146
source/buffer.cpp
Normal file
146
source/buffer.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "buffer.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
Buffer::Buffer()
|
||||
{
|
||||
buffer = nullptr;
|
||||
size = 0;
|
||||
taken = 0;
|
||||
}
|
||||
|
||||
Buffer::Buffer(size_t size)
|
||||
{
|
||||
this->size = size;
|
||||
this->buffer = new uint8_t[size];
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
if (buffer) delete[] buffer;
|
||||
}
|
||||
|
||||
bool Buffer::resize(size_t new_size)
|
||||
{
|
||||
if (size >= new_size) return true;
|
||||
uint8_t* new_buffer = (uint8_t*)realloc(buffer, new_size);
|
||||
if (!new_buffer)
|
||||
{
|
||||
printf_s("Error resizing buffer\n");
|
||||
return false;
|
||||
}
|
||||
buffer = new_buffer;
|
||||
size = new_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
int Buffer::add_end(uint8_t* data, size_t data_size)
|
||||
{
|
||||
if (taken + data_size > size)
|
||||
if (!resize(size + data_size)) return -1;
|
||||
|
||||
memcpy_s(buffer + taken, size - taken, data, data_size);
|
||||
taken += data_size;
|
||||
return taken - data_size;
|
||||
}
|
||||
|
||||
int Buffer::add_middle(uint8_t* data, size_t data_size, size_t index)
|
||||
{
|
||||
if (taken + data_size > size)
|
||||
if (!resize(size + data_size)) return -1;
|
||||
memmove_s(buffer + index + data_size, size - index - data_size, buffer + index, taken - index);
|
||||
memcpy_s(buffer + index, size - index, data, data_size);
|
||||
taken += data_size;
|
||||
return index;
|
||||
}
|
||||
|
||||
void Buffer::remove_fast(uint8_t* data, size_t data_size)
|
||||
{
|
||||
int64_t index = data - buffer;
|
||||
if (index < 0 || index > taken || index + data_size > taken)
|
||||
{
|
||||
printf_s("Error removing from buffer\n");
|
||||
return;
|
||||
}
|
||||
memmove_s(buffer + index, size - index, buffer + index + data_size, taken - index - data_size);
|
||||
taken -= data_size;
|
||||
}
|
||||
|
||||
void Buffer::remove(size_t index, size_t data_size)
|
||||
{
|
||||
if (index + data_size > taken)
|
||||
{
|
||||
printf_s("Error removing from buffer\n");
|
||||
return;
|
||||
}
|
||||
memmove_s(buffer + index, size - index, buffer + index + data_size, taken - index - data_size);
|
||||
taken -= data_size;
|
||||
}
|
||||
|
||||
size_t Buffer::find(uint8_t* data, size_t data_size)
|
||||
{
|
||||
for (size_t i = 0; i < taken; i++)
|
||||
if (memcmp(buffer + i, data, data_size) == 0)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Buffer::remove(uint8_t* data, size_t data_size)
|
||||
{
|
||||
size_t index = find(data, data_size);
|
||||
if (index == -1)
|
||||
{
|
||||
printf_s("Error removing from buffer\n");
|
||||
return;
|
||||
}
|
||||
remove(index, data_size);
|
||||
}
|
||||
|
||||
bool Buffer::save_to_file()
|
||||
{
|
||||
std::ofstream file(this->file_path, std::ios::binary | std::ios::out);
|
||||
if (!file.is_open())
|
||||
{
|
||||
printf_s("Error saving file\n");
|
||||
return false;
|
||||
}
|
||||
file.write((char*)this->buffer, this->taken);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::save_to_file(std::string file_path)
|
||||
{
|
||||
this->file_path = file_path;
|
||||
return save_to_file();
|
||||
}
|
||||
|
||||
bool Buffer::load_from_file()
|
||||
{
|
||||
std::ifstream file(this->file_path, std::ios::binary | std::ios::in);
|
||||
if (!file.is_open()) return false;
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
|
||||
size_t file_size = file.tellg();
|
||||
resize(file_size);
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read((char*)buffer, size);
|
||||
|
||||
if (file)
|
||||
taken = file_size;
|
||||
else
|
||||
taken = file.gcount();
|
||||
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::load_from_file(std::string file_path)
|
||||
{
|
||||
this->file_path = file_path;
|
||||
return load_from_file();
|
||||
}
|
||||
|
87
source/cryptography.cpp
Normal file
87
source/cryptography.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "cryptography.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
|
||||
Cryptography::Cryptography(const char* password, size_t size)
|
||||
{
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
|
||||
if (!generate_key_and_iv_from_password(password, size))
|
||||
{
|
||||
printf_s("Error generating key and IV from password\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Cryptography::~Cryptography()
|
||||
{
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
}
|
||||
|
||||
bool Cryptography::encrypt(Buffer* plain, Buffer* encrypted)
|
||||
{
|
||||
encrypted->resize(plain->taken + AES_BLOCK_SIZE);
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx) return handleErrors();
|
||||
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return handleErrors();
|
||||
|
||||
if (1 != EVP_EncryptUpdate(ctx, encrypted->buffer, (int*)&encrypted->taken, plain->buffer, plain->taken)) return handleErrors();
|
||||
int final_len;
|
||||
if (1 != EVP_EncryptFinal_ex(ctx, encrypted->buffer + encrypted->taken, &final_len)) return handleErrors();
|
||||
encrypted->taken += final_len;
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cryptography::decrypt(Buffer* encrypted, Buffer* decrypted)
|
||||
{
|
||||
decrypted->resize(encrypted->taken + AES_BLOCK_SIZE);
|
||||
|
||||
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (!ctx) return handleErrors();
|
||||
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return handleErrors();
|
||||
|
||||
if (1 != EVP_DecryptUpdate(ctx, decrypted->buffer, (int*)&decrypted->taken, encrypted->buffer, encrypted->taken)) return handleErrors();
|
||||
int final_len;
|
||||
if (1 != EVP_DecryptFinal_ex(ctx, decrypted->buffer + decrypted->taken, &final_len)) return handleErrors();
|
||||
decrypted->taken += final_len;
|
||||
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cryptography::generate_key_and_iv_from_password(const char* password, size_t size)
|
||||
{
|
||||
int iterations = 10000;
|
||||
|
||||
// Derive key and IV using PBKDF2
|
||||
if (1 != PKCS5_PBKDF2_HMAC(password, size, nullptr, 0, iterations, EVP_sha256(), 32, key)) return false;
|
||||
if (1 != PKCS5_PBKDF2_HMAC(password, size, nullptr, 0, iterations, EVP_sha256(), 16, iv)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cryptography::handleErrors()
|
||||
{
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
while (auto error = ERR_get_error())
|
||||
{
|
||||
char* error_string = ERR_error_string(error, nullptr);
|
||||
printf_s("%s\n", error_string);
|
||||
}
|
||||
return false;
|
||||
}
|
82
source/func.cpp
Normal file
82
source/func.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <ctime>
|
||||
#include "func.h"
|
||||
#include "glob.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
int find_logininfo_in_buffer(Buffer& buffer, const char* label)
|
||||
{
|
||||
Index* index = (Index*)buffer.buffer;
|
||||
LoginInfo* pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
|
||||
|
||||
for (size_t i = 0; i < index->count; i++)
|
||||
{
|
||||
if (glob(label, (const char*)buffer.buffer + pass[i].label + index->offset) == Glob_Result::MATCHED)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void delete_logininfo_from_buffer(Buffer& buffer, int index_of_pass)
|
||||
{
|
||||
Index* in_index = (Index*)buffer.buffer;
|
||||
LoginInfo* in_pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
|
||||
|
||||
int size_of_label = strlen((char*)buffer.buffer + in_pass[index_of_pass].label + in_index->offset) + 1;
|
||||
int size_of_username = strlen((char*)buffer.buffer + in_pass[index_of_pass].username + in_index->offset) + 1;
|
||||
int size_of_password = strlen((char*)buffer.buffer + in_pass[index_of_pass].password + in_index->offset) + 1;
|
||||
int size_pass = size_of_label + size_of_username + size_of_password;
|
||||
|
||||
uint8_t* start_of_pass = buffer.buffer + in_pass[index_of_pass].label + in_index->offset;
|
||||
buffer.remove_fast(start_of_pass, size_pass);
|
||||
|
||||
for (size_t i = index_of_pass; i < in_index->count; i++)
|
||||
{
|
||||
in_pass[i].label -= size_pass;
|
||||
in_pass[i].password -= size_pass;
|
||||
}
|
||||
|
||||
buffer.remove_fast((uint8_t*)&in_pass[index_of_pass], sizeof(LoginInfo));
|
||||
in_index->count -= 1;
|
||||
in_index->offset -= sizeof(LoginInfo);
|
||||
}
|
||||
|
||||
void add_logininfo_to_buffer(Buffer& buffer, const char* label, const char* username, const char* password)
|
||||
{
|
||||
int label_start = buffer.add_end((uint8_t*)label, strlen(label) + 1);
|
||||
int username_start = buffer.add_end((uint8_t*)username, strlen(username) + 1);
|
||||
int password_start = buffer.add_end((uint8_t*)password, strlen(password) + 1);
|
||||
|
||||
Index* index = (Index*)buffer.buffer;
|
||||
|
||||
label_start = label_start - index->offset;
|
||||
username_start = username_start - index->offset;
|
||||
password_start = password_start - index->offset;
|
||||
LoginInfo pass = { label_start, username_start, password_start };
|
||||
index->count++;
|
||||
index->offset += sizeof(LoginInfo);
|
||||
|
||||
buffer.add_middle((uint8_t*)&pass, sizeof(LoginInfo), index->offset - sizeof(LoginInfo));
|
||||
|
||||
}
|
||||
|
||||
LoginInfoPointer get_logininfo_pointer_from_buffer(Buffer& buffer, int index_of_pass)
|
||||
{
|
||||
Index* index = (Index*)buffer.buffer;
|
||||
LoginInfo* pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
|
||||
LoginInfoPointer ret;
|
||||
ret.label = (const char*)buffer.buffer + pass[index_of_pass].label + index->offset;
|
||||
ret.username = (const char*)buffer.buffer + pass[index_of_pass].username + index->offset;
|
||||
ret.password = (const char*)buffer.buffer + pass[index_of_pass].password + index->offset;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void generate_password(std::string& password, int len)
|
||||
{
|
||||
srand(time(NULL));
|
||||
char characters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_-+={[}]|:;<,>.?";
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
password += characters[rand() % (sizeof(characters) - 1)];
|
||||
}
|
||||
}
|
94
source/glob.cpp
Normal file
94
source/glob.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "glob.h"
|
||||
|
||||
Glob_Result glob(const char* pattern, const char* text)
|
||||
{
|
||||
while (*pattern != '\0' && *text != '\0') {
|
||||
switch (*pattern) {
|
||||
case '?': {
|
||||
pattern += 1;
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '*': {
|
||||
Glob_Result result = glob(pattern + 1, text);
|
||||
if (result != Glob_Result::UNMATCHED) return result;
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '[': {
|
||||
bool matched = false;
|
||||
bool negate = false;
|
||||
|
||||
pattern += 1; // skipping [
|
||||
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
|
||||
|
||||
if (*pattern == '!') {
|
||||
negate = true;
|
||||
pattern += 1;
|
||||
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
|
||||
}
|
||||
|
||||
char prev = *pattern;
|
||||
matched |= prev == *text;
|
||||
pattern += 1;
|
||||
|
||||
while (*pattern != ']' && *pattern != '\0') {
|
||||
switch (*pattern) {
|
||||
case '-': {
|
||||
pattern += 1;
|
||||
switch (*pattern) {
|
||||
case ']':
|
||||
matched |= '-' == *text;
|
||||
break;
|
||||
case '\0':
|
||||
return Glob_Result::SYNTAX_ERROR; // unclosed [
|
||||
default: {
|
||||
matched |= prev <= *text && *text <= *pattern;
|
||||
prev = *pattern;
|
||||
pattern += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
prev = *pattern;
|
||||
matched |= prev == *text;
|
||||
pattern += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*pattern != ']') return Glob_Result::SYNTAX_ERROR; // unclosed [
|
||||
if (negate) matched = !matched;
|
||||
if (!matched) return Glob_Result::UNMATCHED;
|
||||
|
||||
pattern += 1;
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
pattern += 1;
|
||||
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unfinished escape
|
||||
// fallthrough
|
||||
default: {
|
||||
if (*pattern == *text) {
|
||||
pattern += 1;
|
||||
text += 1;
|
||||
}
|
||||
else {
|
||||
return Glob_Result::UNMATCHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*text == '\0') {
|
||||
while (*pattern == '*') pattern += 1;
|
||||
if (*pattern == '\0') return Glob_Result::MATCHED;
|
||||
}
|
||||
|
||||
return Glob_Result::UNMATCHED;
|
||||
}
|
156
source/main.cpp
Normal file
156
source/main.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "win.h"
|
||||
#include "buffer.h"
|
||||
#include "cryptography.h"
|
||||
#include "func.h"
|
||||
#include "arg_func.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DEBUG 0
|
||||
#endif // DEBUG
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::string user_pass = "";
|
||||
char* label = nullptr;
|
||||
Arg args = Arg::Error;
|
||||
std::optional<std::string> save_location_path = std::nullopt;
|
||||
std::string save_location = "";
|
||||
|
||||
#if DEBUG
|
||||
|
||||
user_pass = "123";
|
||||
args = Arg::Print_all_p;
|
||||
std::string label_st = "facebook";
|
||||
label = label_st.data();
|
||||
save_location = "passwords.bin";
|
||||
|
||||
#else
|
||||
|
||||
args = get_args(argc, argv, &label);
|
||||
if (args == Arg::Error) return 1;
|
||||
|
||||
save_location_path = get_save_path();
|
||||
if (!save_location_path.has_value())
|
||||
{
|
||||
printf_s("Error geting file for save path\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::fstream ifile(save_location_path.value(), std::ios::binary || std::ios::in);
|
||||
if (ifile.is_open())
|
||||
{
|
||||
std::getline(ifile, save_location);
|
||||
ifile.close();
|
||||
}
|
||||
|
||||
if (save_location.empty() && args != Arg::File)
|
||||
{
|
||||
printf_s("No save location, try selecting folder (-f)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
Buffer encrypted_buffer;
|
||||
//load file
|
||||
if (!encrypted_buffer.load_from_file(save_location))
|
||||
// if file doesn't exist, check if it's a new password is being generated if not, exit
|
||||
if (!(args == Arg::Generate || args == Arg::Input || args == Arg::File)) {
|
||||
printf_s("No passwords, try generating password (-g or -i)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if !DEBUG
|
||||
printf_s("Input main password:");
|
||||
user_pass = get_user_password();
|
||||
if (user_pass.empty())
|
||||
{
|
||||
printf_s("Error getting password\n");
|
||||
return 1;
|
||||
}
|
||||
#endif // !1
|
||||
|
||||
Cryptography crypto(user_pass.c_str(), user_pass.size());
|
||||
|
||||
Buffer decrypted_buffer;
|
||||
//check if encrypted buffer is empty if not, decrypt it
|
||||
if (encrypted_buffer.size > 0)
|
||||
if (!crypto.decrypt(&encrypted_buffer, &decrypted_buffer)) return 1;
|
||||
|
||||
//if decrypted buffer is empty, add index
|
||||
if (decrypted_buffer.taken < sizeof(Index)) {
|
||||
Index index = { 0 };
|
||||
index.offset = sizeof(Index);
|
||||
decrypted_buffer.add_end((uint8_t*)&index, sizeof(Index));
|
||||
}
|
||||
|
||||
std::optional<LoginInfoPointer> login_info;
|
||||
|
||||
switch (args)
|
||||
{
|
||||
case Arg::Get:
|
||||
login_info = arg_get(decrypted_buffer, label);
|
||||
break;
|
||||
|
||||
case Arg::Generate:
|
||||
login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, true);
|
||||
break;
|
||||
|
||||
case Arg::List:
|
||||
arg_list(decrypted_buffer);
|
||||
break;
|
||||
|
||||
case Arg::Delete:
|
||||
arg_delete(decrypted_buffer, encrypted_buffer, label, crypto);
|
||||
break;
|
||||
|
||||
case Arg::Print_all_p:
|
||||
arg_print_all_p(decrypted_buffer, user_pass);
|
||||
break;
|
||||
|
||||
case Arg::Input:
|
||||
login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, false);
|
||||
break;
|
||||
|
||||
case Arg::Username:
|
||||
arg_username(decrypted_buffer, encrypted_buffer, label, crypto);
|
||||
break;
|
||||
|
||||
case Arg::Name:
|
||||
arg_label_name(decrypted_buffer, encrypted_buffer, label, crypto);
|
||||
break;
|
||||
|
||||
case Arg::Change:
|
||||
arg_change(decrypted_buffer, encrypted_buffer, user_pass, crypto);
|
||||
break;
|
||||
|
||||
case Arg::Show:
|
||||
arg_show(decrypted_buffer, label);
|
||||
break;
|
||||
|
||||
case Arg::File:
|
||||
arg_file(decrypted_buffer, encrypted_buffer, label, crypto, save_location_path.value());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!login_info.has_value()) return 0;
|
||||
|
||||
#if DEBUG
|
||||
|
||||
printf_s("Username: %s\n", login_info.value().username);
|
||||
printf_s("Password: %s\n", login_info.value().password);
|
||||
|
||||
#else
|
||||
|
||||
printf_s("Username: %s\n", login_info.value().username);
|
||||
put_data_on_clipboard(login_info.value().password);
|
||||
printf_s("Password copied to clipboard\n");
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
return 0;
|
||||
}
|
108
source/win.cpp
Normal file
108
source/win.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <Windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <shlobj.h>
|
||||
#include "win.h"
|
||||
#include "func.h"
|
||||
|
||||
bool put_data_on_clipboard(const char* text) {
|
||||
size_t len = strlen(text);
|
||||
if (len == 0) {
|
||||
printf_s("Text is empty\n");
|
||||
return false;
|
||||
}
|
||||
// Open the clipboard
|
||||
if (!OpenClipboard(nullptr)) {
|
||||
printf_s("Failed to open clipboard");
|
||||
return false;
|
||||
}
|
||||
// Allocate global memory for the text
|
||||
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
|
||||
if (!hMem) {
|
||||
CloseClipboard();
|
||||
printf_s("Failed to allocate memory for text");
|
||||
return false;
|
||||
}
|
||||
// Copy the text to the allocated memory
|
||||
char* memData = static_cast<char*>(GlobalLock(hMem));
|
||||
if (!memData) {
|
||||
CloseClipboard();
|
||||
printf_s("Failed to lock memory for text");
|
||||
return false;
|
||||
}
|
||||
strcpy_s(memData, strlen(text) + 1, text);
|
||||
GlobalUnlock(hMem);
|
||||
// Set the data to the clipboard
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_TEXT, hMem);
|
||||
// Clean up and close the clipboard
|
||||
CloseClipboard();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string get_user_password()
|
||||
{
|
||||
|
||||
HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
|
||||
// Create a restore point Mode
|
||||
// is know 503
|
||||
GetConsoleMode(hStdInput, &mode);
|
||||
|
||||
// Enable echo input
|
||||
// set to 499
|
||||
SetConsoleMode(hStdInput, mode & (~ENABLE_ECHO_INPUT));
|
||||
|
||||
// Take input
|
||||
std::string ipt;
|
||||
std::getline(std::cin, ipt);
|
||||
|
||||
// Otherwise next cout will print
|
||||
// into the same line
|
||||
std::cout << std::endl;
|
||||
|
||||
// Restore the mode
|
||||
SetConsoleMode(hStdInput, mode);
|
||||
|
||||
return ipt;
|
||||
}
|
||||
|
||||
std::optional<std::string> get_save_path()
|
||||
{
|
||||
PWSTR path = nullptr;
|
||||
|
||||
HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramData, 0, nullptr, &path);
|
||||
|
||||
if (!SUCCEEDED(result)) {
|
||||
CoTaskMemFree(path); // Free the allocated memory
|
||||
return{};
|
||||
}
|
||||
|
||||
std::wstring userDirectory(path);
|
||||
CoTaskMemFree(path); // Free the allocated memory
|
||||
|
||||
userDirectory.append(L"\\password_manager");
|
||||
|
||||
DWORD attrib = GetFileAttributes(userDirectory.c_str());
|
||||
|
||||
//check if it exists
|
||||
if(!(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY)))
|
||||
{
|
||||
if (!CreateDirectory(userDirectory.c_str(), nullptr)) return {};
|
||||
}
|
||||
|
||||
|
||||
userDirectory.append(L"\\save.txt");
|
||||
|
||||
int size = WideCharToMultiByte(CP_UTF8, 0, userDirectory.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (size > 0) {
|
||||
std::string str(size, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, userDirectory.c_str(), -1, &str[0], size, nullptr, nullptr);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
Reference in New Issue
Block a user