aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--info/libpassphrase.texinfo6
-rw-r--r--src/passphrase.c108
-rw-r--r--src/passphrase.h2
3 files changed, 105 insertions, 11 deletions
diff --git a/info/libpassphrase.texinfo b/info/libpassphrase.texinfo
index 32f19c3..475b50f 100644
--- a/info/libpassphrase.texinfo
+++ b/info/libpassphrase.texinfo
@@ -154,7 +154,7 @@ be used when getting authentication. Should not
be combined with @code{PASSPHRASE_READ_NEW}.
@item PASSPHRASE_READ_NEW
@code{passphrase_read2} shall draw a pasphrase
-strenght meter if such capability is available.
+strength meter if such capability is available.
This should be used when create a new passphrase.
Should not be combined with @code{PASSPHRASE_READ_EXISTING}.
@item PASSPHRASE_READ_SCREEN_FREE
@@ -396,9 +396,9 @@ in @command{valgrind}.
When the @code{PASSPHRASE_READ_METER} flag
is used, and @code{PASSPHRASE_READ_SCREEN_FREE}
or @code{PASSPHRASE_READ_BELOW_FREE}, use
-@command{passcheck} to evaluate the strenght
+@command{passcheck} to evaluate the strength
of the passphrase and display a passphrase
-strenght meter. @command{passcheck} will be
+strength meter. @command{passcheck} will be
started by the real user, not the effective
user, and the real group.
diff --git a/src/passphrase.c b/src/passphrase.c
index 1430a47..032111b 100644
--- a/src/passphrase.c
+++ b/src/passphrase.c
@@ -19,8 +19,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <string.h>
#include <fcntl.h>
#include <errno.h>
+#include <limits.h>
#include <sys/wait.h>
#define PASSPHRASE_USE_DEPRECATED
@@ -44,6 +46,9 @@ struct passcheck_state
pid_t pid;
int flags;
};
+
+static char* strength = NULL;
+static size_t strength_size = 0;
#endif /* PASSPHRASE_METER */
@@ -111,24 +116,28 @@ static void passcheck_start(struct passcheck_state* state, int flags)
{
gid_t gid = getgid(), egid = getegid();
uid_t uid = getuid(), euid = geteuid();
+ int fd;
if ((state->pipe_rw[0] != STDIN_FILENO) && (state->pipe_rw[1] == STDIN_FILENO))
{
- pipe_rw[1] = dup(state->pipe_rw[1]);
- if (pipe_rw[1] == -1)
+ fd = dup(state->pipe_rw[1]);
+ if (fd == -1)
goto child_fail;
- state->pipe_rw[1] = pipe_rw[1], pipe_rw[1] = -1;
+ state->pipe_rw[1] = fd;
}
for (i = 0; i <= 1; i++)
if (state->pipe_rw[i] != i)
{
close(i);
- pipe_rw[i] = dup2(state->pipe_rw[i], i);
- if (pipe_rw[i] == -1)
+ fd = dup2(state->pipe_rw[i], i);
+ if (fd == -1)
goto child_fail;
- close(state->pipe_rw[i]), state->pipe_rw[i] = pipe_rw[i];
+ close(state->pipe_rw[i]);
+ state->pipe_rw[i] = fd;
}
+ close(STDERR_FILENO);
+
if (egid != gid)
if (setregid(gid, gid) && gid)
goto child_fail;
@@ -168,6 +177,7 @@ static void passcheck_start(struct passcheck_state* state, int flags)
state->flags = 0;
}
+
static void passcheck_stop(struct passcheck_state* state)
{
int _status;
@@ -178,19 +188,103 @@ static void passcheck_stop(struct passcheck_state* state)
close(state->pipe_rw[0]);
close(state->pipe_rw[1]);
+ free(strength), strength = NULL;
+ strength_size = 0;
+
rereap:
if ((waitpid(state->pid, &_status, 0) == -1) && (errno == EINTR))
goto rereap;
/* TODO cleanup */
+
+ state->flags = 0;
}
-static void passcheck_update(struct passcheck_state* state, char* passphrase, size_t len)
+
+static void passcheck_update(struct passcheck_state* state, const char* passphrase, size_t len)
{
+ size_t strength_ptr = 0;
+ ssize_t n;
+ int i;
+ void* new;
+ char* p;
+ unsigned long long int value;
+
if (state->flags == 0)
return;
+ for (i = 0; i < 2; i++, passphrase = "\n", len = 1)
+ while (len)
+ {
+ n = write(state->pipe_rw[1], passphrase, len);
+ if (n < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ goto fail;
+ }
+ passphrase += (size_t)n;
+ len -= (size_t)n;
+ }
+
+ again:
+ if (strength_ptr == strength_size)
+ {
+ strength_size = strength_size ? (strength_size << 1) : 8;
+ new = realloc(strength, strength_size * sizeof(char));
+ if (new == NULL)
+ goto fail;
+ strength = new;
+ }
+ n = read(state->pipe_rw[0], strength + strength_ptr, strength_size - 1 - strength_ptr);
+ if (n <= 0)
+ {
+ if (n && (errno == EINTR))
+ goto again;
+ goto fail;
+ }
+ strength_ptr += (size_t)n;
+ strength[strength_ptr] = '\0';
+ p = strpbrk(strength, " \t\r\f\n\v");
+ if (p == NULL)
+ goto again;
+ if (*p == '\033')
+ {
+ p = strpbrk(strength, "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm~");
+ if (p == NULL)
+ goto fail;
+ p++;
+ }
+ else
+ p = strength;
+ *(strpbrk(p, " \t\r\f\n\v\033")) = '\0';
+ errno = 0;
+ value = strtoull(p, NULL, 10);
+ if ((value == 0) && errno)
+ {
+ if (errno != ERANGE)
+ goto fail;
+ value = ULLONG_MAX;
+ }
+ while (memchr(strength, '\n', strength_ptr) == NULL)
+ {
+ strength_ptr = 0;
+ n = read(state->pipe_rw[0], strength, strength_size);
+ if (n <= 0)
+ {
+ if (n && (errno == EINTR))
+ goto again;
+ goto fail;
+ }
+ strength_ptr = (size_t)n;
+ }
+ strength_ptr = 0;
+
/* TODO */
+
+ return;
+ fail:
+ passcheck_stop(state);
}
#endif /* PASSPHRASE_METER */
diff --git a/src/passphrase.h b/src/passphrase.h
index 24ee71b..dd9dfb6 100644
--- a/src/passphrase.h
+++ b/src/passphrase.h
@@ -39,7 +39,7 @@
/**
* `passphrase_read2` shall draw a pasphrase
- * strenght meter if such capability is
+ * strength meter if such capability is
* available. This should be used when create
* a new passphrase.
* Should not be combined with `PASSPHRASE_READ_EXISTING`.