pkcs15-tool: implemented --clear-cache (#873)

This commit is contained in:
Frank Morgner 2016-10-07 14:19:03 +02:00 committed by GitHub
parent 1893dcf3cb
commit 44694a0cf3
3 changed files with 106 additions and 3 deletions

View File

@ -138,6 +138,16 @@
<listitem><para>Disables token data caching.</para></listitem>
</varlistentry>
<varlistentry>
<term>
<option>--clear-cache</option>
</term>
<listitem><para>Removes the user's cache directory. On
Windows, this option additionally removes the system's
caching directory (requires administrator
privileges).</para></listitem>
</varlistentry>
<varlistentry>
<term>
<option>--output</option> <replaceable>filename</replaceable>,

View File

@ -22,5 +22,5 @@ $(TARGETS): $(OBJECTS) $(LIBS)
.c.exe:
cl $(COPTS) /c $<
link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib
link $(LINKFLAGS) /pdb:$*.pdb /out:$@ $*.obj $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib shell32.lib
if EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;1

View File

@ -18,10 +18,22 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <ctype.h>
#define _XOPEN_SOURCE 500
#include <assert.h>
#include <ctype.h>
#ifdef _WIN32
#ifdef __MINGW32__
// work around for https://sourceforge.net/p/mingw-w64/bugs/476/
#include <windows.h>
#endif
#include <shellapi.h>
#include <tchar.h>
#else
#include <ftw.h>
#endif
#include <stdio.h>
#ifdef ENABLE_OPENSSL
#if defined(HAVE_INTTYPES_H)
@ -46,6 +58,7 @@ static const char *app_name = "pkcs15-tool";
static int opt_wait = 0;
static int opt_no_cache = 0;
static int opt_clear_cache = 0;
static char * opt_auth_id = NULL;
static char * opt_reader = NULL;
static char * opt_cert = NULL;
@ -69,6 +82,7 @@ enum {
OPT_READER,
OPT_PIN_ID,
OPT_NO_CACHE,
OPT_CLEAR_CACHE,
OPT_LIST_PUB,
OPT_READ_PUB,
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
@ -120,6 +134,7 @@ static const struct option options[] = {
{ "verify-pin", no_argument, NULL, OPT_VERIFY_PIN },
{ "output", required_argument, NULL, 'o' },
{ "no-cache", no_argument, NULL, OPT_NO_CACHE },
{ "clear-cache", no_argument, NULL, OPT_CLEAR_CACHE },
{ "auth-id", required_argument, NULL, 'a' },
{ "aid", required_argument, NULL, OPT_BIND_TO_AID },
{ "wait", no_argument, NULL, 'w' },
@ -157,6 +172,7 @@ static const char *option_help[] = {
"Verify PIN after card binding (without 'auth-id' the first non-SO, non-Unblock PIN will be verified)",
"Outputs to file <arg>",
"Disable card caching",
"Clear card caching",
"The auth ID of the PIN to use",
"Specify AID of the on-card PKCS#15 application to bind to (in hexadecimal form)",
"Wait for card insertion",
@ -1134,6 +1150,73 @@ static u8 * get_pin(const char *prompt, sc_pkcs15_object_t *pin_obj)
}
}
#ifdef _WIN32
static int clear_cache(void)
{
TCHAR dirname[PATH_MAX];
SHFILEOPSTRUCT fileop;
int r;
fileop.hwnd = NULL; // no status display
fileop.wFunc = FO_DELETE; // delete operation
fileop.pFrom = dirname; // source file name as double null terminated string
fileop.pTo = NULL; // no destination needed
fileop.fFlags = FOF_NOCONFIRMATION|FOF_SILENT; // do not prompt the user
fileop.fAnyOperationsAborted = FALSE;
fileop.lpszProgressTitle = NULL;
fileop.hNameMappings = NULL;
/* remove the user's cache directory */
if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
return r;
dirname[_tcslen(dirname)+1] = 0;
printf("Deleting %s...", dirname);
r = SHFileOperation(&fileop);
if (r == 0) {
printf(" OK\n");
} else {
printf(" Error\n");
}
_tcscpy(dirname, _T("C:\\Windows\\System32\\config\\systemprofile\\eid-cache"));
dirname[_tcslen(dirname)+1] = 0;
printf("Deleting %s...", dirname);
r = SHFileOperation(&fileop);
if (r == 0) {
printf(" OK\n");
} else {
printf(" Error\n");
}
return r;
}
#else
int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
int r = remove(fpath);
if (r)
perror(fpath);
return r;
}
static int clear_cache(void)
{
char dirname[PATH_MAX];
int r = 0;
/* remove the user's cache directory */
if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
return r;
r = nftw(dirname, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
return r;
}
#endif
static int verify_pin(void)
{
struct sc_pkcs15_object *pin_obj = NULL;
@ -1908,6 +1991,10 @@ int main(int argc, char * const argv[])
case OPT_NO_CACHE:
opt_no_cache++;
break;
case OPT_CLEAR_CACHE:
opt_clear_cache = 1;
action_count++;
break;
case 'w':
opt_wait = 1;
break;
@ -1934,6 +2021,12 @@ int main(int argc, char * const argv[])
return 1;
}
if (opt_clear_cache) {
if ((err = clear_cache()))
goto end;
action_count--;
}
if (verbose > 1) {
ctx->debug = verbose;
sc_ctx_log_to_file(ctx, "stderr");