Skip to content

Commit a461de2

Browse files
author
Colin Stolley
committed
Linger mode improvements.
- Put socket in $HOME and ensure owner-only privs - Handle decrypt failure from stashed key properly
1 parent 5d58a6a commit a461de2

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

pwm.cc

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ static std::string default_store_path() {
2525
return path;
2626
}
2727

28+
static std::string socket_path() {
29+
const char *home = std::getenv("HOME");
30+
if (home == nullptr) {
31+
home = "";
32+
}
33+
std::string path{home};
34+
path += "/.pwm.sock";
35+
return path;
36+
}
37+
2838
[[noreturn]] static void usage() {
2939
bail("usage: pwm [-d | -C | -u <name> [<meta>...] | -r name | <pattern>\n\n"
3040
"options:\n"
@@ -91,8 +101,7 @@ static void linger(const std::string_view key) {
91101
struct timespec start;
92102
clock_gettime(CLOCK_MONOTONIC, &start);
93103

94-
std::string path{"/tmp/pwm."};
95-
path += std::getenv("USER");
104+
auto path = socket_path();
96105
int sock;
97106
struct sockaddr_un sunaddr;
98107

@@ -126,6 +135,10 @@ static void linger(const std::string_view key) {
126135
}
127136
}
128137

138+
if (0 != chmod(path.c_str(), S_IRUSR | S_IWUSR)) {
139+
bail("%s\n socket must be read/writeable by owner only.", path.c_str());
140+
}
141+
129142
if (listen(sock, 2) == -1) {
130143
bail("Unable to listen on socket %s", strerror(errno));
131144
}
@@ -274,14 +287,15 @@ bool handle_search(const struct cmd_flags &f, struct ent &entry) {
274287
bail("missing or corrupt store: %s", f.store_path.c_str());
275288
}
276289
dkeyiv = readpass_fromdaemon();
277-
if (dkeyiv.empty()) {
290+
if (dkeyiv.empty() || !decrypt(ciphertext, dkeyiv, data)) {
291+
maybe_shutdown_daemon();
278292
key = f.key.empty() ? readpass("passphrase: ") : f.key;
279293
derive_key(ciphertext, key, dkeyiv);
280294
explicit_bzero(&key[0], key.size());
281-
}
282-
if (!decrypt(ciphertext, dkeyiv, data)) {
283-
fprintf(stderr, "Decrypt failed\n");
284-
return false;
295+
if (!decrypt(ciphertext, dkeyiv, data)) {
296+
fprintf(stderr, "Decrypt failed\n");
297+
return false;
298+
}
285299
}
286300
if (search(f.name, data, entry)) {
287301
if (entry.updated_at) {
@@ -694,8 +708,8 @@ bool maybe_shutdown_daemon() {
694708
struct sockaddr_un sunaddr;
695709
memset(&sunaddr, 0, sizeof(sunaddr));
696710
sunaddr.sun_family = AF_UNIX;
697-
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "/tmp/pwm.%s",
698-
std::getenv("USER"));
711+
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s",
712+
socket_path().c_str());
699713
int sock;
700714

701715
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
@@ -718,8 +732,8 @@ std::string readpass_fromdaemon() {
718732
struct sockaddr_un sunaddr;
719733
memset(&sunaddr, 0, sizeof(sunaddr));
720734
sunaddr.sun_family = AF_UNIX;
721-
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "/tmp/pwm.%s",
722-
std::getenv("USER"));
735+
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s",
736+
socket_path().c_str());
723737
int sock;
724738

725739
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {

0 commit comments

Comments
 (0)