summaryrefslogtreecommitdiff
path: root/receiver.cpp
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2020-12-10 23:17:40 +0100
committerDirk Engling <erdgeist@erdgeist.org>2020-12-10 23:17:40 +0100
commit0978e237af3f26070b4824e09a7730aad44c3d0d (patch)
treec72320f39b2e8c3e0f054bee5d582f15b6172e5a /receiver.cpp
parent8e4cbe717397f38bd479a2dbe327adb5ae0baef8 (diff)
Make receiver work on sub directories
Diffstat (limited to 'receiver.cpp')
-rw-r--r--receiver.cpp53
1 files changed, 40 insertions, 13 deletions
diff --git a/receiver.cpp b/receiver.cpp
index a3a0dc9..6be0f8a 100644
--- a/receiver.cpp
+++ b/receiver.cpp
@@ -7,6 +7,8 @@
7#include <fcntl.h> 7#include <fcntl.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <sys/socket.h> 9#include <sys/socket.h>
10#include <sys/stat.h>
11#include <limits.h>
10#include <netinet/in.h> 12#include <netinet/in.h>
11 13
12#include <mbedtls/pk.h> 14#include <mbedtls/pk.h>
@@ -78,15 +80,16 @@ static time_t now() {
78 80
79// Constants 81// Constants
80enum { SESSION_ID_LENGTH = 8, AES_KEY_LENGTH = 16, GCM_IV_LENGTH = 16, GCM_TAG_LENGTH = 16, MIN_PACKET_SIZE = 40 }; 82enum { SESSION_ID_LENGTH = 8, AES_KEY_LENGTH = 16, GCM_IV_LENGTH = 16, GCM_TAG_LENGTH = 16, MIN_PACKET_SIZE = 40 };
81enum { FILENAME_LENGTH = 73, SIDOFFS = 20, KEYOFFS = 37 }; 83enum { DIRNAME_LENGTH = 10, FILENAME_LENGTH = 73, SIDOFFS = 20, KEYOFFS = 37 };
82 84
83class Session { 85class Session {
84public: 86public:
85 Session(uint64_t session_id, uint8_t key[AES_KEY_LENGTH], const std::string &filename) : 87 Session(uint64_t session_id, uint8_t key[AES_KEY_LENGTH], const std::string &dirname, const std::string &filename) :
86 _session_id(session_id), _filename(filename) { 88 _session_id(session_id), _dirname(dirname), _filename(filename) {
87 memcpy(_key, key, AES_KEY_LENGTH); 89 memcpy(_key, key, AES_KEY_LENGTH);
88 mbedtls_gcm_init(&_ctx); 90 mbedtls_gcm_init(&_ctx);
89 mbedtls_gcm_setkey(&_ctx, MBEDTLS_CIPHER_ID_AES, _key, 8 * AES_KEY_LENGTH); 91 mbedtls_gcm_setkey(&_ctx, MBEDTLS_CIPHER_ID_AES, _key, 8 * AES_KEY_LENGTH);
92// std::cerr << "Imported file " << _filename << " in dir " << _dirname << std::endl;
90 } 93 }
91 94
92 Session(uint64_t session_id, uint8_t key[AES_KEY_LENGTH]) : _session_id(session_id) { 95 Session(uint64_t session_id, uint8_t key[AES_KEY_LENGTH]) : _session_id(session_id) {
@@ -98,7 +101,7 @@ public:
98 char tprefix[32]; 101 char tprefix[32];
99 time_t t = time(NULL); 102 time_t t = time(NULL);
100 struct tm * jetzt = localtime(&t); 103 struct tm * jetzt = localtime(&t);
101 size_t nlen = strftime(tprefix, sizeof(tprefix), "%F-%H-%M-%S", jetzt); 104 strftime(tprefix, sizeof(tprefix), "%F-%H-%M-%S", jetzt);
102 105
103 // Dump key 106 // Dump key
104 char hexkey[2*AES_KEY_LENGTH + 1]; 107 char hexkey[2*AES_KEY_LENGTH + 1];
@@ -107,18 +110,24 @@ public:
107 110
108 // Glue together serialisation 111 // Glue together serialisation
109 char filename[FILENAME_LENGTH + 1]; 112 char filename[FILENAME_LENGTH + 1];
110 snprintf(filename, sizeof(filename), "%s-%016" PRIx64 "-%s.log", tprefix, _session_id, hexkey); 113 size_t nlen = snprintf(filename, sizeof(filename), "%s-%016" PRIx64 "-%s.log", tprefix, _session_id, hexkey);
114 _filename = std::string(filename, filename + nlen);
111 115
112 // Touch file to save session_id and key 116 _dirname = std::string(filename, DIRNAME_LENGTH);
113 close(open(filename, O_WRONLY|O_CREAT, 0755));
114 117
115 _filename = std::string(filename, filename + FILENAME_LENGTH); 118 // Touch file to save session_id and key
119 close(ensure_file());
116 } 120 }
117 121
118 ~Session() { 122 ~Session() {
119 mbedtls_gcm_free(&_ctx); 123 mbedtls_gcm_free(&_ctx);
120 } 124 }
121 125
126 int ensure_file() {
127 mkdir(_dirname.c_str(), 0755);
128 return open((_dirname + "/" + _filename).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0755);
129 }
130
122 void write_log(const uint8_t *packet, size_t len) { 131 void write_log(const uint8_t *packet, size_t len) {
123 // First check if the packet holds enough space for session id, iv and at least one gcm block 132 // First check if the packet holds enough space for session id, iv and at least one gcm block
124 if (len < GCM_IV_LENGTH + GCM_TAG_LENGTH) { 133 if (len < GCM_IV_LENGTH + GCM_TAG_LENGTH) {
@@ -140,7 +149,7 @@ public:
140 149
141 // Create output file if it doesn't exist 150 // Create output file if it doesn't exist
142 if (_fd < 0) 151 if (_fd < 0)
143 _fd = ::open(_filename.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0755); 152 _fd = ensure_file();
144 if (_fd < 0) { 153 if (_fd < 0) {
145 std::cerr << "Error: Can't create file " << _filename << " for session " << std::hex << _session_id; 154 std::cerr << "Error: Can't create file " << _filename << " for session " << std::hex << _session_id;
146 return; 155 return;
@@ -179,6 +188,7 @@ private:
179 uint8_t _key[AES_KEY_LENGTH]; 188 uint8_t _key[AES_KEY_LENGTH];
180 int _fd = -1; 189 int _fd = -1;
181 time_t _last_access = 0; 190 time_t _last_access = 0;
191 std::string _dirname;
182 std::string _filename; 192 std::string _filename;
183 std::set<std::string> _used_ivs; 193 std::set<std::string> _used_ivs;
184 mbedtls_gcm_context _ctx; 194 mbedtls_gcm_context _ctx;
@@ -194,10 +204,10 @@ static uint8_t hex2nyble(char c)
194 : 0; 204 : 0;
195} 205}
196 206
197static void import_sessions(const char *dirname) { 207static void import_directory(const char *path, std::string dirname) {
198 DIR * dirp = opendir(dirname); 208 DIR * dirp = opendir(path);
199 if (!dirp) 209 if (!dirp)
200 errx(-1, "Fatal: Can't open dir %s\n", dirname); 210 errx(-1, "Fatal: Can't open dir %s\n", path);
201 211
202 regex_t regex; 212 regex_t regex;
203 if (regcomp(&regex, "^[[:digit:]]{4}-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-" 213 if (regcomp(&regex, "^[[:digit:]]{4}-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-"
@@ -223,12 +233,29 @@ static void import_sessions(const char *dirname) {
223 const char * hexkey = filename.c_str() + KEYOFFS; 233 const char * hexkey = filename.c_str() + KEYOFFS;
224 for (int i=0; i<16; ++i) 234 for (int i=0; i<16; ++i)
225 aeskey[i] = (hex2nyble(hexkey[2*i]) << 4 ) | hex2nyble(hexkey[2*i+1]); 235 aeskey[i] = (hex2nyble(hexkey[2*i]) << 4 ) | hex2nyble(hexkey[2*i+1]);
226 g_sessions[session_id] = std::make_unique<Session>(session_id, aeskey, filename); 236 g_sessions[session_id] = std::make_unique<Session>(session_id, aeskey, dirname, filename);
227 } 237 }
228 closedir(dirp); 238 closedir(dirp);
229 regfree(&regex); 239 regfree(&regex);
230} 240}
231 241
242static void import_sessions(const char *root_dir) {
243 char dirpath[PATH_MAX];
244 DIR * dirp = opendir(root_dir);
245 if (!dirp)
246 errx(-1, "Fatal: Can't open dir %s\n", root_dir);
247
248 struct dirent * entry;
249 while ((entry = readdir(dirp)) != NULL) {
250 if (entry->d_type != DT_DIR || entry->d_namlen != DIRNAME_LENGTH)
251 continue;
252 std::string dirname(entry->d_name, entry->d_name + entry->d_namlen);
253 snprintf(dirpath, PATH_MAX, "%s/%*s", root_dir, DIRNAME_LENGTH, entry->d_name);
254 import_directory(dirpath, dirname);
255 }
256 closedir(dirp);
257}
258
232int main() { 259int main() {
233 mbedtls_ctr_drbg_context ctr_drbg; 260 mbedtls_ctr_drbg_context ctr_drbg;
234 mbedtls_entropy_context entropy; 261 mbedtls_entropy_context entropy;