Navigation Menu

Skip to content

Commit

Permalink
Added experimental support for using a "trusted device."
Browse files Browse the repository at this point in the history
This might be a terrible idea, just experimenting here.
  • Loading branch information
icculus committed Nov 9, 2015
1 parent de06503 commit 3b807fa
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 6 deletions.
59 changes: 57 additions & 2 deletions 1pass.c
Expand Up @@ -8,14 +8,15 @@
#include <unistd.h>
#include <dirent.h>
#include <signal.h>

#include <mntent.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "pkcs5_pbkdf2.h"
#include "aes.h"
#include "base64.h"
#include "md5.h"
#include "sha256.h"
#include "keyhook.h"

#include <gtk/gtk.h>
Expand Down Expand Up @@ -363,6 +364,24 @@ static int decryptBase64UsingKey(lua_State *L)
} // decryptBase64UsingKey


static void calcSha256(const BYTE *buf, const size_t len, BYTE *hash)
{
SHA256_CTX sha256;
sha256_init(&sha256);
sha256_update(&sha256, buf, len);
sha256_final(&sha256, hash);
} // calcSha256

static int calcSha256_Lua(lua_State *L)
{
size_t len = 0;
const char *str = luaL_checklstring(L, 1, &len);
BYTE hash[32];
calcSha256(str, len, hash);
return retvalStringBytes(L, hash, sizeof (hash));
} // calcSha256_Lua


static int runGuiPasswordPrompt(lua_State *L)
{
const char *hintstr = lua_tostring(L, 1);
Expand Down Expand Up @@ -539,7 +558,18 @@ static int guiAddMenuItem(lua_State *L)
{
GtkWidget *vbox = (GtkWidget *) lua_touserdata(L, 1);
const char *label = luaL_checkstring(L, 2);
const int callback = makeLuaCallback(L, 3);
const int checked = lua_toboolean(L, 3);
const int callback = makeLuaCallback(L, 4);

if (checked)
{
// !!! FIXME: this is pretty lousy.
const size_t len = strlen(label) + 5;
char *buf = (char *) alloca(len);
snprintf(buf, len, "[X] %s", label);
label = buf;
} // if

GtkWidget *item = GTK_WIDGET(gtk_button_new_with_label(label));
g_signal_connect(item, "key-press-event", G_CALLBACK(checkForEscapeKey), NULL);
g_signal_connect(item, "clicked", G_CALLBACK(clickedMenuItem), (gpointer) ((size_t)callback));
Expand Down Expand Up @@ -662,6 +692,29 @@ static int giveControlToGui(lua_State *L)
} // giveControlToGui


static int getMountedDisks(lua_State *L)
{
lua_newtable(L);
int luai = 1;

FILE *mounts = setmntent("/etc/mtab", "r");
if (mounts != NULL)
{
struct mntent *ent = NULL;
while ((ent = getmntent(mounts)) != NULL)
{
lua_pushinteger(luaState, luai);
lua_pushstring(luaState, ent->mnt_dir);
lua_settable(luaState, -3);
luai++;
} // while
endmntent(mounts);
} // if

return 1; // return the table.
} // getMountedDisks


static void *luaAlloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
if (nsize == 0)
Expand Down Expand Up @@ -717,6 +770,8 @@ static int initLua(const int argc, char **argv)
luaSetCFunc(luaState, runGuiPasswordPrompt, "runGuiPasswordPrompt");
luaSetCFunc(luaState, copyToClipboard, "copyToClipboard");
luaSetCFunc(luaState, setPowermateLED_Lua, "setPowermateLED");
luaSetCFunc(luaState, calcSha256_Lua, "calcSha256");
luaSetCFunc(luaState, getMountedDisks, "getMountedDisks");

luaSetCFunc(luaState, guiCreateTopLevelMenu, "guiCreateTopLevelMenu");
luaSetCFunc(luaState, guiCreateSubMenu, "guiCreateSubMenu");
Expand Down
93 changes: 89 additions & 4 deletions 1pass.lua
Expand Up @@ -52,7 +52,7 @@ local function load_json(fname)
return nil
end

local str = f:read("*all")
local str = f:read("*a")
f:close()

return load_json_str(str, fname)
Expand Down Expand Up @@ -102,7 +102,7 @@ local function getHint()
return
end

local str = "(hint is '" .. f:read("*all") .. "')."
local str = "(hint is '" .. f:read("*a") .. "')."
f:close()
--print(str)
return str
Expand Down Expand Up @@ -131,6 +131,9 @@ local function setMenuItemSubmenu(menuitem, submenu)
menuitem["submenu"] = submenu
end

local function setMenuItemChecked(menuitem, ischecked)
menuitem["checked"] = ischecked
end


local function build_secret_menuitem(menu, type, str, hidden)
Expand Down Expand Up @@ -423,7 +426,7 @@ local function buildGuiMenuItem(guimenu, item)
return spawnSubMenu(button, submenu, depth)
end
end
guiAddMenuItem(guimenu, item["text"], cb)
guiAddMenuItem(guimenu, item["text"], item["checked"], cb)
end

buildGuiMenuList = function(guimenu, list)
Expand Down Expand Up @@ -494,6 +497,71 @@ local function launchGuiMenu(topmenu)
guiShowWindow(guimenu)
end

local trustedDisks = {}

local function getTrustedDiskChecksumPath(mntpoint)
return mntpoint .. "/1pass.dat"
end

local function getTrustedDiskChecksum(mntpoint)
local f = io.open(getTrustedDiskChecksumPath(mntpoint), "rb")
if f == nil then
return nil
end

local str = f:read("*a")
f:close()
return calcSha256(str)
end

local function choseTrustedDisk(mntpoint)
if trustedDisks[mntpoint] ~= nil then
trustedDisks[mntpoint] = nil -- no longer check existing trusted disk.
else
-- !!! FIXME: probably needs a message box if this fails.
local checksum = getTrustedDiskChecksum(mntpoint)
-- No checksum file yet? Generate and write out a random string.
if checksum == nil then
local f = io.open("/dev/urandom", "rb")
if f ~= nil then
local str = f:read(4096)
f:close()
if (str ~= nil) and (#str == 4096) then
f = io.open(getTrustedDiskChecksumPath(mntpoint), "wb")
if f ~= nil then
if f:write(str) and f:flush() then
checksum = calcSha256(str)
end
f:close()
end
end
end
end
trustedDisks[mntpoint] = checksum
end

-- kill the popup if it exists.
-- !!! FIXME: put this in its own function, this is a copy/paste from elsewhere.
if (keyhookGuiMenus ~= nil) and (keyhookGuiMenus[1] ~= nil) then
guiDestroyMenu(keyhookGuiMenus[1])
end
end

local function buildTrustedDeviceMenu()
local menu = makeMenu()
local disks = getMountedDisks() -- this is a C function.

table.sort(disks, function(a, b) return a < b end)
for i,v in ipairs(disks) do
local item = appendMenuItem(menu, v, function() choseTrustedDisk(v) end)
if trustedDisks[v] ~= nil then
setMenuItemChecked(item, true)
end
end

return menu
end

function keyhookPressed() -- not local! Called from C!
--print("keyhookPressed: running==" .. tostring(keyhookRunning))
if keyhookRunning then
Expand All @@ -502,6 +570,20 @@ function keyhookPressed() -- not local! Called from C!

keyhookRunning = true

local allowaccess = true;
for mntpoint,checksum in pairs(trustedDisks) do
if getTrustedDiskChecksum(mntpoint) ~= checksum then
allowaccess = false
break
end
end

if not allowaccess then
-- !!! FIXME: probably needs a message box if this happens.
keyhookRunning = false
return
end

while password == nil do
password = runGuiPasswordPrompt(getHint())
if password == nil then
Expand All @@ -528,11 +610,14 @@ function keyhookPressed() -- not local! Called from C!

local topmenu = makeMenu()
local favesmenu = makeMenu()
local securitymenu = makeMenu()
faveitems = {}

setMenuItemSubmenu(appendMenuItem(topmenu, "Favorites"), favesmenu)
setMenuItemSubmenu(appendMenuItem(topmenu, "Security"), securitymenu)

appendMenuItem(topmenu, "Lock keychain", function() lockKeychain() end)
appendMenuItem(securitymenu, "Lock keychain now", function() lockKeychain() end)
setMenuItemSubmenu(appendMenuItem(securitymenu, "Require trusted device"), buildTrustedDeviceMenu())

for orderi,type in ipairs(passwordTypeOrdering) do
local bucket = items[type]
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -80,6 +80,7 @@ add_executable(1pass
aes.c
md5.c
sha1.c
sha256.c
base64.c
lua/lapi.c
lua/ldebug.c
Expand Down

0 comments on commit 3b807fa

Please sign in to comment.