Bug 14444

Summary: enigma command can't decrypt files encrypted on other UNIX systems
Product: Base System Reporter: mike <mike>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.2-RELEASE   
Hardware: Any   
OS: Any   

Description mike 1999-10-21 02:50:00 UTC
1)  The 'enigma' program uses the /usr/libexec/makekey program to
generate the key with which the Enigma machine is started.
It has been modified to call the crypt(3) library routine directly,
to simplify porting.  (This is more of an issue for other OSs that
we use this program on).

2)  If the MD5 version of crypt(3) has been installed (the default
for FreeBSD 3.x systems), the enigma program will not be able to decode
files encrypted on other UNIX systems, nor will files encrypted on
FreeBSD be able to be decrypted on other UNIX systems.  As the
only real point of having the enigma command around at all is to
permit reading of old encrypted files, this defeats its purpose.

I have added self-checking into the enigma source, so that if the
crypt(3) routine is not functioning in a backwards-compatible manner,
it will complain and abort.

Fix: 

END--K9Eoyg14t4M8QBSsZMtX9G1uhvHix549BIX8hx8r3kXxApUo
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

*** /p/ftp/pub/FreeBSD/FreeBSD-current/src/usr.bin/enigma/enigma.c	Fri Oct 30 10:24:00 1998
--- enigma.c	Wed Oct 20 19:49:28 1999
***************
*** 8,18 ****
   *	A public-domain replacement for the UNIX "crypt" command.
   *
   *	Upgraded to function properly on 64-bit machines.
   */
  
- #include <sys/types.h>
- #include <sys/wait.h>
- 
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
--- 8,19 ----
   *	A public-domain replacement for the UNIX "crypt" command.
   *
   *	Upgraded to function properly on 64-bit machines.
+  *
+  *      Upgraded to have inline "makekey", and to test for
+  *	backwards-compatible operation of crypt(), rather than MD5 version.
+  *      crypt() is often found in -lcrypt
   */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
***************
*** 35,76 ****
  setup(pw)
  	char *pw;
  {
! 	int ic, i, k, temp, pf[2], pid;
  	unsigned random;
  	long seed;
  
  	strncpy(buf, pw, 8);
  	while (*pw)
  		*pw++ = '\0';
! 	buf[8] = buf[0];
! 	buf[9] = buf[1];
! 	pipe(pf);
! 	if ((pid=fork())==0) {
! 		close(0);
! 		close(1);
! 		dup(pf[0]);
! 		dup(pf[1]);
! 		execlp("makekey", "-", 0);
! 		execl("/usr/libexec/makekey", "-", 0);	/* BSDI */
! 		execl("/usr/lib/makekey", "-", 0);
! 		execl("/usr/bin/makekey", "-", 0);	/* IBM */
! 		execl("/lib/makekey", "-", 0);
! 		perror("makekey");
! 		fprintf(stderr, "enigma: cannot execute 'makekey', aborting\n");
! 		exit(1);
! 	}
! 	write(pf[1], buf, 10);
! 	close(pf[1]);
! 	i=wait((int *)NULL);
! 	if (i<0) perror("enigma: wait");
! 	if (i!=pid) {
! 		fprintf(stderr, "enigma: expected pid %d, got pid %d\n", pid, i);
! 		exit(1);
! 	}
! 	if ((i=read(pf[0], buf, 13)) != 13) {
! 		fprintf(stderr, "enigma: cannot generate key, read %d\n",i);
! 		exit(1);
! 	}
  	seed = 123;
  	for (i=0; i<13; i++)
  		seed = seed*buf[i] + i;
--- 36,70 ----
  setup(pw)
  	char *pw;
  {
! 	int ic, i, k, temp;
  	unsigned random;
  	long seed;
+         char *r;
+         char salt[3];
+ 
+         /* Verify backwards-compatible operation of library routine crypt() */
+         r = crypt("glorp", "gl");
+         if( strncmp( r, "$1$gl$85n.KNI", 13 ) == 0 )  {
+                 fprintf(stderr, "enigma: crypt() library routine is using MD5 rather than DES.\n%s\n",
+ 			"Incompatible encryption would occur, aborting.");
+                 exit(1);
+         }
+         if( strcmp( r, "gl4EsjmGvYQE." ) != 0 )  {
+                 fprintf(stderr, "enigma: malfunction in crypt() library routine, aborting.\n");
+                 exit(1);
+         }
  
+         /* Don't exec makekey, just invoke library routine directly */
  	strncpy(buf, pw, 8);
  	while (*pw)
  		*pw++ = '\0';
! 	buf[8] = '\0';
! 	salt[0] = buf[0];
! 	salt[1] = buf[1];
! 	salt[2] = '\0';
!         r = crypt( buf, salt );
!         strncpy( buf, r, sizeof(buf) );
! 
  	seed = 123;
  	for (i=0; i<13; i++)
  		seed = seed*buf[i] + i;
How-To-Repeat: 
On FreeBSD, this (incorrect) output is produced:

echo testing | enigma glorp | hd
00000000  20 e9 04 27  8e 38 8c 15                           | ..'.8..|

On correctly operating UNIX systems, this is the output produced:

echo testing | crypt glorp | hd
00000000  bf f7 35 2b  fc 49 fa 22                           |..5+.I."|

I verified these correct results on three systems:  my reference
VAX-11/780 running 4.3 BSD, an SGI Origin-200 running IRIX64 release
6.4, and a RedHat Linux 6.0 running on a Dell Dimension XPS-R400
Pentium.
Comment 1 Mike Barcroft freebsd_committer freebsd_triage 2001-07-21 03:23:03 UTC
State Changed
From-To: open->suspended


Awaiting committer.
Comment 2 ashp freebsd_committer freebsd_triage 2002-01-15 18:01:34 UTC
State Changed
From-To: suspended->closed

This now produces the correct output on a 4.5-RC machine.