summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2010-04-29 16:28:54 -0400
committerNalin Dahyabhai <nalin@dahyabhai.net>2010-04-29 16:28:54 -0400
commitc427ad63d452d515c7bd49e70bb401f2467babe6 (patch)
treef5c8a5e74ad0fa2cb4851d79f8371011ee73e1f3
parent2b58d08567e1375440fa0a0619920b34ebd68e5a (diff)
downloadpam_rps-c427ad63d452d515c7bd49e70bb401f2467babe6.tar.gz
pam_rps-c427ad63d452d515c7bd49e70bb401f2467babe6.tar.xz
pam_rps-c427ad63d452d515c7bd49e70bb401f2467babe6.zip
- add "verbose"
- add man page docs for the expanded rule set
-rw-r--r--README1
-rw-r--r--src/main.c12
-rw-r--r--src/pam_rps.8.in7
-rw-r--r--src/pam_rps.c80
4 files changed, 90 insertions, 10 deletions
diff --git a/README b/README
index afd3c79..c4eb4ca 100644
--- a/README
+++ b/README
@@ -6,6 +6,7 @@ RECOGNIZED ARGUMENTS:
throw= control the challenge(s) issued
best_of= control the number of rounds
echo make the user's response visible to the user
+ verbose make the results visible to the user
sun expect Sun PAM semantics
linux expect Linux-PAM semantics
diff --git a/src/main.c b/src/main.c
index 2dc54a0..0abdaf4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -70,14 +70,16 @@ converse(int n, const struct pam_message **msgs,
/* Sun ABI. */
msg = msgs[i];
}
- if (msg->msg_style == PAM_PROMPT_ECHO_OFF) {
+ switch (msg->msg_style) {
+ case PAM_PROMPT_ECHO_OFF:
s = getpass(msg->msg);
if (s == NULL) {
s = "";
}
(*resp)[i].resp_retcode = 0;
(*resp)[i].resp = strdup(s);
- } else {
+ break;
+ case PAM_PROMPT_ECHO_ON:
fprintf(stderr, "%s", msg->msg);
s = fgets(buf, sizeof(buf), stdin);
if (s == NULL) {
@@ -86,6 +88,12 @@ converse(int n, const struct pam_message **msgs,
s[strcspn(s, "\r\n")] = '\0';
(*resp)[i].resp_retcode = 0;
(*resp)[i].resp = strdup(s);
+ break;
+ default:
+ fprintf(stderr, "%s\n", msg->msg);
+ (*resp)[i].resp_retcode = 0;
+ (*resp)[i].resp = NULL;
+ break;
}
}
return 0;
diff --git a/src/pam_rps.8.in b/src/pam_rps.8.in
index 2bb96c0..5d93952 100644
--- a/src/pam_rps.8.in
+++ b/src/pam_rps.8.in
@@ -31,6 +31,9 @@ one half of them. If the supplied number is not odd, it will be incremented.
Signal to the calling application that the user should be able to see
the response as it is being typed in.
+.IP verbose
+Let the user know the results of the match(es).
+
.IP sun
Follow the conversation conventions consistent with Solaris PAM and not
Linux-PAM. The default is to attempt to accomodate both.
@@ -39,6 +42,10 @@ Linux-PAM. The default is to attempt to accomodate both.
Follow the conversation conventions consistent with Linux-PAM and not
Solaris PAM. The default is to attempt to accomodate both.
+.IP lizard
+.IP spock
+Use the enhanced ruleset.
+
.SH NOTES
Do not use this module in production.
diff --git a/src/pam_rps.c b/src/pam_rps.c
index 4e08c1d..46595e6 100644
--- a/src/pam_rps.c
+++ b/src/pam_rps.c
@@ -37,6 +37,8 @@
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
@@ -44,30 +46,45 @@
#include <security/pam_modules.h>
-/* These are the rules. */
+/* These are the rules. Apologies to Sam Kass. */
struct beater {
const char *what, *how;
};
struct beater what_beats_rock[] = {
{"paper", "covers"},
{"papyrus", "covers"},
+ {"spock", "vaporizes"},
};
struct beater what_beats_paper[] = {
{"scissors", "cuts"},
{"shears", "cuts"},
+ {"lizard", "eats"},
};
struct beater what_beats_scissors[] = {
{"rock", "blunts"},
{"stone", "blunts"},
+ {"spock", "smashes"},
+};
+struct beater what_beats_lizard[] = {
+ {"rock", "crushes"},
+ {"stone", "crushes"},
+ {"scissors", "decapitates"},
+};
+struct beater what_beats_spock[] = {
+ {"paper", "disproves"},
+ {"papyrus", "disproves"},
+ {"lizard", "poisons"},
};
struct rule {
- const char *challenge;
+ const char *what, *challenge;
struct beater *beaters;
};
struct rule rules[] = {
- {"rock: ", what_beats_rock},
- {"paper: ", what_beats_paper},
- {"scissors: ", what_beats_scissors},
+ {"rock", "rock: ", what_beats_rock},
+ {"paper", "paper: ", what_beats_paper},
+ {"scissors", "scissors: ", what_beats_scissors},
+ {"lizard", "lizard: ", what_beats_lizard},
+ {"spock", "spock: ", what_beats_spock},
};
/* Wrappers for pam_get_item() to get some measure of type-safety. */
@@ -134,6 +151,26 @@ lost(int loglevel, const char *challenge, const char *response)
}
}
+static void
+info(const struct pam_conv *conv,
+ const char *resp, const char *does, const char *what)
+{
+ char buffer[LINE_MAX];
+ const struct pam_message *msgs, msg = {
+ .msg_style = PAM_TEXT_INFO,
+ .msg = buffer,
+ };
+ struct pam_response *r;
+ snprintf(buffer, sizeof(buffer), "%s %s %s", resp, does, what);
+ r = NULL;
+ msgs = &msg;
+ (*(conv->conv))(1, &msgs, &r, conv->appdata_ptr);
+ if (r != NULL) {
+ free(r->resp);
+ free(r);
+ }
+}
+
int
pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
@@ -142,8 +179,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
struct pam_message **msgs, *msg_array, *prompt;
const struct pam_message **cmsgs;
const char *service;
- int debug = 0, loglevel, i, j, k, score, best_of, prompt_style, throw;
- int abi_sun, abi_linux, n_rules, n_winners;
+ int debug, loglevel, i, j, k, score, best_of, prompt_style, throw;
+ int verbose, abi_sun, abi_linux, n_rules, n_winners;
#ifdef LOG_AUTHPRIV
loglevel = LOG_AUTHPRIV | LOG_NOTICE;
@@ -174,6 +211,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
}
/* Parse our debug flag. */
+ debug = 0;
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "debug") == 0) {
#ifdef LOG_AUTHPRIV
@@ -192,6 +230,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
n_rules = 3;
n_winners = 2;
throw = -1;
+ verbose = 0;
for (i = 0; i < argc; i++) {
/* Force Linux-PAM-style semantics. */
if (strcmp(argv[i], "linux") == 0) {
@@ -237,6 +276,19 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
syslog(debug, "always throwing %d", throw);
}
}
+ /* Expanded rules. */
+ if ((strcmp(argv[i], "lizard") == 0) ||
+ (strcmp(argv[i], "spock") == 0)) {
+ n_rules = 5;
+ n_winners = 3;
+ if (debug) {
+ syslog(debug, "using expanded rules");
+ }
+ }
+ /* Tell the user what happened. */
+ if (strcmp(argv[i], "verbose") == 0) {
+ verbose++;
+ }
}
/* Set up the PAM message structure. We want to be able to exercise
@@ -333,6 +385,12 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
prompt->msg,
&rules[j].beaters[k],
responses[i].resp);
+ if (verbose) {
+ info(conv,
+ responses[i].resp,
+ rules[j].beaters[k].how,
+ rules[j].what);
+ }
score++;
break;
}
@@ -341,8 +399,14 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
* user lost. */
if (k >= n_winners) {
lost(debug,
- rules[j].challenge,
+ rules[j].what,
responses[i].resp);
+ if (verbose) {
+ info(conv,
+ responses[i].resp,
+ "loses to",
+ rules[j].what);
+ }
}
break;
}