From 56affbe423c2328a352ce61adc0b47af4bde8e93 Mon Sep 17 00:00:00 2001 From: /jedi/ Date: Wed, 5 Sep 2018 21:51:13 +0200 Subject: [PATCH] PW from cin --- .gitmodules | 3 ++ Makefile | 10 +++- libs/libsodium | 1 + rsa.cpp | 43 ---------------- src/Database.cpp | 75 +++++++++++++--------------- src/Database.h | 73 ++++++++++++++++----------- src/Manager.cpp | 88 ++++++++++++++++++++++++++++----- src/Manager.h | 10 +++- src/pwmgr.cpp | 126 ++++++++++++++++++++++++++--------------------- 9 files changed, 246 insertions(+), 183 deletions(-) create mode 100644 .gitmodules create mode 160000 libs/libsodium delete mode 100644 rsa.cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b6819e8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libs/libsodium"] + path = libs/libsodium + url = https://github.com/jedisct1/libsodium.git diff --git a/Makefile b/Makefile index 464c9a6..ff498fa 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ DEBUG = -g prefix=/usr/local -all: shepherd rsa +all: shepherd shepherd: src/*.cpp src/*.h mkdir -p bin @@ -18,6 +18,14 @@ rsa: rsa.cpp install: bin/shepherd install -m 0755 bin/shepherd $(prefix)/bin +.PHONY: test +test: + test/test.sh test/test.db + # remove produced files, invoke as "make clean" clean: rm -f bin/* + +#%.o : %.cpp +# $(CC) $(CFLAGS) -c $^ -o $@ + \ No newline at end of file diff --git a/libs/libsodium b/libs/libsodium new file mode 160000 index 0000000..11eef91 --- /dev/null +++ b/libs/libsodium @@ -0,0 +1 @@ +Subproject commit 11eef91e4924f0a8130731125db3a88cf605805c diff --git a/rsa.cpp b/rsa.cpp deleted file mode 100644 index ed2d30e..0000000 --- a/rsa.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -using namespace std; - -static const unsigned char key[] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f -}; - -int main() -{ - unsigned char text[]="hello world!"; - unsigned char enc_out[80]; - unsigned char dec_out[80]; - - AES_KEY enc_key, dec_key; - - AES_set_encrypt_key(key, 128, &enc_key); - AES_encrypt(text, enc_out, &enc_key); - - AES_set_decrypt_key(key,128,&dec_key); - AES_decrypt(enc_out, dec_out, &dec_key); - - int i; - - printf("original:\t"); - for(i=0;*(text+i)!=0x00;i++) - printf("%X ",*(text+i)); - printf("\nencrypted:\t"); - for(i=0;*(enc_out+i)!=0x00;i++) - printf("%X ",*(enc_out+i)); - printf("\ndecrypted:\t"); - for(i=0;*(dec_out+i)!=0x00;i++) - printf("%X ",*(dec_out+i)); - printf("\n"); - - return 0; -} diff --git a/src/Database.cpp b/src/Database.cpp index ba9d94d..2f542b8 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -1,56 +1,49 @@ #include -#include -#include #include "Database.h" using namespace std; -bool Database::open(string filename) -{ - if(sqlite3_open(filename.c_str(), &database) == SQLITE_OK) - return true; +bool Database::open(string filename) { + if (sqlite3_open(filename.c_str(), &database) == SQLITE_OK) + return true; - return false; + return false; } -vector > Database::query2(string query) -{ - sqlite3_stmt *statement; - vector > results; - if(!strcmp(query.c_str(),"")) return results; - if(sqlite3_prepare_v2(database, query.c_str(), -1, &statement, 0) == SQLITE_OK) - { - int cols = sqlite3_column_count(statement); - int result = 0; - while(true) - { - result = sqlite3_step(statement); +vector > Database::query2(string query) { + sqlite3_stmt *statement; + vector > results; + if (!strcmp(query.c_str(), "")) + return results; + if (sqlite3_prepare_v2(database, query.c_str(), -1, &statement, 0) + == SQLITE_OK) { + int cols = sqlite3_column_count(statement); + int result = 0; + while (true) { + result = sqlite3_step(statement); - if(result == SQLITE_ROW) - { - vector values; - for(int col = 0; col < cols; col++) - { - values.push_back((char*)sqlite3_column_text(statement, col)); - } - results.push_back(values); - } - else - { - break; - } - } + if (result == SQLITE_ROW) { + vector values; + for (int col = 0; col < cols; col++) { + values.push_back( + (char *) sqlite3_column_text(statement, col)); + } + results.push_back(values); + } else { + break; + } + } - sqlite3_finalize(statement); - } + sqlite3_finalize(statement); + } - string error = sqlite3_errmsg(database); - if(error != "not an error") cout << query << " " << error << endl; + string error = sqlite3_errmsg(database); + if (error != "not an error") + cout << query << " " << error << endl; - return results; + return results; } -void Database::close() -{ - sqlite3_close(database); +void Database::close() { + sqlite3_close(database); } diff --git a/src/Database.h b/src/Database.h index a568b68..c4db282 100644 --- a/src/Database.h +++ b/src/Database.h @@ -7,47 +7,62 @@ #include #include - using namespace std; -class Database{ +class Database { private: - sqlite3 *database; + sqlite3 *database; - class QueryStream : public std::ostream { - private: - class QueryBuf : public std::stringbuf { - private: - Database *m_db; - public: - QueryBuf(Database *db) { m_db = db;} - ~QueryBuf() { pubsync(); } - int sync() { - m_db->result = m_db->query2(str()); - str(""); - return 0; - } - }; + class QueryStream : public std::ostream { + private: + class QueryBuf : public std::stringbuf { + private: + Database *m_db; + public: + QueryBuf(Database *db) { + m_db = db; + } - public: - QueryStream(Database *db) : std::ostream(new QueryBuf(db)) {} - ~QueryStream() { delete rdbuf(); } - }; + ~QueryBuf() { + pubsync(); + } + + int sync() { + m_db->result = m_db->query2(str()); + str(""); + return 0; + } + }; + + public: + QueryStream(Database *db) : + std::ostream(new QueryBuf(db)) { + } + + ~QueryStream() { + delete rdbuf(); + } + }; public: - bool open(string filename); + bool open(string filename); + vector > query2(string query); - void close(); + + void close(); vector > result; - QueryStream query; + QueryStream query; - Database(const std::string& filename) : query(this) { - database = NULL; - open(filename); - }; - ~Database(){} + Database(const std::string &filename) : + query(this) { + database = NULL; + open(filename); + }; + + ~Database() { + } }; #endif diff --git a/src/Manager.cpp b/src/Manager.cpp index d3ae2fd..0ac1aa9 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -6,7 +6,6 @@ */ #include #include -#include #include "Manager.h" @@ -27,7 +26,7 @@ int Manager::add(string pattern, string passwd) { std::cmatch sm; if (regex_match(pattern.c_str(), sm, std::regex( - "^([a-zA-Z0-9]+):([a-zA-Z0-9/_\\.\\-]+)@([a-zA-Z0-9\\.\\-]+)$"))) { + "^([a-zA-Z0-9]+):([a-zA-Z0-9/_\\.\\-]+)@([a-zA-Z0-9/_\\.\\-]+)$"))) { db.query << "INSERT INTO passwd (type, user, host, passwd) VALUES('" << sm[1] << "', '" << sm[2] << "','" << sm[3] << "','" << passwd << "');" << flush; @@ -43,10 +42,16 @@ int Manager::add(string pattern, string passwd) { } int Manager::create(string pattern) { - cout << "12345" << endl; - db.query - << "INSERT INTO passwd (type, user, host, passwd) VALUES('http', 'fish','test.de','12345');" - << flush; + char charset[] = "ABCDEFGHIJKLMOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + int len = strlen(charset); + + string secret; + + for (int i = 0; i < 20; i++) { + secret += charset[rand() % len]; + } + cout << secret << endl; + add(pattern, secret); return 0; } @@ -65,13 +70,70 @@ int Manager::clear() { } int Manager::get(string pattern) { - db.query - << "SELECT type, user, host, passwd FROM passwd WHERE type='http' AND user='blub';" - << flush; - for (vector row : db.result) { - cout << row.at(0) << "://" << row.at(1) << "@" << row.at(2) << "\t" - << row.at(3) << endl; + std::cmatch sm; + if (regex_match(pattern.c_str(), sm, + std::regex( + "^([a-zA-Z0-9%]+):([a-zA-Z0-9%/_\\.\\-]+)@([a-zA-Z0-9%/_\\.\\-]+)$"))) { + db.query << "SELECT * FROM passwd WHERE 1"; + if (string("*").compare(sm[1]) != 0) + db.query << " AND type LIKE '" << sm[1] << "'"; + if (string("*").compare(sm[2]) != 0) + db.query << " AND user LIKE '" << sm[2] << "'"; + if (string("*").compare(sm[2]) != 0) + db.query << " AND host LIKE '" << sm[3] << "'"; + db.query << ";" << flush; + for (vector row : db.result) { + cout << row.at(0) << ":" << row.at(1) << "@" << row.at(2) << "\t" + << row.at(3) << endl; + } + return 0; + } else if (regex_match(pattern.c_str(), sm, + std::regex("^([a-zA-Z0-9]+):([a-zA-Z0-9/_\\.\\-]+)$"))) { + db.query + << "SELECT * FROM passwd WHERE (type, user, host, passwd) VALUES('" + << sm[1] << "', '" << sm[2] << "','" << sm[2] << "');" << flush; + for (vector row : db.result) { + cout << row.at(0) << ":" << row.at(1) << "@" << row.at(2) << "\t" + << row.at(3) << endl; + } + return 0; + } else { + cout << "fehler: " << pattern << endl; + return 1; + } +} + +int Manager::del(string pattern) { + std::cmatch sm; + if (regex_match(pattern.c_str(), sm, + std::regex( + "^([a-zA-Z0-9%]+):([a-zA-Z0-9%/_\\.\\-]+)@([a-zA-Z0-9%/_\\.\\-]+)$"))) { + db.query << "DELETE FROM passwd WHERE 1"; + if (string("*").compare(sm[1]) != 0) + db.query << " AND type LIKE '" << sm[1] << "'"; + if (string("*").compare(sm[2]) != 0) + db.query << " AND user LIKE '" << sm[2] << "'"; + if (string("*").compare(sm[2]) != 0) + db.query << " AND host LIKE '" << sm[3] << "'"; + db.query << ";" << flush; + for (vector row : db.result) { + cout << row.at(0) << ":" << row.at(1) << "@" << row.at(2) << "\t" + << row.at(3) << endl; + } + return 0; + } else if (regex_match(pattern.c_str(), sm, + std::regex("^([a-zA-Z0-9]+):([a-zA-Z0-9/_\\.\\-]+)$"))) { + db.query + << "DELETE FROM passwd WHERE (type, user, host, passwd) VALUES('" + << sm[1] << "', '" << sm[2] << "','" << sm[2] << "');" << flush; + for (vector row : db.result) { + cout << row.at(0) << ":" << row.at(1) << "@" << row.at(2) << "\t" + << row.at(3) << endl; + } + return 0; + } else { + cout << "fehler: " << pattern << endl; + return 1; } - return 0; } diff --git a/src/Manager.h b/src/Manager.h index cef2bf3..1ac5417 100644 --- a/src/Manager.h +++ b/src/Manager.h @@ -12,16 +12,24 @@ #include #include "Database.h" - class Manager { public: Manager(std::string); + ~Manager(); + int add(std::string pattern, std::string passwd); + int create(std::string pattern); + int show(); + int clear(); + int get(std::string pattern); + + int del(std::string pattern); + private: Database db; }; diff --git a/src/pwmgr.cpp b/src/pwmgr.cpp index d1a4d31..2f5045f 100644 --- a/src/pwmgr.cpp +++ b/src/pwmgr.cpp @@ -1,7 +1,6 @@ #include -#include #include -#include +#include #include #include "Manager.h" @@ -16,86 +15,103 @@ constexpr unsigned int arg(const char* str, int h = 0) { } int main(int argc, char *argv[]) { + srand(time(NULL)); int opt, index; - string file = "passwd.db"; + string file = getenv("HOME"); + file += "/.shepherd/passwd.db"; - const struct option longopts[] = { { "version", no_argument, 0, 'v' }, { - "help", no_argument, 0, 'h' }, { "reverse", no_argument, 0, 'r' }, { - "permanent", no_argument, 0, 's' }, { "debug", optional_argument, 0, - 'd' }, { "password", required_argument, 0, 'p' }, { "user", - required_argument, 0, 'u' }, { "interface", required_argument, 0, - 'i' }, { "header", required_argument, 0, 'b' }, { "hex", - required_argument, 0, 'x' }, { "file", required_argument, 0, 'f' }, - { "timeout", required_argument, 0, 't' }, { "wait", - required_argument, 0, 'w' }, { 0, 0, 0, 0 }, }; + const struct option longopts[] = { + {"version", no_argument, 0, 'v'}, + { + "help", no_argument, 0, 'h'}, + {"reverse", no_argument, 0, 'r'}, + { + "permanent", no_argument, 0, 's'}, + {"debug", optional_argument, 0, 'd'}, + { + "password", required_argument, 0, 'p'}, + {"user", required_argument, 0, 'u'}, + { + "interface", required_argument, 0, 'i'}, + {"header", required_argument, 0, 'b'}, + { + "hex", required_argument, 0, 'x'}, + {"file", required_argument, 0, 'f'}, + { + "timeout", required_argument, 0, 't'}, + {"wait", required_argument, 0, 'w'}, + { + 0, 0, 0, 0},}; while ((opt = getopt_long(argc, argv, "bhrvswxp:u:i:f:t:d::", longopts, &index)) != -1) { switch (opt) { - /*case 'h': - fprintf(stderr, VERSION); - fprintf(stderr, USAGE, argv[0]); - fprintf(stderr, HELP); - exit(EXIT_SUCCESS); - break; + /*case 'h': + fprintf(stderr, VERSION); + fprintf(stderr, USAGE, argv[0]); + fprintf(stderr, HELP); + exit(EXIT_SUCCESS); + break; - case 'v': - fprintf(stderr, VERSION); - exit(EXIT_SUCCESS); - break;*/ + case 'v': + fprintf(stderr, VERSION); + exit(EXIT_SUCCESS); + break;*/ - case 'r': - //options.flags |= FLAG_REVERSE; + case 'r': + //options.flags |= FLAG_REVERSE; break; - case 'd': - //options.flags |= FLAG_DEBUG; - //if (optarg != NULL) - // options.debug_level = atoi(optarg); + case 'd': + //options.flags |= FLAG_DEBUG; + //if (optarg != NULL) + // options.debug_level = atoi(optarg); break; - case 't': - //options.timeout = atol(optarg); + case 't': + //options.timeout = atol(optarg); break; - case 'f': - file = std::string(optarg); + case 'f': + file = std::string(optarg); break; - default: /* '?' */ - //cerr << "Unknown option" << endl; - //cerr << argv[0] << " " << endl; - exit (EXIT_FAILURE); + default: /* '?' */ + //cerr << "Unknown option" << endl; + //cerr << argv[0] << " " << endl; + exit(EXIT_FAILURE); } } Manager mg(file); switch (argc - optind) { - case 0: - mg.show(); + case 0: + mg.show(); break; - case 1: - if (!strcmp(argv[optind], "clear")) { - mg.clear(); - cerr << file << " cleared" << endl; - } else { + case 1: mg.get(argv[optind]); - } break; - case 2: - if (!strcmp(argv[optind], "new")) { - mg.create(argv[optind+1]); - } - break; - case 3: - if (!strcmp(argv[optind], "add")) { - mg.add(argv[optind+1], argv[optind+2]); - } else { - cerr << argv[0] << " " << endl; - } + case 2: + if (!strcmp(argv[optind], "clear")) { + if (!strcmp(argv[optind + 1], "all")) { + mg.clear(); + cerr << file << " cleared" << endl; + } + } else if (!strcmp(argv[optind], "gen")) { + mg.create(argv[optind + 1]); + } else if (!strcmp(argv[optind], "del")) { + mg.del(argv[optind + 1]); + } else if (!strcmp(argv[optind], "add")) { + string pw; + cout << argv[optind + 1] << ": " << flush; + cin >> pw; + mg.add(argv[optind + 1], pw); + } else { + cerr << argv[0] << " " << endl; + } break; } exit (EXIT_SUCCESS);