diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2020-12-10 23:17:40 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2020-12-10 23:17:40 +0100 |
| commit | 0978e237af3f26070b4824e09a7730aad44c3d0d (patch) | |
| tree | c72320f39b2e8c3e0f054bee5d582f15b6172e5a | |
| parent | 8e4cbe717397f38bd479a2dbe327adb5ae0baef8 (diff) | |
Make receiver work on sub directories
| -rw-r--r-- | receiver.cpp | 53 | ||||
| -rw-r--r-- | sender.c | 16 |
2 files changed, 49 insertions, 20 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 |
| 80 | enum { SESSION_ID_LENGTH = 8, AES_KEY_LENGTH = 16, GCM_IV_LENGTH = 16, GCM_TAG_LENGTH = 16, MIN_PACKET_SIZE = 40 }; | 82 | enum { SESSION_ID_LENGTH = 8, AES_KEY_LENGTH = 16, GCM_IV_LENGTH = 16, GCM_TAG_LENGTH = 16, MIN_PACKET_SIZE = 40 }; |
| 81 | enum { FILENAME_LENGTH = 73, SIDOFFS = 20, KEYOFFS = 37 }; | 83 | enum { DIRNAME_LENGTH = 10, FILENAME_LENGTH = 73, SIDOFFS = 20, KEYOFFS = 37 }; |
| 82 | 84 | ||
| 83 | class Session { | 85 | class Session { |
| 84 | public: | 86 | public: |
| 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 | ||
| 197 | static void import_sessions(const char *dirname) { | 207 | static 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(®ex, "^[[:digit:]]{4}-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]-" | 213 | if (regcomp(®ex, "^[[: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(®ex); | 239 | regfree(®ex); |
| 230 | } | 240 | } |
| 231 | 241 | ||
| 242 | static 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 | |||
| 232 | int main() { | 259 | int 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; |
| @@ -83,13 +83,6 @@ void new_session(int sock, mbedtls_ctr_drbg_context *ctr_drbg) { | |||
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | int main() { | 85 | int main() { |
| 86 | mbedtls_ctr_drbg_context ctr_drbg; | ||
| 87 | mbedtls_entropy_context entropy; | ||
| 88 | |||
| 89 | mbedtls_entropy_init(&entropy); | ||
| 90 | mbedtls_ctr_drbg_init(&ctr_drbg); | ||
| 91 | mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pp, sizeof(pp)); | ||
| 92 | |||
| 93 | struct addrinfo hints, *result, *rp; | 86 | struct addrinfo hints, *result, *rp; |
| 94 | memset (&hints, 0, sizeof (hints)); | 87 | memset (&hints, 0, sizeof (hints)); |
| 95 | hints.ai_socktype = SOCK_DGRAM; | 88 | hints.ai_socktype = SOCK_DGRAM; |
| @@ -109,10 +102,19 @@ int main() { | |||
| 109 | errx(EXIT_FAILURE, "Can't open socket"); | 102 | errx(EXIT_FAILURE, "Can't open socket"); |
| 110 | freeaddrinfo(result); | 103 | freeaddrinfo(result); |
| 111 | 104 | ||
| 105 | // Setup | ||
| 106 | mbedtls_ctr_drbg_context ctr_drbg; | ||
| 107 | mbedtls_entropy_context entropy; | ||
| 108 | |||
| 109 | mbedtls_entropy_init(&entropy); | ||
| 110 | mbedtls_ctr_drbg_init(&ctr_drbg); | ||
| 111 | mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pp, sizeof(pp)); | ||
| 112 | |||
| 112 | new_session(sock, &ctr_drbg); | 113 | new_session(sock, &ctr_drbg); |
| 113 | 114 | ||
| 114 | sleep(3); | 115 | sleep(3); |
| 115 | 116 | ||
| 117 | // Fire | ||
| 116 | const unsigned char *logline = (const unsigned char*)"Juchuuu, es klappt!\n"; | 118 | const unsigned char *logline = (const unsigned char*)"Juchuuu, es klappt!\n"; |
| 117 | send_udp(sock, &ctr_drbg, logline, strlen((char*)logline)); | 119 | send_udp(sock, &ctr_drbg, logline, strlen((char*)logline)); |
| 118 | send_udp(sock, &ctr_drbg, logline, strlen((char*)logline)); | 120 | send_udp(sock, &ctr_drbg, logline, strlen((char*)logline)); |
