diff --git a/src/storage.c b/src/storage.c index c451c1c6..1c032e6c 100644 --- a/src/storage.c +++ b/src/storage.c @@ -37,6 +37,7 @@ #include +#include "common.h" #include "storage.h" #ifdef TEMP_FAILURE_RETRY @@ -191,6 +192,63 @@ static char *get_network_file_path(const char *type, const char *ssid) return path; } +char *storage_network_ssid_from_path(const char *path, enum security *type) +{ + const char *filename = strrchr(path, '/'); + const char *c, *end; + char *decoded; + static char buf[67]; + + if (filename) + filename++; /* Skip the / */ + else + filename = path; + + end = strchr(filename, '.'); + + if (!end || !security_from_str(end + 1, type)) + return NULL; + + if (filename[0] != '=') { + if (end == filename || end - filename > 32) + return NULL; + + for (c = filename; c < end; c++) + if (!isalnum(*c) && !strchr("-_ ", *c)) + break; + + if (c < end) + return NULL; + + memcpy(buf, filename, end - filename); + buf[end - filename] = '\0'; + + return buf; + } + + if (end - filename <= 1 || end - filename > 65) + return NULL; + + memcpy(buf, filename + 1, end - filename - 1); + buf[end - filename - 1] = '0'; + buf[end - filename + 0] = '0'; + buf[end - filename + 1] = '\0'; + + decoded = (char *) l_util_from_hexstring(buf, NULL); + if (!decoded) + return NULL; + + if (!l_utf8_validate(decoded, (end - filename) / 2, NULL)) { + l_free(decoded); + return NULL; + } + + strcpy(buf, decoded); + l_free(decoded); + + return buf; +} + struct l_settings *storage_network_open(const char *type, const char *ssid) { struct l_settings *settings; diff --git a/src/storage.h b/src/storage.h index ad6e5a6c..db61bd3a 100644 --- a/src/storage.h +++ b/src/storage.h @@ -21,6 +21,7 @@ */ struct l_settings; +enum security; int create_dirs(const char *filename); @@ -30,6 +31,8 @@ ssize_t read_file(void *buffer, size_t len, const char *path_fmt, ...) ssize_t write_file(const void *buffer, size_t len, const char *path_fmt, ...) __attribute__((format(printf, 3, 4))); +char *storage_network_ssid_from_path(const char *path, enum security *type); + struct l_settings *storage_network_open(const char *type, const char *ssid); int storage_network_touch(const char *type, const char *ssid); int storage_network_get_mtime(const char *type, const char *ssid,