summaryrefslogtreecommitdiffstats
path: root/crypto/telnet
diff options
context:
space:
mode:
authornsayer <nsayer@FreeBSD.org>2001-05-07 20:42:02 +0000
committernsayer <nsayer@FreeBSD.org>2001-05-07 20:42:02 +0000
commitb47830be3e58e44dd6ae03b8dc4c9c034f7a2074 (patch)
tree6a64bdcf7b40b60eb51400ed98636f3cf17b21a3 /crypto/telnet
parentce2648b0d2ae4682634f37e718bdc59869d8d572 (diff)
downloadFreeBSD-src-b47830be3e58e44dd6ae03b8dc4c9c034f7a2074.zip
FreeBSD-src-b47830be3e58e44dd6ae03b8dc4c9c034f7a2074.tar.gz
Pointy hat fix -- reapply the SRA PAM patch. To -current this time.
Diffstat (limited to 'crypto/telnet')
-rw-r--r--crypto/telnet/libtelnet/sra.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/crypto/telnet/libtelnet/sra.c b/crypto/telnet/libtelnet/sra.c
index 95ac9fd..9274f88 100644
--- a/crypto/telnet/libtelnet/sra.c
+++ b/crypto/telnet/libtelnet/sra.c
@@ -13,6 +13,10 @@
#include <string.h>
#endif
+#if !defined(NOPAM)
+#include <security/pam_appl.h>
+#endif
+
#include "auth.h"
#include "misc.h"
#include "encrypt.h"
@@ -447,6 +451,7 @@ syslog(LOG_WARNING,"%s\n",save.pw_dir);
return (&save);
}
+#ifdef NOPAM
char *crypt();
int check_user(name, pass)
@@ -474,7 +479,135 @@ char *pass;
}
return(0);
}
+#else
+
+/*
+ * The following is stolen from ftpd, which stole it from the imap-uw
+ * PAM module and login.c. It is needed because we can't really
+ * "converse" with the user, having already gone to the trouble of
+ * getting their username and password through an encrypted channel.
+ */
+
+#define COPY_STRING(s) (s ? strdup(s):NULL)
+
+struct cred_t {
+ const char *uname;
+ const char *pass;
+};
+typedef struct cred_t cred_t;
+auth_conv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata)
+{
+ int i;
+ cred_t *cred = (cred_t *) appdata;
+ struct pam_response *reply =
+ malloc(sizeof(struct pam_response) * num_msg);
+
+ for (i = 0; i < num_msg; i++) {
+ switch (msg[i]->msg_style) {
+ case PAM_PROMPT_ECHO_ON: /* assume want user name */
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = COPY_STRING(cred->uname);
+ /* PAM frees resp. */
+ break;
+ case PAM_PROMPT_ECHO_OFF: /* assume want password */
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = COPY_STRING(cred->pass);
+ /* PAM frees resp. */
+ break;
+ case PAM_TEXT_INFO:
+ case PAM_ERROR_MSG:
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = NULL;
+ break;
+ default: /* unknown message style */
+ free(reply);
+ return PAM_CONV_ERR;
+ }
+ }
+
+ *resp = reply;
+ return PAM_SUCCESS;
+}
+
+/*
+ * The PAM version as a side effect may put a new username in *user.
+ */
+int check_user(const char *name, const char *pass)
+{
+ pam_handle_t *pamh = NULL;
+ const char *tmpl_user;
+ const void *item;
+ int rval;
+ int e;
+ cred_t auth_cred = { name, pass };
+ struct pam_conv conv = { &auth_conv, &auth_cred };
+
+ e = pam_start("telnetd", name, &conv, &pamh);
+ if (e != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
+ return 0;
+ }
+
+#if 0 /* Where can we find this value? */
+ e = pam_set_item(pamh, PAM_RHOST, remotehost);
+ if (e != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
+ pam_strerror(pamh, e));
+ return 0;
+ }
+#endif
+
+ e = pam_authenticate(pamh, 0);
+ switch (e) {
+ case PAM_SUCCESS:
+ /*
+ * With PAM we support the concept of a "template"
+ * user. The user enters a login name which is
+ * authenticated by PAM, usually via a remote service
+ * such as RADIUS or TACACS+. If authentication
+ * succeeds, a different but related "template" name
+ * is used for setting the credentials, shell, and
+ * home directory. The name the user enters need only
+ * exist on the remote authentication server, but the
+ * template name must be present in the local password
+ * database.
+ *
+ * This is supported by two various mechanisms in the
+ * individual modules. However, from the application's
+ * point of view, the template user is always passed
+ * back as a changed value of the PAM_USER item.
+ */
+ if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
+ PAM_SUCCESS) {
+ strcpy(user, (const char *) item);
+ } else
+ syslog(LOG_ERR, "Couldn't get PAM_USER: %s",
+ pam_strerror(pamh, e));
+ rval = 1;
+ break;
+
+ case PAM_AUTH_ERR:
+ case PAM_USER_UNKNOWN:
+ case PAM_MAXTRIES:
+ rval = 0;
+ break;
+
+ default:
+ syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
+ rval = 0;
+ break;
+ }
+
+ if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
+ rval = 0;
+ }
+ return rval;
+}
+
+#endif
#endif
OpenPOWER on IntegriCloud