libaacs | branch: refs/tags/0.3.0 | npzacs <[email protected]> | Sun Sep 25 03:00:41 2011 +0300| [ef917b1cc51dfcea68f96d2e70b5b6034853d7cc] | committer: npzacs
Added simple caching for VUKs > http://git.videolan.org/gitweb.cgi/libaacs.git/?a=commit;h=ef917b1cc51dfcea68f96d2e70b5b6034853d7cc --- src/file/keydbcfg.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/file/keydbcfg.h | 6 +++ src/file/xdg.c | 25 +++++++++++ src/file/xdg.h | 1 + src/libaacs/aacs.c | 12 +++++ 5 files changed, 166 insertions(+) diff --git a/src/file/keydbcfg.c b/src/file/keydbcfg.c index d7b663e..3bf06e5 100644 --- a/src/file/keydbcfg.c +++ b/src/file/keydbcfg.c @@ -22,10 +22,12 @@ #ifndef _WIN32 # include "xdg.h" # define get_config_home xdg_get_config_home +# define get_cache_home xdg_get_cache_home # define get_config_system xdg_get_config_system #else # include "win32.h" # define get_config_home win32_get_config_home +# define get_cache_home(...) NULL # define get_config_system win32_get_config_system #endif @@ -37,6 +39,10 @@ #include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #define CFG_DIR "aacs" @@ -277,6 +283,122 @@ int keydbcfg_load_cert_file(config_file *cf) return result; } +static int _mkpath(const char *path) +{ + struct stat s; + int result = 1; + char *dir = str_printf("%s", path); + char *end = dir; + + while (*end == '/') + end++; + + while ((end = strchr(end, '/'))) { + *end = 0; + + if (stat(dir, &s) != 0 || !S_ISDIR(s.st_mode)) { + DEBUG(DBG_FILE, "Creating directory %s\n", dir); + + if (mkdir(dir, S_IRWXU|S_IRWXG|S_IRWXO) == -1) { + DEBUG(DBG_FILE, "Error creating directory %s\n", dir); + result = 0; + break; + } + } + + *end++ = '/'; + } + + X_FREE(dir); + + return result; +} + +char *_keycache_file(const char *type, const uint8_t *disc_id) +{ + const char *cache_dir = get_cache_home(); + char disc_id_str[41]; + + if (!cache_dir) { + return NULL; + } + + hex_array_to_hexstring(disc_id_str, disc_id, 20); + + return str_printf("%s/%s/%s/%s", cache_dir, CFG_DIR, type, disc_id_str); +} + +int keycache_save(const char *type, const uint8_t *disc_id, const uint8_t *key, unsigned int len) +{ + int result = 0; + char *file = _keycache_file(type, disc_id); + + if (file) { + if (_mkpath(file)) { + FILE *fp = fopen(file, "w"); + + if (fp) { + char *key_str = calloc(1, len*2 + 1); + hex_array_to_hexstring(key_str, key, len); + + if (fwrite(key_str, 1, len*2, fp) == len*2) { + DEBUG(DBG_FILE, "Wrote %s to %s\n", type, file); + result = 1; + + } else { + DEBUG(DBG_FILE, "Error writing to %s\n", file); + } + + free(key_str); + + fclose(fp); + } + } + + X_FREE(file); + } + + return result; +} + +int keycache_find(const char *type, const uint8_t *disc_id, uint8_t *key, unsigned int len) +{ + int result = 0; + char *file = _keycache_file(type, disc_id); + + if (file) { + FILE *fp = fopen(file, "r"); + + if (fp) { + char *key_str = malloc(len*2); + + DEBUG(DBG_FILE, "Reading %s\n", file); + + if (fread(key_str, 1, len*2, fp) == len*2) { + + result = hexstring_to_hex_array(key, len, key_str); + if (!result) { + DEBUG(DBG_FILE, "Error converting %s\n", file); + } + + } else { + DEBUG(DBG_FILE, "Error reading from %s\n", file); + } + + free(key_str); + + fclose(fp); + + } else { + DEBUG(DBG_FILE, "%s not found\n", file); + } + + X_FREE(file); + } + + return result; +} + char *keydbcfg_find_config_file(void) { static const char cfg_file_name[] = CFG_FILE_NAME; diff --git a/src/file/keydbcfg.h b/src/file/keydbcfg.h index 44e47f1..b71a2fa 100644 --- a/src/file/keydbcfg.h +++ b/src/file/keydbcfg.h @@ -22,6 +22,8 @@ #include <util/attributes.h> +#include <stdint.h> + /* struct holding a digit and key pair for <ENTRY NUMBER> - <ENTRY> entries */ typedef struct digit_key_pair_t digit_key_pair; struct digit_key_pair_t @@ -120,5 +122,9 @@ AACS_PRIVATE char *keydbcfg_find_config_file(void); AACS_PRIVATE int keydbcfg_load_cert_file(config_file *cf); AACS_PRIVATE int keydbcfg_load_pk_file(config_file *cf); +AACS_PRIVATE int keycache_save(const char *type, const uint8_t *disc_id, + const uint8_t *key, unsigned int len); +AACS_PRIVATE int keycache_find(const char *type, const uint8_t *disc_id, + uint8_t *key, unsigned int len); #endif diff --git a/src/file/xdg.c b/src/file/xdg.c index f99156b..bbb1dd2 100644 --- a/src/file/xdg.c +++ b/src/file/xdg.c @@ -32,6 +32,7 @@ */ #define USER_CFG_DIR ".config" +#define USER_CACHE_DIR ".cache" #define SYSTEM_CFG_DIR "/etc/xdg" @@ -59,6 +60,30 @@ const char *xdg_get_config_home(void) return dir; } +const char *xdg_get_cache_home(void) +{ + static char *dir = NULL; + static int init_done = 0; + + if (!init_done) { + init_done = 1; + + const char *xdg_cache = getenv("XDG_CACHE_HOME"); + if (xdg_cache && *xdg_cache) { + return dir = str_printf("%s", xdg_cache); + } + + const char *user_home = getenv("HOME"); + if (user_home && *user_home) { + return dir = str_printf("%s/%s", user_home, USER_CACHE_DIR); + } + + DEBUG(DBG_FILE, "Can't find user home directory ($HOME) !\n"); + } + + return dir; +} + const char *xdg_get_config_system(const char *dir) { static char *dirs = NULL; // "dir1\0dir2\0...\0dirN\0\0" diff --git a/src/file/xdg.h b/src/file/xdg.h index d36dd8a..d19db5c 100644 --- a/src/file/xdg.h +++ b/src/file/xdg.h @@ -24,5 +24,6 @@ AACS_PRIVATE const char *xdg_get_config_home(void); AACS_PRIVATE const char *xdg_get_config_system(const char *dir); +AACS_PRIVATE const char *xdg_get_cache_home(void); #endif diff --git a/src/libaacs/aacs.c b/src/libaacs/aacs.c index 9f9c206..a3f8af6 100644 --- a/src/libaacs/aacs.c +++ b/src/libaacs/aacs.c @@ -161,6 +161,12 @@ static int _calc_vuk(AACS *aacs, const char *path) if (memcmp(aacs->vuk, empty_key, 16)) return 1; + /* get cached vuk */ + if (keycache_find("vuk", aacs->disc_id, aacs->vuk, 16)) { + DEBUG(DBG_AACS, "Using cached VUK\n"); + return 1; + } + /* make sure we have media key */ if (!_calc_mk(aacs, path)) { return 0; @@ -185,6 +191,9 @@ static int _calc_vuk(AACS *aacs, const char *path) DEBUG(DBG_AACS, "Volume unique key: %s\n", print_hex(str, aacs->vuk, 16)); + /* cache vuk */ + keycache_save("vuk", aacs->disc_id, aacs->vuk, 16); + return 1; } @@ -227,6 +236,9 @@ static int _calc_vuk(AACS *aacs, const char *path) DEBUG(DBG_AACS, "Volume unique key: %s\n", print_hex(str, aacs->vuk, 16)); + /* cache vuk */ + keycache_save("vuk", aacs->disc_id, aacs->vuk, 16); + return 1; } _______________________________________________ libaacs-devel mailing list [email protected] http://mailman.videolan.org/listinfo/libaacs-devel
