summaryrefslogtreecommitdiffstats
path: root/login-utils/cryptocard.c
diff options
context:
space:
mode:
Diffstat (limited to 'login-utils/cryptocard.c')
-rw-r--r--login-utils/cryptocard.c228
1 files changed, 0 insertions, 228 deletions
diff --git a/login-utils/cryptocard.c b/login-utils/cryptocard.c
deleted file mode 100644
index 44cfb55d5..000000000
--- a/login-utils/cryptocard.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* cryptocard.c - support for the CRYPTOCard
- RB-1 Challenge-Response Token, initial code by
- bentson@grieg.seaslug.org (Randolph Bentson) on 3-Dec-96,
- Hacked severely by poe@daimi.aau.dk.
- This relies on an implementation of DES in a library, currently
- it interfaces with the koontz-des.tar.gz implementation which
- can be found in:
-
- ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/des/
-
- (Link with the fdes.o file from that distribution)
-
- and with Eric A. Young's libdes implementation used in SSLeay. Also
- available from the above ftp site. Link with the libdes.a library.
-
- The sources for this code are maintained in
-
- ftp://ftp.daimi.aau.dk/pub/linux/poe/poeigl-X.XX.tar.gz
-
- 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- - added Native Language Support
-
-*/
-#ifdef CRYPTOCARD
-
-/******************** CONFIGURATION section *****************************/
-/*--------------- select ONE DES implementation ------------------------*/
-/*#define KOONTZ_DES */
-#define EAY_LIBDES
-/*--------------- define if on little endian machine (Intel x86) -------*/
-#define LITTLE_ENDIAN
-/******************** end of CONFIGURATION section **********************/
-
-#define _BSD_SOURCE
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <syslog.h>
-#include <pwd.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include "nls.h"
-
-#ifdef KOONTZ_DES
-#include "../koontz-des/des.h"
-#endif /* KOONTZ_DES */
-
-#ifdef EAY_LIBDES
-#include "../libdes/des.h"
-#endif /* EAY_LIBDES */
-
-#include "cryptocard.h"
-
-static char *
-generate_challenge(void)
-{
- static char challenge_str[30];
- int rfd;
- unsigned long clong;
-
- /* create and present a challenge string */
- if ((rfd = open("/dev/urandom", O_RDONLY)) < 0) {
- syslog(LOG_NOTICE, _("couldn't open /dev/urandom"));
- return NULL;
- }
- if (read(rfd, &clong, 4) < 4) {
- close(rfd);
- syslog(LOG_NOTICE, _("couldn't read random data from /dev/urandom"));
- return NULL;
- }
- close(rfd);
-
- sprintf(challenge_str,"%08lu", clong);
- return challenge_str;
-}
-
-static char *
-get_key()
-{
- int success = 0;
- char keyfile[MAXPATHLEN];
- static char key[10];
- int rfd;
- struct stat statbuf;
-
- if (strlen(pwd->pw_dir) + 13 > sizeof(keyfile))
- goto bail_out;
- sprintf(keyfile, "%s/.cryptocard", pwd->pw_dir);
-
- if ((rfd = open(keyfile, O_RDONLY)) < 0) {
- syslog(LOG_NOTICE, _("can't open %s for reading"), keyfile);
- goto bail_out;
- }
- if (fstat(rfd, &statbuf) < 0) {
- syslog(LOG_NOTICE, _("can't stat(%s)"), keyfile);
- goto close_and_bail_out;
- }
- if ((statbuf.st_uid != pwd->pw_uid)
- || ((statbuf.st_mode & S_IFMT) != S_IFREG)
- || (statbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) {
- syslog(LOG_NOTICE, _("%s doesn't have the correct filemodes"), keyfile);
- goto close_and_bail_out;
- }
-
- if (read(rfd, key, 8) < 8) {
- syslog(LOG_NOTICE, _("can't read data from %s"), keyfile);
- goto close_and_bail_out;
- }
-
- key[8] = 0;
- success = 1;
-
-close_and_bail_out:
- close(rfd);
-
-bail_out:
- if (success)
- return key;
- else
- return NULL;
-}
-
-static int
-check_response(char *challenge, char *response, char *key)
-{
- char buf[20];
-
-#ifdef KOONTZ_DES
- extern void des (union LR_block *);
- extern void loadkey(char *,int);
- extern void set_des_mode(int);
-
- union LR_block data;
-
- strncpy((char *)data.string, (char *)challenge, 8);
- set_des_mode(ENCRYPT);
- loadkey(key, NOSHIFT);
- des(&data);
-
- memset(key, 0, 8); /* no need for the secret key anymore, scratch it */
-
- sprintf(buf, "%2.2X%2.2X%2.2X%2.2X",
- (int)(data.LR[0]) & 0xff,
- (int)(data.LR[0]>>8) & 0xff,
- (int)(data.LR[0]>>16) & 0xff,
- (int)(data.LR[0]>>24) & 0xff);
-#endif /* KOONTZ_DES */
-#ifdef EAY_LIBDES
- des_cblock res;
- des_key_schedule ks;
-
- des_set_key((des_cblock *)key, ks);
- memset(key, 0, 8);
- des_ecb_encrypt((des_cblock *)challenge, &res, ks, DES_ENCRYPT);
-
-#ifdef LITTLE_ENDIAN
- /* use this on Intel x86 boxes */
- sprintf(buf, "%2.2X%2.2X%2.2X%2.2X",
- res[0], res[1], res[2], res[3]);
-#else /* ie. BIG_ENDIAN */
- /* use this on big endian RISC boxes */
- sprintf(buf, "%2.2X%2.2X%2.2X%2.2X",
- res[3], res[2], res[1], res[0]);
-#endif /* LITTLE_ENDIAN */
-#endif /* EAY_LIBDES */
-
- /* return success only if ALL requirements have been met */
- if (strncmp(buf, response, 8) == 0)
- return 1;
-
- return 0;
-}
-
-int
-cryptocard(void)
-{
- char prompt[80];
- char *challenge;
- char *key;
- char *response;
-
- challenge = generate_challenge();
- if (challenge == NULL) return 0;
-
- if (strlen(challenge) + 13 > sizeof(prompt)) return 0;
- sprintf(prompt, "%s Password: ", challenge);
-
- alarm((unsigned int)timeout); /* give user time to fiddle with card */
- response = getpass(prompt); /* presents challenge and gets response */
-
- if (response == NULL) return 0;
-
- /* This requires some explanation: As root we may not be able to
- read the directory of the user if it is on an NFS mounted
- filesystem. We temporarily set our effective uid to the user-uid
- making sure that we keep root privs. in the real uid.
-
- A portable solution would require a fork(), but we rely on Linux
- having the BSD setreuid() */
-
- {
- uid_t ruid = getuid();
- gid_t egid = getegid();
-
- setregid(-1, pwd->pw_gid);
- setreuid(0, pwd->pw_uid);
-
- /* now we can access the file */
- /* get the (properly qualified) key */
- key = get_key();
-
- /* reset to root privs */
- setuid(0); /* setreuid doesn't do it alone! */
- setreuid(ruid, 0);
- setregid(-1, egid);
-
- if (key == NULL) return 0;
- }
-
- return check_response(challenge, response, key);
-}
-
-#endif /* CRYPTOCARD */