password_manager/source/arg_func.cpp
2024-07-22 16:12:04 +02:00

392 lines
9.7 KiB
C++

#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstring>
#include <filesystem>
#include <vector>
#include <algorithm>
#include "arg_func.hpp"
#include "func.hpp"
#include "environment.hpp"
#include "func.hpp"
#include "buffer.hpp"
#include "aes256.hpp"
#include "editor.hpp"
void print_args()
{
printf(" Usage:\n\n");
printf(" password_manager.exe [flags]\n\n");
printf(" Flags:\n\n");
printf(" -h print this message\n");
printf(" <label> get password for this label can use GLOB\n");
printf(" -g <label> generate password for this label (or update if exists)\n");
printf(" -i <label> input new password for this label (or update if exists)\n");
printf(" -d <label> delete password for this label\n");
printf(" -s <label> show password for this label\n");
printf(" -u <label> update username for this label\n");
printf(" -n <label> update label name\n");
printf(" -e <label> open editor, password as note\n");
printf(" -l list all labels\n");
printf(" -p print all passwords\n");
printf(" -c change master password\n");
printf(" -z print size of file\n");
printf(" -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 (argv[1][0] != '-')
{
*label = argv[1];
return Arg::Get;
}
switch (argv[1][1])
{
case 'h':
print_args();
return Arg::Error;
case 'l':
return Arg::List;
case 'p':
return Arg::Print_all_p;
case 'c':
return Arg::Change;
case 'z':
return Arg::Size;
}
if (argc != 3)
return Arg::Error;
*label = argv[2];
switch (argv[1][1])
{
case 'g':
return Arg::Generate;
case 'd':
return Arg::Delete;
case 'i':
return Arg::Input;
case 's':
return Arg::Show;
case 'u':
return Arg::Username;
case 'n':
return Arg::Name;
case 'f':
return Arg::File;
case 'e':
return Arg::Editor;
default:
return Arg::Error;
break;
}
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("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, std::string &key, 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("New password for %s: \n", name.c_str());
if (pass < 0)
{
printf("Input username: ");
std::getline(std::cin, username);
}
if (generate)
{
int default_length = 15;
printf("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;
}
if (!generate_password(password, length))
{
printf("error generating password\n");
return {};
}
}
else
{
printf("Input new password: ");
password = get_user_password();
if (password.empty())
{
printf("error getting password\n");
return {};
}
}
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), name.size(), username.c_str(), username.size(), password.c_str(), password.size());
Aes256::encrypt(key, 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, std::string &key)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0)
{
printf("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("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(), name.size(), username.c_str(), username.size(), password.c_str(), password.size());
Aes256::encrypt(key, decrypted_buffer, encrypted_buffer);
encrypted_buffer.save_to_file();
}
void arg_label_name(Buffer &decrypted_buffer, Buffer &encrypted_buffer, const char *label, std::string &key)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0)
{
printf("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("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(), name.size(), username.c_str(), username.size(), password.c_str(), password.size());
Aes256::encrypt(key, 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));
std::vector<std::string> list;
for (size_t i = 0; i < index->count; i++)
{
list.emplace_back(std::string((char *)decrypted_buffer.buffer + pass[i].label + index->offset));
}
std::sort(list.begin(), list.end());
for (auto &&str : list)
{
printf("%s\n", str.c_str());
}
}
void arg_delete(Buffer &decrypted_buffer, Buffer &encrypted_buffer, const char *label_to_del, std::string &key)
{
printf("Deleting password for %s\n", label_to_del);
int pass = find_logininfo_in_buffer(decrypted_buffer, label_to_del);
if (pass < 0)
{
printf("Password not found\n");
return;
}
delete_logininfo_from_buffer(decrypted_buffer, pass);
Aes256::encrypt(key, decrypted_buffer, encrypted_buffer);
encrypted_buffer.save_to_file();
printf("Password deleted\n");
}
void arg_print_all_p(Buffer &decrypted_buffer, std::string &user_pass)
{
printf("Input main password for confirmation:");
std::string new_string = get_user_password();
if (new_string.empty())
{
printf("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf("Wrong password\n");
return;
}
Index *index = (Index *)decrypted_buffer.buffer;
LoginInfo *pass = (LoginInfo *)(decrypted_buffer.buffer + sizeof(Index));
printf("\n");
for (size_t i = 0; i < index->count; i++)
{
printf("label: %-20s\t", decrypted_buffer.buffer + pass[i].label + index->offset);
printf("username: %-30s\t", decrypted_buffer.buffer + pass[i].username + index->offset);
printf("password: %s\n", decrypted_buffer.buffer + pass[i].password + index->offset);
}
}
void arg_change(Buffer &decrypted_buffer, Buffer &encrypted_buffer, std::string &user_pass)
{
printf("Input main password for confirmation:");
std::string new_string = get_user_password();
if (new_string.empty())
{
printf("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf("Passwords don't match\n");
return;
}
printf("Input new password:");
new_string = get_user_password();
if (new_string.empty())
{
printf("Error getting password\n");
return;
}
printf("Input new password again:");
user_pass = get_user_password();
if (user_pass.empty())
{
printf("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf("Passwords don't match\n");
return;
}
Aes256::encrypt(new_string, decrypted_buffer, encrypted_buffer);
encrypted_buffer.save_to_file();
printf("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("Password not found\n");
else
{
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
printf("Username: %s\n", lip.username);
printf("Password: %s\n", lip.password);
}
}
void arg_file(Buffer &decrypted_buffer, Buffer &encrypted_buffer, const char *label, std::string &key, std::string &save_location_path)
{
namespace fs = std::filesystem;
fs::path save(label);
save /= "passwords.bin";
std::ofstream file(save_location_path, std::ios::binary);
file << save.string() << std::endl;
file.close();
if (decrypted_buffer.taken <= sizeof(Index))
return;
Aes256::encrypt(key, decrypted_buffer, encrypted_buffer);
encrypted_buffer.save_to_file(save.string());
}
void arg_size(Buffer &encrypted_buffer)
{
printf("File size is: %zuB\n", encrypted_buffer.taken);
}
void arg_editor(Buffer &decrypted_buffer, Buffer &encrypted_buffer, const char *label_to_del, std::string &key)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label_to_del);
if (pass < 0)
{
printf("Password not found\n");
return;
}
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
int len = 0;
char *new_buff = edit_file(lip.password, len);
if (new_buff == nullptr)
{
return;
}
std::string lable = lip.label;
std::string username = lip.username;
delete_logininfo_from_buffer(decrypted_buffer, pass);
add_logininfo_to_buffer(decrypted_buffer, lable.c_str(), lable.size(), username.c_str(), username.size(), new_buff, len);
Aes256::encrypt(key, decrypted_buffer, encrypted_buffer);
encrypted_buffer.save_to_file();
}