summaryrefslogtreecommitdiffstats
path: root/lib/librpc/secure_rpc/bin/chkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/librpc/secure_rpc/bin/chkey.c')
-rw-r--r--lib/librpc/secure_rpc/bin/chkey.c302
1 files changed, 302 insertions, 0 deletions
diff --git a/lib/librpc/secure_rpc/bin/chkey.c b/lib/librpc/secure_rpc/bin/chkey.c
new file mode 100644
index 0000000..eefb34e
--- /dev/null
+++ b/lib/librpc/secure_rpc/bin/chkey.c
@@ -0,0 +1,302 @@
+#ifndef lint
+static char sccsid[] = "@(#)chkey.c 2.3 88/08/15 4.0 RPCSRC";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+ */
+
+/*
+ * Command to change one's public key in the public key database
+ */
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <rpc/key_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <sys/file.h>
+#include <pwd.h>
+#include <mp.h>
+
+extern char *getpass();
+extern char *index();
+extern char *crypt();
+extern char *sprintf();
+extern long random();
+
+static char PKMAP[] = "publickey.byname";
+static char *domain;
+struct passwd *ypgetpwuid();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char name[MAXNETNAMELEN+1];
+ char public[HEXKEYBYTES + 1];
+ char secret[HEXKEYBYTES + 1];
+ char crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
+ char crypt2[HEXKEYBYTES + KEYCHECKSUMSIZE + 1];
+ int status;
+ char *pass;
+ struct passwd *pw;
+ char *master;
+ int euid;
+ int fd;
+ int force;
+ char *self;
+
+ self = argv[0];
+ force = 0;
+ for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
+ if (argv[0][2] != 0) {
+ usage(self);
+ }
+ switch (argv[0][1]) {
+ case 'f':
+ force = 1;
+ break;
+ default:
+ usage(self);
+ }
+ }
+ if (argc != 0) {
+ usage(self);
+ }
+
+ (void)yp_get_default_domain(&domain);
+ if (yp_master(domain, PKMAP, &master) != 0) {
+ (void)fprintf(stderr,
+ "can't find master of publickey database\n");
+ exit(1);
+ }
+
+ getnetname(name);
+ (void)printf("Generating new key for %s.\n", name);
+
+ euid = geteuid();
+ if (euid != 0) {
+ pw = ypgetpwuid(euid);
+ if (pw == NULL) {
+ (void)fprintf(stderr,
+ "No yp password found: can't change key.\n");
+ exit(1);
+ }
+ } else {
+ pw = getpwuid(0);
+ if (pw == NULL) {
+ (void)fprintf(stderr,
+ "No password found: can't change key.\n");
+ exit(1);
+ }
+ }
+ pass = getpass("Password:");
+ if (!force) {
+ if (strcmp(crypt(pass, pw->pw_passwd), pw->pw_passwd) != 0) {
+ (void)fprintf(stderr, "Invalid password.\n");
+ exit(1);
+ }
+ }
+
+ genkeys(public, secret, pass);
+
+ bcopy(secret, crypt1, HEXKEYBYTES);
+ bcopy(secret, crypt1 + HEXKEYBYTES, KEYCHECKSUMSIZE);
+ crypt1[HEXKEYBYTES + KEYCHECKSUMSIZE] = 0;
+ xencrypt(crypt1, pass);
+
+ if (force) {
+ bcopy(crypt1, crypt2, HEXKEYBYTES + KEYCHECKSUMSIZE + 1);
+ xdecrypt(crypt2, getpass("Retype password:"));
+ if (bcmp(crypt2, crypt2 + HEXKEYBYTES, KEYCHECKSUMSIZE) != 0 ||
+ bcmp(crypt2, secret, HEXKEYBYTES) != 0) {
+ (void)fprintf(stderr, "Password incorrect.\n");
+ exit(1);
+ }
+ }
+
+ (void)printf("Sending key change request to %s...\n", master);
+ status = setpublicmap(name, public, crypt1);
+ if (status != 0) {
+ (void)printf("%s: unable to update yp database (%u): %s\n",
+ self, status, yperr_string(status));
+ (void)printf("Perhaps %s is down?\n", master);
+ exit(1);
+ }
+ (void)printf("Done.\n");
+
+ if (key_setsecret(secret) < 0) {
+ (void)printf("Unable to login with new secret key.\n");
+ exit(1);
+ }
+}
+
+usage(name)
+ char *name;
+{
+ (void)fprintf(stderr, "usage: %s [-f]\n", name);
+ exit(1);
+}
+
+
+/*
+ * Generate a seed
+ */
+getseed(seed, seedsize, pass)
+ char *seed;
+ int seedsize;
+ unsigned char *pass;
+{
+ int i;
+ int rseed;
+ struct timeval tv;
+
+ (void)gettimeofday(&tv, (struct timezone *)NULL);
+ rseed = tv.tv_sec + tv.tv_usec;
+ for (i = 0; i < 8; i++) {
+ rseed ^= (rseed << 8) | pass[i];
+ }
+ srandom(rseed);
+
+ for (i = 0; i < seedsize; i++) {
+ seed[i] = (random() & 0xff) ^ pass[i % 8];
+ }
+}
+
+
+/*
+ * Generate a random public/secret key pair
+ */
+genkeys(public, secret, pass)
+ char *public;
+ char *secret;
+ char *pass;
+{
+ int i;
+
+#define BASEBITS (8*sizeof(short) - 1)
+#define BASE (1 << BASEBITS)
+
+ MINT *pk = itom(0);
+ MINT *sk = itom(0);
+ MINT *tmp;
+ MINT *base = itom(BASE);
+ MINT *root = itom(PROOT);
+ MINT *modulus = xtom(HEXMODULUS);
+ short r;
+ unsigned short seed[KEYSIZE/BASEBITS + 1];
+ char *xkey;
+
+ getseed((char *)seed, sizeof(seed), (unsigned char *)pass);
+ for (i = 0; i < KEYSIZE/BASEBITS + 1; i++) {
+ r = seed[i] % BASE;
+ tmp = itom(r);
+ mult(sk, base, sk);
+ madd(sk, tmp, sk);
+ mfree(tmp);
+ }
+ tmp = itom(0);
+ mdiv(sk, modulus, tmp, sk);
+ mfree(tmp);
+ pow(root, sk, modulus, pk);
+ xkey = mtox(sk);
+ adjust(secret, xkey);
+ xkey = mtox(pk);
+ adjust(public, xkey);
+ mfree(sk);
+ mfree(base);
+ mfree(pk);
+ mfree(root);
+ mfree(modulus);
+}
+
+/*
+ * Adjust the input key so that it is 0-filled on the left
+ */
+adjust(keyout, keyin)
+ char keyout[HEXKEYBYTES+1];
+ char *keyin;
+{
+ char *p;
+ char *s;
+
+ for (p = keyin; *p; p++)
+ ;
+ for (s = keyout + HEXKEYBYTES; p >= keyin; p--, s--) {
+ *s = *p;
+ }
+ while (s >= keyout) {
+ *s-- = '0';
+ }
+}
+
+/*
+ * Set the entry in the public key map
+ */
+setpublicmap(name, public, secret)
+ char *name;
+ char *public;
+ char *secret;
+{
+ char pkent[1024];
+ u_int rslt;
+
+ (void)sprintf(pkent,"%s:%s", public, secret);
+ rslt = yp_update(domain, PKMAP, YPOP_STORE,
+ name, strlen(name), pkent, strlen(pkent));
+ return (rslt);
+}
+
+struct passwd *
+ypgetpwuid(uid)
+ int uid;
+{
+ char uidstr[10];
+ char *val;
+ int vallen;
+ static struct passwd pw;
+ char *p;
+
+ (void)sprintf(uidstr, "%d", uid);
+ if (yp_match(domain, "passwd.byuid", uidstr, strlen(uidstr),
+ &val, &vallen) != 0) {
+ return (NULL);
+ }
+ p = index(val, ':');
+ if (p == NULL) {
+ return (NULL);
+ }
+ pw.pw_passwd = p + 1;
+ p = index(pw.pw_passwd, ':');
+ if (p == NULL) {
+ return (NULL);
+ }
+ *p = 0;
+ return (&pw);
+}
OpenPOWER on IntegriCloud