home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / circ / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-08-11  |  52.9 KB

  1. From: newsham@wiliki.eng.hawaii.edu (Timothy Newsham)
  2. Newsgroups: comp.sources.misc
  3. Subject: v38i010: circ - encrypted irc package, Part01/03
  4. Date: 19 Jun 1993 08:30:21 +0100
  5. Sender: aem@aber.ac.uk
  6. Approved: aem@aber.ac.uk
  7. Message-ID: <csm-v38i010=circ.082941@aber.ac.uk>
  8. X-Md4-Signature: 8f69745400e904297079a7f9cb0d0e4d
  9.  
  10. Submitted-by: newsham@wiliki.eng.hawaii.edu (Timothy Newsham)
  11. Posting-number: Volume 38, Issue 10
  12. Archive-name: circ/part01
  13. Environment: C UNIX
  14.  
  15. The following (in uuencoded tar-Z format) is The first release (V1.0) of
  16. the Circ package.  It works in conjunction with the ircII client (chat
  17. program: available at csd.bu.edu in pub/irc/clients)
  18.  
  19. The program allows for key management, key exchange and the exchange of
  20. encrypted messages in real time over the IRC chat network.
  21.  
  22. The current version has been tested on Ultrix (decstation) and HPUX 9.0
  23. (hp9000) machines.  Previous versions have been tested on other
  24. platforms, the code is mostly made up of STDIO routines and should
  25. compile on most unix machines.
  26.  
  27. All code written by me is released into the public domain.
  28.  
  29. The code in the RSA and d3des directories were not authored by me but
  30. are freely distributable.
  31.  
  32. ****
  33. Moderators note:
  34. Circ was supplied to me as a single 127Kb shar file.  Since this was too
  35. large to post directly, I've split it into 3 separate issues.  +Alec-
  36. --
  37. #! /bin/sh
  38. # This is a shell archive.  Remove anything before this line, then feed it
  39. # into a shell via "sh file" or similar.  To overwrite existing files,
  40. # type "sh file -c".
  41. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  42. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  43. # Contents:  MANIFEST Circ Circ/README.old Circ/RSA Circ/RSA/conf.h
  44. #   Circ/d3des Circ/d3des/d3des.c Circ/pubkeys Circ/sock2.c
  45. # Wrapped by alecm@uk-usenet on Sat Jun 19 08:26:20 1993
  46. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  47. echo If this archive is complete, you will see the following message:
  48. echo '          "shar: End of archive 1 (of 3)."'
  49. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  50.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  51. else
  52.   echo shar: Extracting \"'MANIFEST'\" \(1445 characters\)
  53.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  54. X   File Name        Archive #    Description
  55. X----------------------------------------------------------
  56. XMANIFEST                   1    
  57. XCirc                       1    
  58. XCirc/LOG                   3    
  59. XCirc/Makefile              3    
  60. XCirc/README                2    
  61. XCirc/README.old            1    
  62. XCirc/RSA                   1    
  63. XCirc/RSA/MANIFEST          3    
  64. XCirc/RSA/Make.amiga        3    
  65. XCirc/RSA/Make.unix         3    
  66. XCirc/RSA/Makefile          3    
  67. XCirc/RSA/README            3    
  68. XCirc/RSA/README.english    3    
  69. XCirc/RSA/WARNING           3    
  70. XCirc/RSA/arith.c           2    
  71. XCirc/RSA/arith.h           3    
  72. XCirc/RSA/conf.h            1    
  73. XCirc/RSA/genprim.c         3    
  74. XCirc/RSA/genrsa.c          3    
  75. XCirc/RSA/makekey           3    
  76. XCirc/RSA/nio.c             2    
  77. XCirc/RSA/nio.h             3    
  78. XCirc/RSA/patchlevel.h      3    
  79. XCirc/RSA/prim.c            2    
  80. XCirc/RSA/prim.h            3    
  81. XCirc/RSA/rnd.c             3    
  82. XCirc/RSA/rnd.h             3    
  83. XCirc/RSA/rsa.c             2    
  84. XCirc/RSA/rsa.hdr           3    
  85. XCirc/RSA/test.c            3    
  86. XCirc/crypt.c               3    
  87. XCirc/crypt.irc             2    
  88. XCirc/crypt.irc2            3    
  89. XCirc/d3des                 1    
  90. XCirc/d3des/d3des.c         1    
  91. XCirc/d3des/d3des.h         2    
  92. XCirc/d3des/main.c          3    
  93. XCirc/d3des/readme          3    
  94. XCirc/ignore.irc            3    
  95. XCirc/new.c                 2    
  96. XCirc/pubkeys               1    
  97. XCirc/pubkeys/al            3    
  98. XCirc/sock.h                3    
  99. XCirc/sock2.c               1    
  100. XPOSTER                     3    
  101. END_OF_FILE
  102.   if test 1445 -ne `wc -c <'MANIFEST'`; then
  103.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  104.   fi
  105.   # end of 'MANIFEST'
  106. fi
  107. if test ! -d 'Circ' ; then
  108.     echo shar: Creating directory \"'Circ'\"
  109.     mkdir 'Circ'
  110. fi
  111. if test -f 'Circ/README.old' -a "${1}" != "-c" ; then 
  112.   echo shar: Will not clobber existing file \"'Circ/README.old'\"
  113. else
  114.   echo shar: Extracting \"'Circ/README.old'\" \(6652 characters\)
  115.   sed "s/^X//" >'Circ/README.old' <<'END_OF_FILE'
  116. X
  117. Xthis is a tinyirc client (client not written by me)
  118. Xbut I added in encryption..  Right now encryption is
  119. Xdone in DES for messages and RSA for key exchange.
  120. X
  121. XTo set it up,  unarchive (you probably already did this)
  122. Xthen type :
  123. X    (you should be in the 'irc' dir at this point)
  124. X     make sock
  125. Xthis should make a program called 'sock'
  126. X
  127. Xnow you need to go into the RSA directory and make yourself
  128. Xa keypair.
  129. X
  130. X     cd RSA
  131. X     make genrsa
  132. X     make genprim
  133. X     genrsa
  134. X
  135. Xthis makes two files  'public' and 'secret'.  You need to install
  136. Xthese:
  137. X     mv secret ..
  138. X     mv public ../<yournick>
  139. X     cd ..
  140. X
  141. Xand give out your public key to everyone you want to talk to.
  142. XThis lets them send their key to you.
  143. X
  144. XYou must send them your public key *BEFORE* you start talking
  145. Xto them on irc.  You can do this with mail or with /dcc on
  146. Xa normal irc client, or any other way you wish.
  147. X
  148. XYou must also receive keys for the people you wish to talk to
  149. X*BEFORE* running the program!  These should be in the same
  150. Xdirectory as 'sock' and have they same filename as the
  151. Xother person's nickname.  So by this point you should have:
  152. X   your friends key in a file named after their nickname
  153. X   your key in a file called 'secret'
  154. X   a binary named 'sock'
  155. Xall in the same directory.
  156. X
  157. XI have supplied a number of public keys from me and my friends.
  158. XThese are in the directory irc/pubkeys/*.  If you wish to
  159. Xuse any of them copy them into the same directory as you
  160. Xhave 'sock' in:
  161. X     cp pubkeys/* .
  162. X
  163. Xrun sock:
  164. X      sock
  165. X
  166. Xjoin the same channel as your friend you wish to talk to:
  167. X      /join #channel
  168. X
  169. Xsend them your key,  this lets them read any message typed by
  170. Xyou (note you have to be in the same channel as them)
  171. X      /key <your friend>
  172. X
  173. Xyour friend will receive your key, and now everything you type
  174. Xcan be read by him.  In order to send your key to your friend
  175. Xyou must have the file <your friend> in your directory that
  176. Xis <your friend>'s public key.  He must have the matching
  177. Xsecret key in the file 'secret' in his directory.  If your
  178. Xfriend changes nick's and the filename of his key isnt the
  179. Xsame as his nick you can specify the file:
  180. X       /key <your friend> <filename of his key>
  181. X
  182. X(note: this isnt working yet ^^^ will be fixed)
  183. Xthats it!  Everything you type is encrypted with the same key
  184. Xwhich is chosen at random when you start up 'sock'.  Every time
  185. Xyou use sock a new key is used.  Every time you want to talk to
  186. Xa new person you have to send them your key.  Anyone who has
  187. Xyour key can read any of your messages,  so if you dont want
  188. Xpeople reading your messages dont give them your key.  Everything
  189. Xyou type is encrypted.
  190. X
  191. X
  192. Xsome public keys are already provided in pubkeys/*
  193. Xcopy them into current directory to use them.
  194. X--------
  195. XWeaknesses:
  196. X
  197. X  (1) RSA key as created by 'genrsa' is not very long!  It
  198. X      is crackable right now.  This could be lengthened
  199. X      easily enough by modifying genrsa.c .  The rest of
  200. X      the program doesnt care what length key is used.
  201. X
  202. X  (2) You can send alot of garbage to someone's screen by
  203. X      sending out wrong key's and/or sending out bad
  204. X      data matching keys already aquired.
  205. X      possible solution: header inside of the encrypted
  206. X      data.  1 character would give a 1/256 chance of
  207. X      this attack working.
  208. X
  209. X  (3) probably alot more I didnt think about.
  210. X
  211. X----------
  212. XProtocol:
  213. X
  214. Xthere are two types of messages,  one to send keys across
  215. Xto other people, one to send across encrypted messages, all
  216. Xmessages are sent to the current irc channel, not through messages
  217. Xto individual people:
  218. X
  219. X   SKPJACK:xxxx:yyyy:zzzzz
  220. X        xxxx - the nick name of the intended recipient
  221. X        yyyy - the serial number of the key being transfered
  222. X        zzzz - ascii encoded RSA data
  223. X     messages of this format are used to send private keys (DES
  224. X     keys) to the recipient, ie   /key nick.
  225. X     Messages received are ignored if xxxxx isnt our current nick.
  226. X
  227. X   CLIPPER:xxxx:yyyy
  228. X         xxxx - the serial number of the key used to encrypt
  229. X         yyyy - the ascii encoded crypted data (DES)
  230. X     messages of this format are used to send encrypted chat
  231. X     messages.  Messages received are ignored if we dont have
  232. X     the key corresponding to the serial number. 
  233. X
  234. X   ascii coding:  each byte is broken into 2 nybbles (4 bits)
  235. X   and sent across as two characters,  the first nybble
  236. X   is sent as   hi+'a' and the second is sent as lo+'A'
  237. X   so alternate characters are always upper then lower then
  238. X   upper case and so on.  (byte = hi<<4 + lo)
  239. X    
  240. X   Keys are generated randomly and each key has a random 
  241. X   32 bit serial number associated with it.  The program
  242. X   uses the serial number to decided which key to decrypt 
  243. X   with.  The program keeps all the keys it receives.
  244. X   All messages you type are sent with your key,  all messages
  245. X   you receive are decoded with the key matching the serial
  246. X   number sent with it.
  247. X
  248. X   your key and its serial number are generated as follows:
  249. X      srand(time(0));   <-- seed random with time
  250. X      pick 8 random chars into K
  251. X      L=encrypt(K,K)      <-- encrypt K with key K
  252. X      serial = (int)L     <-- use this as the serial number
  253. X      pick 8 random chars int M
  254. X      N=encrypt(M,K)      <-- encrypt M with key K
  255. X      N is used as your private DES key
  256. X      serial is used to keep track of N 
  257. X     
  258. X   this should thward attacks trying to guess N given 
  259. X   serial and possibly a good guess of time(0);
  260. X   encrypt(a,b) means encrypt a with key b in DES
  261. X-----
  262. XCREDITS
  263. X
  264. XAlot of this software was not written by me, In fact my part
  265. Xwas minimal.  I stole code from the following people:
  266. X
  267. XThe basic IRC client (tinyIRC) by:
  268. X Nathan Laredo - "Green" 
  269. X gt7080a@prism.gatech.edu 
  270. X
  271. X
  272. XThe RSA package by:    (email address is no longer valid)
  273. X
  274. X  Martin Nicolay        ( martin@trillian.megalon.de )
  275. X  Fliederstr. 23
  276. X  4100 Duisburg 1
  277. X  W-Germany
  278. X
  279. XI couldn't reach him via email.  I got this package via
  280. Xanon-ftp,  I hope he doesnt mind use of it in this program.
  281. X
  282. X
  283. XThe DES package (d3des):
  284. X
  285. X D3DES (V5.09) -
  286. X
  287. X A portable, public domain, version of the Data Encryption Standard.
  288. X
  289. X Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
  290. X Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
  291. X code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
  292. X Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
  293. X for humouring me on.
  294. X
  295. X Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
  296. X (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
  297. X
  298. XHe says "public domain" and then later "Copyright".  I assume
  299. Xhe means "freely distributable, useable".
  300. X
  301. XIf any of you are out there thanx alot!  Your code is much
  302. Xappreciated.
  303. X
  304. END_OF_FILE
  305.   if test 6652 -ne `wc -c <'Circ/README.old'`; then
  306.     echo shar: \"'Circ/README.old'\" unpacked with wrong size!
  307.   fi
  308.   # end of 'Circ/README.old'
  309. fi
  310. if test ! -d 'Circ/RSA' ; then
  311.     echo shar: Creating directory \"'Circ/RSA'\"
  312.     mkdir 'Circ/RSA'
  313. fi
  314. if test -f 'Circ/RSA/conf.h' -a "${1}" != "-c" ; then 
  315.   echo shar: Will not clobber existing file \"'Circ/RSA/conf.h'\"
  316. else
  317.   echo shar: Extracting \"'Circ/RSA/conf.h'\" \(2293 characters\)
  318.   sed "s/^X//" >'Circ/RSA/conf.h' <<'END_OF_FILE'
  319. X/*******************************************************************************
  320. X*                                           *
  321. X*    Copyright (c) Martin Nicolay,  22. Nov. 1988                   *
  322. X*                                           *
  323. X*    Wenn diese (oder sinngemaess uebersetzte) Copyright-Angabe enthalten   *
  324. X*    bleibt, darf diese Source fuer jeden nichtkomerziellen Zweck weiter    *
  325. X*    verwendet werden.                               *
  326. X*                                           *
  327. X*    martin@trillian.megalon.de                           *
  328. X*                                           *
  329. X*******************************************************************************/
  330. X
  331. X#ifndef    _conf_h_
  332. X#define    _conf_h_
  333. X
  334. Xtypedef    unsigned short INT;        /* muss MAXINT fassen        */
  335. Xtypedef    unsigned long LONG;        /* muss (MAXINT+1)^2 -1 fassen    */
  336. X
  337. X#if    defined( M_XENIX )
  338. X#define    P(x)    x            /* Funktions Prototypen an    */
  339. X#else
  340. X#define    P(x)    ()            /* Funktions Prototypen aus    */
  341. X#endif
  342. X
  343. X/*
  344. X *    (MAXINT+1)-adic Zahlen
  345. X */
  346. X
  347. X/*
  348. X *    MAXINT        Maximale Zahl pro Elemenmt (muss int sein)
  349. X *    MAXBIT        Maximales Bit von MAXINT
  350. X *    LOWBITS        Anzahl der consekutiven low Bits von MAXINT
  351. X *    HIGHBIT        Hoechsten Bit von MAXINT
  352. X *    TOINT        muss (INT)( (x) % MAXINT) ergeben
  353. X *    MAXLEN        Laenge der INT Array in jeder NUMBER
  354. X */
  355. X
  356. X#define MAXINT        0xFFFF
  357. X
  358. X#if MAXINT == 99
  359. X#define    MAXBIT        7
  360. X#define    LOWBITS     2
  361. X#endif
  362. X#if MAXINT == 9
  363. X#define    MAXBIT        4
  364. X#define    LOWBITS     1
  365. X#endif
  366. X#if MAXINT == 1
  367. X#define MAXBIT        1
  368. X#endif
  369. X#if MAXINT == 0xFF
  370. X#define MAXBIT        8
  371. X#define    TOINT(x)    ((INT)(x))        /* ACHTUNG !!!!! */
  372. X#endif
  373. X#if MAXINT == 0xFFFF
  374. X#define MAXBIT        16
  375. X#define    TOINT(x)    ((INT)(x))        /* ACHTUNG !!!!! */
  376. X#endif
  377. X
  378. X#ifndef    MAXBIT
  379. X#include    "<< ERROR: MAXBIT must be defined >>"
  380. X#endif
  381. X#ifndef    LOWBITS
  382. X#if MAXINT == (1 << MAXBIT) - 1
  383. X#define    LOWBITS        MAXBIT
  384. X#else
  385. X#include    "<< ERROR: LOWBITS must be defined >>"
  386. X#endif
  387. X#endif
  388. X
  389. X#define    MAXLEN        (300*8/(MAXBIT + 1))
  390. X#define    STRLEN        (MAXLEN*MAXBIT/4)
  391. X#define    HIGHBIT        (1 << (MAXBIT-1) )
  392. X
  393. X#if LOWBITS == MAXBIT
  394. X#define    DIVMAX1(x)    ((x) >> MAXBIT)
  395. X#define    MODMAX1(x)    ((x) & MAXINT)
  396. X#define    MULMAX1(x)    ((x) << MAXBIT)
  397. X#else
  398. X#define    DIVMAX1(x)    ((x) / (MAXINT+1))
  399. X#define    MODMAX1(x)    ((x) % (MAXINT+1))
  400. X#define    MULMAX1(x)    ((x) * (unsigned)(MAXINT+1))
  401. X#endif
  402. X
  403. X#ifndef    TOINT
  404. X#define    TOINT(x)    ((INT)MODMAX1(x))
  405. X#endif
  406. X
  407. Xtypedef struct {
  408. X    int    n_len;            /* Hoechster benutzter Index    */
  409. X    INT    n_part[MAXLEN];
  410. X} NUMBER;
  411. X
  412. X#define    NUM0P    ((NUMBER *)0)        /* Abkuerzung            */
  413. X
  414. X#endif
  415. END_OF_FILE
  416.   if test 2293 -ne `wc -c <'Circ/RSA/conf.h'`; then
  417.     echo shar: \"'Circ/RSA/conf.h'\" unpacked with wrong size!
  418.   fi
  419.   # end of 'Circ/RSA/conf.h'
  420. fi
  421. if test ! -d 'Circ/d3des' ; then
  422.     echo shar: Creating directory \"'Circ/d3des'\"
  423.     mkdir 'Circ/d3des'
  424. fi
  425. if test -f 'Circ/d3des/d3des.c' -a "${1}" != "-c" ; then 
  426.   echo shar: Will not clobber existing file \"'Circ/d3des/d3des.c'\"
  427. else
  428.   echo shar: Extracting \"'Circ/d3des/d3des.c'\" \(20140 characters\)
  429.   sed "s/^X//" >'Circ/d3des/d3des.c' <<'END_OF_FILE'
  430. X/* D3DES (V5.09) -
  431. X *
  432. X * A portable, public domain, version of the Data Encryption Standard.
  433. X *
  434. X * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
  435. X * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
  436. X * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
  437. X * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
  438. X * for humouring me on.
  439. X *
  440. X * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
  441. X * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
  442. X */
  443. X
  444. X#include "d3des.h"
  445. X
  446. Xstatic void scrunch(/* unsigned char *, unsigned long * */);
  447. Xstatic void unscrun(/* unsigned long *, unsigned char * */);
  448. Xstatic void desfunc(/* unsigned long *, unsigned long * */);
  449. Xstatic void cookey(/* unsigned long * */);
  450. X
  451. Xstatic unsigned long KnL[32] = { 0L };
  452. Xstatic unsigned long KnR[32] = { 0L };
  453. Xstatic unsigned long Kn3[32] = { 0L };
  454. Xstatic unsigned char Df_Key[24] = {
  455. X    0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
  456. X    0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
  457. X    0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
  458. X
  459. Xstatic unsigned short bytebit[8]    = {
  460. X    0200, 0100, 040, 020, 010, 04, 02, 01 };
  461. X
  462. Xstatic unsigned long bigbyte[24] = {
  463. X    0x800000L,    0x400000L,    0x200000L,    0x100000L,
  464. X    0x80000L,    0x40000L,    0x20000L,    0x10000L,
  465. X    0x8000L,    0x4000L,    0x2000L,    0x1000L,
  466. X    0x800L,     0x400L,     0x200L,     0x100L,
  467. X    0x80L,        0x40L,        0x20L,        0x10L,
  468. X    0x8L,        0x4L,        0x2L,        0x1L    };
  469. X
  470. X/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
  471. X
  472. Xstatic unsigned char pc1[56] = {
  473. X    56, 48, 40, 32, 24, 16,  8,     0, 57, 49, 41, 33, 25, 17,
  474. X     9,  1, 58, 50, 42, 34, 26,    18, 10,  2, 59, 51, 43, 35,
  475. X    62, 54, 46, 38, 30, 22, 14,     6, 61, 53, 45, 37, 29, 21,
  476. X    13,  5, 60, 52, 44, 36, 28,    20, 12,  4, 27, 19, 11,  3 };
  477. X
  478. Xstatic unsigned char totrot[16] = {
  479. X    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
  480. X
  481. Xstatic unsigned char pc2[48] = {
  482. X    13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
  483. X    22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
  484. X    40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
  485. X    43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
  486. X
  487. Xvoid deskey(key, edf)    /* Thanks to James Gillogly & Phil Karn! */
  488. Xunsigned char *key;
  489. Xshort edf;
  490. X{
  491. X    register int i, j, l, m, n;
  492. X    unsigned char pc1m[56], pcr[56];
  493. X    unsigned long kn[32];
  494. X
  495. X    for ( j = 0; j < 56; j++ ) {
  496. X        l = pc1[j];
  497. X        m = l & 07;
  498. X        pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
  499. X        }
  500. X    for( i = 0; i < 16; i++ ) {
  501. X        if( edf == DE1 ) m = (15 - i) << 1;
  502. X        else m = i << 1;
  503. X        n = m + 1;
  504. X        kn[m] = kn[n] = 0L;
  505. X        for( j = 0; j < 28; j++ ) {
  506. X            l = j + totrot[i];
  507. X            if( l < 28 ) pcr[j] = pc1m[l];
  508. X            else pcr[j] = pc1m[l - 28];
  509. X            }
  510. X        for( j = 28; j < 56; j++ ) {
  511. X            l = j + totrot[i];
  512. X            if( l < 56 ) pcr[j] = pc1m[l];
  513. X            else pcr[j] = pc1m[l - 28];
  514. X            }
  515. X        for( j = 0; j < 24; j++ ) {
  516. X            if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
  517. X            if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
  518. X            }
  519. X        }
  520. X    cookey(kn);
  521. X    return;
  522. X    }
  523. X
  524. Xstatic void cookey(raw1)
  525. Xregister unsigned long *raw1;
  526. X{
  527. X    register unsigned long *cook, *raw0;
  528. X    unsigned long dough[32];
  529. X    register int i;
  530. X
  531. X    cook = dough;
  532. X    for( i = 0; i < 16; i++, raw1++ ) {
  533. X        raw0 = raw1++;
  534. X        *cook     = (*raw0 & 0x00fc0000L) << 6;
  535. X        *cook    |= (*raw0 & 0x00000fc0L) << 10;
  536. X        *cook    |= (*raw1 & 0x00fc0000L) >> 10;
  537. X        *cook++ |= (*raw1 & 0x00000fc0L) >> 6;
  538. X        *cook     = (*raw0 & 0x0003f000L) << 12;
  539. X        *cook    |= (*raw0 & 0x0000003fL) << 16;
  540. X        *cook    |= (*raw1 & 0x0003f000L) >> 4;
  541. X        *cook++ |= (*raw1 & 0x0000003fL);
  542. X        }
  543. X    usekey(dough);
  544. X    return;
  545. X    }
  546. X
  547. Xvoid cpkey(into)
  548. Xregister unsigned long *into;
  549. X{
  550. X    register unsigned long *from, *endp;
  551. X
  552. X    from = KnL, endp = &KnL[32];
  553. X    while( from < endp ) *into++ = *from++;
  554. X    return;
  555. X    }
  556. X
  557. Xvoid usekey(from)
  558. Xregister unsigned long *from;
  559. X{
  560. X    register unsigned long *to, *endp;
  561. X
  562. X    to = KnL, endp = &KnL[32];
  563. X    while( to < endp ) *to++ = *from++;
  564. X    return;
  565. X    }
  566. X
  567. Xvoid des(inblock, outblock)
  568. Xunsigned char *inblock, *outblock;
  569. X{
  570. X    unsigned long work[2];
  571. X
  572. X    scrunch(inblock, work);
  573. X    desfunc(work, KnL);
  574. X    unscrun(work, outblock);
  575. X    return;
  576. X    }
  577. X
  578. Xstatic void scrunch(outof, into)
  579. Xregister unsigned char *outof;
  580. Xregister unsigned long *into;
  581. X{
  582. X    *into     = (*outof++ & 0xffL) << 24;
  583. X    *into    |= (*outof++ & 0xffL) << 16;
  584. X    *into    |= (*outof++ & 0xffL) << 8;
  585. X    *into++ |= (*outof++ & 0xffL);
  586. X    *into     = (*outof++ & 0xffL) << 24;
  587. X    *into    |= (*outof++ & 0xffL) << 16;
  588. X    *into    |= (*outof++ & 0xffL) << 8;
  589. X    *into    |= (*outof   & 0xffL);
  590. X    return;
  591. X    }
  592. X
  593. Xstatic void unscrun(outof, into)
  594. Xregister unsigned long *outof;
  595. Xregister unsigned char *into;
  596. X{
  597. X    *into++ = (*outof >> 24) & 0xffL;
  598. X    *into++ = (*outof >> 16) & 0xffL;
  599. X    *into++ = (*outof >>  8) & 0xffL;
  600. X    *into++ =  *outof++     & 0xffL;
  601. X    *into++ = (*outof >> 24) & 0xffL;
  602. X    *into++ = (*outof >> 16) & 0xffL;
  603. X    *into++ = (*outof >>  8) & 0xffL;
  604. X    *into    =  *outof     & 0xffL;
  605. X    return;
  606. X    }
  607. X
  608. Xstatic unsigned long SP1[64] = {
  609. X    0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
  610. X    0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
  611. X    0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
  612. X    0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
  613. X    0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
  614. X    0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
  615. X    0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
  616. X    0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
  617. X    0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
  618. X    0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
  619. X    0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
  620. X    0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
  621. X    0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
  622. X    0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
  623. X    0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
  624. X    0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
  625. X
  626. Xstatic unsigned long SP2[64] = {
  627. X    0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
  628. X    0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
  629. X    0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
  630. X    0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
  631. X    0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
  632. X    0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
  633. X    0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
  634. X    0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
  635. X    0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
  636. X    0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
  637. X    0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
  638. X    0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
  639. X    0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
  640. X    0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
  641. X    0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
  642. X    0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
  643. X
  644. Xstatic unsigned long SP3[64] = {
  645. X    0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
  646. X    0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
  647. X    0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
  648. X    0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
  649. X    0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
  650. X    0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
  651. X    0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
  652. X    0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
  653. X    0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
  654. X    0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
  655. X    0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
  656. X    0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
  657. X    0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
  658. X    0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
  659. X    0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
  660. X    0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
  661. X
  662. Xstatic unsigned long SP4[64] = {
  663. X    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
  664. X    0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
  665. X    0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
  666. X    0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
  667. X    0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
  668. X    0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
  669. X    0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
  670. X    0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
  671. X    0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
  672. X    0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
  673. X    0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
  674. X    0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
  675. X    0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
  676. X    0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
  677. X    0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
  678. X    0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
  679. X
  680. Xstatic unsigned long SP5[64] = {
  681. X    0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
  682. X    0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
  683. X    0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
  684. X    0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
  685. X    0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
  686. X    0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
  687. X    0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
  688. X    0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
  689. X    0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
  690. X    0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
  691. X    0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
  692. X    0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
  693. X    0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
  694. X    0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
  695. X    0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
  696. X    0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
  697. X
  698. Xstatic unsigned long SP6[64] = {
  699. X    0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
  700. X    0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
  701. X    0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
  702. X    0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
  703. X    0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
  704. X    0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
  705. X    0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
  706. X    0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
  707. X    0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
  708. X    0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
  709. X    0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
  710. X    0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
  711. X    0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
  712. X    0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
  713. X    0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
  714. X    0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
  715. X
  716. Xstatic unsigned long SP7[64] = {
  717. X    0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
  718. X    0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
  719. X    0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
  720. X    0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
  721. X    0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
  722. X    0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
  723. X    0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
  724. X    0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
  725. X    0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
  726. X    0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
  727. X    0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
  728. X    0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
  729. X    0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
  730. X    0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
  731. X    0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
  732. X    0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
  733. X
  734. Xstatic unsigned long SP8[64] = {
  735. X    0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
  736. X    0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
  737. X    0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
  738. X    0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
  739. X    0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
  740. X    0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
  741. X    0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
  742. X    0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
  743. X    0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
  744. X    0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
  745. X    0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
  746. X    0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
  747. X    0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
  748. X    0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
  749. X    0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
  750. X    0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
  751. X
  752. Xstatic void desfunc(block, keys)
  753. Xregister unsigned long *block, *keys;
  754. X{
  755. X    register unsigned long fval, work, right, leftt;
  756. X    register int round;
  757. X
  758. X    leftt = block[0];
  759. X    right = block[1];
  760. X    work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
  761. X    right ^= work;
  762. X    leftt ^= (work << 4);
  763. X    work = ((leftt >> 16) ^ right) & 0x0000ffffL;
  764. X    right ^= work;
  765. X    leftt ^= (work << 16);
  766. X    work = ((right >> 2) ^ leftt) & 0x33333333L;
  767. X    leftt ^= work;
  768. X    right ^= (work << 2);
  769. X    work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
  770. X    leftt ^= work;
  771. X    right ^= (work << 8);
  772. X    right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
  773. X    work = (leftt ^ right) & 0xaaaaaaaaL;
  774. X    leftt ^= work;
  775. X    right ^= work;
  776. X    leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
  777. X
  778. X    for( round = 0; round < 8; round++ ) {
  779. X        work  = (right << 28) | (right >> 4);
  780. X        work ^= *keys++;
  781. X        fval  = SP7[ work         & 0x3fL];
  782. X        fval |= SP5[(work >>  8) & 0x3fL];
  783. X        fval |= SP3[(work >> 16) & 0x3fL];
  784. X        fval |= SP1[(work >> 24) & 0x3fL];
  785. X        work  = right ^ *keys++;
  786. X        fval |= SP8[ work         & 0x3fL];
  787. X        fval |= SP6[(work >>  8) & 0x3fL];
  788. X        fval |= SP4[(work >> 16) & 0x3fL];
  789. X        fval |= SP2[(work >> 24) & 0x3fL];
  790. X        leftt ^= fval;
  791. X        work  = (leftt << 28) | (leftt >> 4);
  792. X        work ^= *keys++;
  793. X        fval  = SP7[ work         & 0x3fL];
  794. X        fval |= SP5[(work >>  8) & 0x3fL];
  795. X        fval |= SP3[(work >> 16) & 0x3fL];
  796. X        fval |= SP1[(work >> 24) & 0x3fL];
  797. X        work  = leftt ^ *keys++;
  798. X        fval |= SP8[ work         & 0x3fL];
  799. X        fval |= SP6[(work >>  8) & 0x3fL];
  800. X        fval |= SP4[(work >> 16) & 0x3fL];
  801. X        fval |= SP2[(work >> 24) & 0x3fL];
  802. X        right ^= fval;
  803. X        }
  804. X
  805. X    right = (right << 31) | (right >> 1);
  806. X    work = (leftt ^ right) & 0xaaaaaaaaL;
  807. X    leftt ^= work;
  808. X    right ^= work;
  809. X    leftt = (leftt << 31) | (leftt >> 1);
  810. X    work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
  811. X    right ^= work;
  812. X    leftt ^= (work << 8);
  813. X    work = ((leftt >> 2) ^ right) & 0x33333333L;
  814. X    right ^= work;
  815. X    leftt ^= (work << 2);
  816. X    work = ((right >> 16) ^ leftt) & 0x0000ffffL;
  817. X    leftt ^= work;
  818. X    right ^= (work << 16);
  819. X    work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
  820. X    leftt ^= work;
  821. X    right ^= (work << 4);
  822. X    *block++ = right;
  823. X    *block = leftt;
  824. X    return;
  825. X    }
  826. X
  827. X#ifdef D2_DES
  828. X
  829. Xvoid des2key(hexkey, mode)        /* stomps on Kn3 too */
  830. Xunsigned char *hexkey;            /* unsigned char[16] */
  831. Xshort mode;
  832. X{
  833. X    short revmod;
  834. X
  835. X    revmod = (mode == EN0) ? DE1 : EN0;
  836. X    deskey(&hexkey[8], revmod);
  837. X    cpkey(KnR);
  838. X    deskey(hexkey, mode);
  839. X    cpkey(Kn3);                    /* Kn3 = KnL */
  840. X    return;
  841. X    }
  842. X
  843. Xvoid Ddes(from, into)
  844. Xunsigned char *from, *into;        /* unsigned char[8] */
  845. X{
  846. X    unsigned long work[2];
  847. X
  848. X    scrunch(from, work);
  849. X    desfunc(work, KnL);
  850. X    desfunc(work, KnR);
  851. X    desfunc(work, Kn3);
  852. X    unscrun(work, into);
  853. X    return;
  854. X    }
  855. X
  856. Xvoid D2des(from, into)
  857. Xunsigned char *from;            /* unsigned char[16] */
  858. Xunsigned char *into;            /* unsigned char[16] */
  859. X{
  860. X    unsigned long *right, *l1, swap;
  861. X    unsigned long leftt[2], bufR[2];
  862. X
  863. X    right = bufR;
  864. X    l1 = &leftt[1];
  865. X    scrunch(from, leftt);
  866. X    scrunch(&from[8], right);
  867. X    desfunc(leftt, KnL);
  868. X    desfunc(right, KnL);
  869. X    swap = *l1;
  870. X    *l1 = *right;
  871. X    *right = swap;
  872. X    desfunc(leftt, KnR);
  873. X    desfunc(right, KnR);
  874. X    swap = *l1;
  875. X    *l1 = *right;
  876. X    *right = swap;
  877. X    desfunc(leftt, Kn3);
  878. X    desfunc(right, Kn3);
  879. X    unscrun(leftt, into);
  880. X    unscrun(right, &into[8]);
  881. X    return;
  882. X    }
  883. X
  884. Xvoid makekey(aptr, kptr)
  885. Xregister char *aptr;                /* NULL-terminated  */
  886. Xregister unsigned char *kptr;        /* unsigned char[8] */
  887. X{
  888. X    register unsigned char *store;
  889. X    register int first, i;
  890. X    unsigned long savek[96];
  891. X
  892. X    cpDkey(savek);
  893. X    des2key(Df_Key, EN0);
  894. X    for( i = 0; i < 8; i++ ) kptr[i] = Df_Key[i];
  895. X    first = 1;
  896. X    while( (*aptr != '\0') || first ) {
  897. X        store = kptr;
  898. X        for( i = 0; i < 8 && (*aptr != '\0'); i++ ) {
  899. X            *store++ ^= *aptr & 0x7f;
  900. X            *aptr++ = '\0';
  901. X            }
  902. X        Ddes(kptr, kptr);
  903. X        first = 0;
  904. X        }
  905. X    useDkey(savek);
  906. X    return;
  907. X    }
  908. X
  909. Xvoid make2key(aptr, kptr)
  910. Xregister char *aptr;                /* NULL-terminated   */
  911. Xregister unsigned char *kptr;        /* unsigned char[16] */
  912. X{
  913. X    register unsigned char *store;
  914. X    register int first, i;
  915. X    unsigned long savek[96];
  916. X
  917. X    cpDkey(savek);
  918. X    des2key(Df_Key, EN0);
  919. X    for( i = 0; i < 16; i++ ) kptr[i] = Df_Key[i];
  920. X    first = 1;
  921. X    while( (*aptr != '\0') || first ) {
  922. X        store = kptr;
  923. X        for( i = 0; i < 16 && (*aptr != '\0'); i++ ) {
  924. X            *store++ ^= *aptr & 0x7f;
  925. X            *aptr++ = '\0';
  926. X            }
  927. X        D2des(kptr, kptr);
  928. X        first = 0;
  929. X        }
  930. X    useDkey(savek);
  931. X    return;
  932. X    }
  933. X
  934. X#ifndef D3_DES    /* D2_DES only */
  935. X#ifdef    D2_DES    /* iff D2_DES! */
  936. X
  937. Xvoid cp2key(into)
  938. Xregister unsigned long *into;    /* unsigned long[64] */
  939. X{
  940. X    register unsigned long *from, *endp;
  941. X
  942. X    cpkey(into);
  943. X    into = &into[32];
  944. X    from = KnR, endp = &KnR[32];
  945. X    while( from < endp ) *into++ = *from++;
  946. X    return;
  947. X    }
  948. X
  949. Xvoid use2key(from)                /* stomps on Kn3 too */
  950. Xregister unsigned long *from;    /* unsigned long[64] */
  951. X{
  952. X    register unsigned long *to, *endp;
  953. X
  954. X    usekey(from);
  955. X    from = &from[32];
  956. X    to = KnR, endp = &KnR[32];
  957. X    while( to < endp ) *to++ = *from++;
  958. X    cpkey(Kn3);                    /* Kn3 = KnL */
  959. X    return;
  960. X    }
  961. X
  962. X#endif    /* iff D2_DES */
  963. X#else    /* D3_DES too */
  964. X
  965. Xstatic void D3des(/* unsigned char *, unsigned char * */);
  966. X
  967. Xvoid des3key(hexkey, mode)
  968. Xunsigned char *hexkey;            /* unsigned char[24] */
  969. Xshort mode;
  970. X{
  971. X    unsigned char *first, *third;
  972. X    short revmod;
  973. X
  974. X    if( mode == EN0 ) {
  975. X        revmod = DE1;
  976. X        first = hexkey;
  977. X        third = &hexkey[16];
  978. X        }
  979. X    else {
  980. X        revmod = EN0;
  981. X        first = &hexkey[16];
  982. X        third = hexkey;
  983. X        }
  984. X    deskey(&hexkey[8], revmod);
  985. X    cpkey(KnR);
  986. X    deskey(third, mode);
  987. X    cpkey(Kn3);
  988. X    deskey(first, mode);
  989. X    return;
  990. X    }
  991. X
  992. Xvoid cp3key(into)
  993. Xregister unsigned long *into;    /* unsigned long[96] */
  994. X{
  995. X    register unsigned long *from, *endp;
  996. X
  997. X    cpkey(into);
  998. X    into = &into[32];
  999. X    from = KnR, endp = &KnR[32];
  1000. X    while( from < endp ) *into++ = *from++;
  1001. X    from = Kn3, endp = &Kn3[32];
  1002. X    while( from < endp ) *into++ = *from++;
  1003. X    return;
  1004. X    }
  1005. X
  1006. Xvoid use3key(from)
  1007. Xregister unsigned long *from;    /* unsigned long[96] */
  1008. X{
  1009. X    register unsigned long *to, *endp;
  1010. X
  1011. X    usekey(from);
  1012. X    from = &from[32];
  1013. X    to = KnR, endp = &KnR[32];
  1014. X    while( to < endp ) *to++ = *from++;
  1015. X    to = Kn3, endp = &Kn3[32];
  1016. X    while( to < endp ) *to++ = *from++;
  1017. X    return;
  1018. X    }
  1019. X
  1020. Xstatic void D3des(from, into)    /* amateur theatrics */
  1021. Xunsigned char *from;            /* unsigned char[24] */
  1022. Xunsigned char *into;            /* unsigned char[24] */
  1023. X{
  1024. X    unsigned long swap, leftt[2], middl[2], right[2];
  1025. X
  1026. X    scrunch(from, leftt);
  1027. X    scrunch(&from[8], middl);
  1028. X    scrunch(&from[16], right);
  1029. X    desfunc(leftt, KnL);
  1030. X    desfunc(middl, KnL);
  1031. X    desfunc(right, KnL);
  1032. X    swap = leftt[1];
  1033. X    leftt[1] = middl[0];
  1034. X    middl[0] = swap;
  1035. X    swap = middl[1];
  1036. X    middl[1] = right[0];
  1037. X    right[0] = swap;
  1038. X    desfunc(leftt, KnR);
  1039. X    desfunc(middl, KnR);
  1040. X    desfunc(right, KnR);
  1041. X    swap = leftt[1];
  1042. X    leftt[1] = middl[0];
  1043. X    middl[0] = swap;
  1044. X    swap = middl[1];
  1045. X    middl[1] = right[0];
  1046. X    right[0] = swap;
  1047. X    desfunc(leftt, Kn3);
  1048. X    desfunc(middl, Kn3);
  1049. X    desfunc(right, Kn3);
  1050. X    unscrun(leftt, into);
  1051. X    unscrun(middl, &into[8]);
  1052. X    unscrun(right, &into[16]);
  1053. X    return;
  1054. X    }
  1055. X
  1056. Xvoid make3key(aptr, kptr)
  1057. Xregister char *aptr;                /* NULL-terminated   */
  1058. Xregister unsigned char *kptr;        /* unsigned char[24] */
  1059. X{
  1060. X    register unsigned char *store;
  1061. X    register int first, i;
  1062. X    unsigned long savek[96];
  1063. X
  1064. X    cp3key(savek);
  1065. X    des3key(Df_Key, EN0);
  1066. X    for( i = 0; i < 24; i++ ) kptr[i] = Df_Key[i];
  1067. X    first = 1;
  1068. X    while( (*aptr != '\0') || first ) {
  1069. X        store = kptr;
  1070. X        for( i = 0; i < 24 && (*aptr != '\0'); i++ ) {
  1071. X            *store++ ^= *aptr & 0x7f;
  1072. X            *aptr++ = '\0';
  1073. X            }
  1074. X        D3des(kptr, kptr);
  1075. X        first = 0;
  1076. X        }
  1077. X    use3key(savek);
  1078. X    return;
  1079. X    }
  1080. X
  1081. X#endif    /* D3_DES */
  1082. X#endif    /* D2_DES */
  1083. X
  1084. X/* Validation sets:
  1085. X *
  1086. X * Single-length key, single-length plaintext -
  1087. X * Key      : 0123 4567 89ab cdef
  1088. X * Plain  : 0123 4567 89ab cde7
  1089. X * Cipher : c957 4425 6a5e d31d
  1090. X *
  1091. X * Double-length key, single-length plaintext -
  1092. X * Key      : 0123 4567 89ab cdef fedc ba98 7654 3210
  1093. X * Plain  : 0123 4567 89ab cde7
  1094. X * Cipher : 7f1d 0a77 826b 8aff
  1095. X *
  1096. X * Double-length key, double-length plaintext -
  1097. X * Key      : 0123 4567 89ab cdef fedc ba98 7654 3210
  1098. X * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
  1099. X * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
  1100. X *
  1101. X * Triple-length key, single-length plaintext -
  1102. X * Key      : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
  1103. X * Plain  : 0123 4567 89ab cde7
  1104. X * Cipher : de0b 7c06 ae5e 0ed5
  1105. X *
  1106. X * Triple-length key, double-length plaintext -
  1107. X * Key      : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
  1108. X * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
  1109. X * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
  1110. X *
  1111. X * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
  1112. X **********************************************************************/
  1113. END_OF_FILE
  1114.   if test 20140 -ne `wc -c <'Circ/d3des/d3des.c'`; then
  1115.     echo shar: \"'Circ/d3des/d3des.c'\" unpacked with wrong size!
  1116.   fi
  1117.   # end of 'Circ/d3des/d3des.c'
  1118. fi
  1119. if test ! -d 'Circ/pubkeys' ; then
  1120.     echo shar: Creating directory \"'Circ/pubkeys'\"
  1121.     mkdir 'Circ/pubkeys'
  1122. fi
  1123. if test -f 'Circ/sock2.c' -a "${1}" != "-c" ; then 
  1124.   echo shar: Will not clobber existing file \"'Circ/sock2.c'\"
  1125. else
  1126.   echo shar: Extracting \"'Circ/sock2.c'\" \(17161 characters\)
  1127.   sed "s/^X//" >'Circ/sock2.c' <<'END_OF_FILE'
  1128. X/* Nathan Laredo - "Green" - gt7080a@prism.gatech.edu */
  1129. X/* mini-client, semi-raw input, formatted output */
  1130. X/* supports none of pre-2.7.2 protocol in formatting */
  1131. X/* the documentation takes up lots of the space here */
  1132. X
  1133. X/* modified Apr 21, 1993 "xxx".  Changed to a special- */
  1134. X/* purpose encryption program                          */
  1135. X
  1136. X#include <stdio.h>
  1137. X#ifdef pyr
  1138. X#include <strings.h>
  1139. X#else
  1140. X#include <string.h>
  1141. X#endif
  1142. X#include <errno.h>
  1143. X#include <sys/types.h>
  1144. X#include <sys/time.h>
  1145. X#include <sys/socket.h>
  1146. X#include <netinet/in.h>
  1147. X#include <netdb.h>
  1148. X#include "sock.h"
  1149. X
  1150. Xchar *encode(),*decode();
  1151. Xchar *en_crypt(),*de_crypt(); /* external, in crypt.c */
  1152. X
  1153. X#define KEYLEN  24+1
  1154. X#define MAXKEYS 30
  1155. X#define HUGE 1024
  1156. X#define SECKEY  "secret"      /* secret key file,  should be a variable */
  1157. X
  1158. Xchar keys[MAXKEYS][KEYLEN];   /* keys           */
  1159. Xunsigned int  sers[MAXKEYS];           /* serial numbers */
  1160. X
  1161. Xint s,d;                      /* IRC socket, DCC socket      */ 
  1162. Xchar buf[512];                /* global text data buffer     */
  1163. Xchar curchan[256];          /* current active channel      */
  1164. Xchar localhost[64];          /* the local machine's name    */
  1165. Xint dcchost,dccsock;          /* for implementing DCC         */
  1166. Xchar dccbuf[2048];          /* buffer for incomming         */
  1167. Xchar dccname[512];          /* filename for dcc transfer   */
  1168. Xunsigned long int dcclength;  /* dcc reply/check         */
  1169. Xchar inputbuf[512];          /* buffer for user input         */
  1170. Xchar IRCNAME[32];          /* storage for current nick    */
  1171. Xfd_set readfs, orig;
  1172. Xint sok=1;            /* socket ok flag */
  1173. X
  1174. Xchar *token[1024]; /* worst case: 1 2 3 4 5 .. etc 512 chars */
  1175. X
  1176. X/* casecmp(a,b)
  1177. X     a,b - null terminated strings.
  1178. X       does a non-case sensitive compare
  1179. X */
  1180. X#define To_lower(a)    (isupper(a)?tolower(a):(a))
  1181. X
  1182. Xcasecmp(a,b)
  1183. Xchar *a,*b;
  1184. X{
  1185. X  while(*a && *b) 
  1186. X    if(To_lower(*a) != To_lower(*b)) 
  1187. X      return (*b-*a);   /* doesnt really matter if they are diff cases here*/
  1188. X    else {
  1189. X      a++,b++;
  1190. X    }
  1191. X  return(0);
  1192. X}
  1193. X
  1194. X/* asctobin(str,len)
  1195. X     str - ascii string (null terminated)
  1196. X     len - int *,   RETURN length of binary block
  1197. X     returns:  char * to binary block data in static storage.
  1198. X       coding:
  1199. X         high nybble - 'a'=0 to 'p'=15
  1200. X         low nybble  - 'A'=0 to 'P'=15
  1201. X      NULL returned for bad encoding. 
  1202. X */
  1203. Xchar *asctobin(str,len)
  1204. Xchar *str;
  1205. Xint *len;
  1206. X{
  1207. X  static char buf[HUGE];
  1208. X  char a,b;
  1209. X  int i;
  1210. X
  1211. X  for(i=0;;) {
  1212. X    a=*str++;
  1213. X    while(a==' '||a=='\n') a=*str++;
  1214. X    b=*str++;
  1215. X    if(a=='\0' || b=='\0') {
  1216. X      *len=i;
  1217. X      return(buf);
  1218. X    }
  1219. X    if (a<'a'||a>'p' || b<'A'||b>'P') 
  1220. X      return(0);
  1221. X    buf[i++] = ((a-'a')<<4)|(b-'A');
  1222. X  }
  1223. X}
  1224. X
  1225. X/* bintoasc(str,len)
  1226. X      str - a pointer to a binary block
  1227. X      len - length of binary block in bytes
  1228. X      return - char * to a string that is ascii, null-terminated
  1229. X        coding -
  1230. X           high nybble  'a'=0 to 'p'=15
  1231. X           low nybble   'A'=0 to 'P'=15
  1232. X */
  1233. Xchar *bintoasc(str,len)
  1234. Xint len;
  1235. Xchar *str;
  1236. X{
  1237. X  static char buf[HUGE];
  1238. X  int i;
  1239. X  
  1240. X  for(i=0;len-- >0;str++) {
  1241. X    buf[i++]=((*str&0xf0)>>4) + 'a';
  1242. X    buf[i++]=(*str&0xf) + 'A'; 
  1243. X  }
  1244. X  buf[i]='\0';
  1245. X  return(buf);
  1246. X}
  1247. X
  1248. X/* encode(str)
  1249. X     str - an ascii null-terminated string 
  1250. X     returned - char * an encoded null terminated ascii string
  1251. X     encoding:
  1252. X       CLIPPER:xxxx:yyyyyyyyyyyyy
  1253. X          xxxx - serial number of key used
  1254. X          yyyyy- ascii coded, encrypted text message
  1255. X */
  1256. Xchar *encode(str)
  1257. Xchar *str;
  1258. X{
  1259. X  int l,ser,a;
  1260. X  static char buf[HUGE];
  1261. X  char *p;
  1262. X
  1263. X  set_key(keys[0]);          /* use our key and our serial number */
  1264. X  a=strlen(str)-1;
  1265. X  if(str[a]=='\n') str[a]='\0';
  1266. X  str[a++]='\0';
  1267. X  p=en_crypt(str ,a,&l);
  1268. X  sprintf(buf,"CLIPPER:%d:",sers[0]);
  1269. X  strcat(buf,bintoasc(p,l));
  1270. X  strcat(buf,"\n");
  1271. X  return(buf);
  1272. X}
  1273. X
  1274. X/*  decode(ar,len)
  1275. X      ar - array of words like argv[]
  1276. X      len - number of words,  like argc
  1277. X      return - char * to a decoded ascii null-termianted string
  1278. X       coding:  see encode()
  1279. X       error codes are returned as human readable strings.
  1280. X
  1281. X        CLIPPER:xxxx:yyyyyy
  1282. X            x - ascii serial number
  1283. X            y - ascii encoded binary data, crypted
  1284. X        SKPJACK:xxxx:yyyy:zzzz
  1285. X            x - nick name of destination
  1286. X            y - serial number of key being received
  1287. X            z - ascii encoded binary data,  encrypted with rsa
  1288. X                in 'nick's public key ,  contains the key
  1289. X                needed to read messages from nick
  1290. X */
  1291. Xchar *decode(ar,len)
  1292. Xchar *ar[];
  1293. Xint len;
  1294. X{
  1295. X  char *p;      /* lots of chars */
  1296. X  static char buf[HUGE];
  1297. X  int i,ser,l,a,itsakey=0;
  1298. X  
  1299. X  buf[0]='\0';
  1300. X  for(i=0;i<len;i++) {    /* put it into a single string */
  1301. X    strcat(buf,ar[i]); 
  1302. X    strcat(buf," ");      /* spaces seperate tokens */
  1303. X  }
  1304. X  if(strncmp(buf,"SKPJACK:",8)==0) 
  1305. X    itsakey=1;                          /* someones sending a key */
  1306. X  else if(strncmp(buf,"CLIPPER:",8))   
  1307. X      return(0);                    /* not encoded */
  1308. X  for(i=8;buf[i]!=':'&&buf[i]!='\0';i++);  /* jump past ser # */
  1309. X  if(buf[i]!=':') {
  1310. X    return("*Badly Formed*\n");
  1311. X  }
  1312. X  buf[i++]='\0';
  1313. X  ser=atoi(buf+8);                          /* this is ser # */
  1314. X
  1315. X  if(itsakey && casecmp(buf+8,IRCNAME)==0) {      /* new key sent to us */
  1316. X    ser=atoi(buf+i);
  1317. X    for(;buf[i]!=':'&&buf[i]!='\0';i++) ;
  1318. X    if(buf[i++]!=':') return("*Newkey: badly formed*");
  1319. X    p=asctobin(buf+i,&len);
  1320. X    if(!p) 
  1321. X      return("*new key: bad coding*");
  1322. X    memcpy(buf,p,len);         /* copy binary data */
  1323. X    if(do_rsa(SECKEY,buf,len,HUGE)<0) 
  1324. X      return("*new key: couldnt decrypt (rsa)*");
  1325. X    for(i=0;i<MAXKEYS;i++) 
  1326. X      if(sers[i]==0 || sers[i]==ser) break;
  1327. X    if(i==MAXKEYS) return ("*new key: out of table entries*");
  1328. X                    /* *never* receive a key we already have */
  1329. X                    /* this could be a trick                 */
  1330. X    if(sers[i]==ser) return("*new key: already have it!*");
  1331. X    sers[i]= ser;
  1332. X    memcpy(keys[i],buf,KEYLEN);
  1333. X    return("*New Key installed*");
  1334. X  }
  1335. Xif (itsakey) printf("Saw key for %s\n",buf+8);
  1336. X  if (itsakey) return("*Key received, but not for us*");
  1337. X
  1338. X  /* else its a message , try to decode */  
  1339. X  a=key(ser);                               /* find the key */
  1340. X  if(a==-1) return("*Dont Have the Key*\n");
  1341. X  set_key(keys[a]);
  1342. X  p=asctobin(buf+i,&len);                   /* decrypt it */
  1343. X  if(!p) return("*Bad Encoding*");
  1344. X  sprintf(buf,"<E> %s",de_crypt(p,len,&l));
  1345. X  return(buf);
  1346. X}
  1347. X
  1348. X/*  key(ser)
  1349. X      ser = serial number 
  1350. X      returned - index to the key with serial number ser, else -1 
  1351. X */
  1352. Xint key(ser)
  1353. Xint ser;
  1354. X{
  1355. X  int i;
  1356. X
  1357. X  for(i=0;i<MAXKEYS;i++)
  1358. X    if(ser == sers[i]) return(i);
  1359. X  return(-1);
  1360. X}
  1361. X
  1362. X/* sendkey(line)
  1363. X     line - char *,  everything after  /key on the command line
  1364. X       parsed to 'nick' and the optional 'filename'
  1365. X       filename is set to nick if it doesnt exist.
  1366. X     encodes our key and serial number with nick's public
  1367. X     key and sends it over the current channel for him
  1368. X     to receive 
  1369. X */
  1370. Xsendkey(line)     /* handle  /key nick [filename]   */
  1371. Xchar *line;
  1372. X{
  1373. X  char *file,*nick,*p;
  1374. X  char buf[1024];
  1375. X  int len;
  1376. X
  1377. X  while(*line==' ') line++;
  1378. X  nick=line;
  1379. X  while(*line!=' '&&*line!='\0'&&*line!='\n') line++; 
  1380. X  if(*line=='\n') *line='\0';
  1381. X  if(*line=='\0') 
  1382. X    file=nick;
  1383. X  else {
  1384. X    *line++='\0';
  1385. X    file=line;
  1386. X    while(*line!=' '&&*line!='\0'&&*line!='\n') line++; 
  1387. X    *line='\0';
  1388. X  }
  1389. X  if(*nick=='\0') {
  1390. X    printf("*ERROR*  nick missing,  /key nick [file]");
  1391. X    return;
  1392. X  }
  1393. X
  1394. X  memcpy(buf,keys[0],KEYLEN);
  1395. X  len=do_rsa(file,buf,KEYLEN,1024);
  1396. X  if(len<0)  {
  1397. X    printf("*ERROR* dont have public key for %s\n",file);
  1398. X    return;                 /* couldnt send it, RSA failed */
  1399. X  }
  1400. X  p=bintoasc(buf,len);
  1401. X  sprintf(buf,"PRIVMSG %s SKPJACK:%s:%d:%s\n",
  1402. X          curchan,nick,sers[0],p);
  1403. X  writeln(buf);     /* send it to irc */
  1404. X}
  1405. X
  1406. X
  1407. Xint call_socket(hostname)
  1408. X  char *hostname;
  1409. X{
  1410. X  struct sockaddr_in sa;
  1411. X  struct hostent     *hp;
  1412. X  int    a, s;
  1413. X
  1414. X  bzero(&sa, sizeof(sa));
  1415. X  sa.sin_family = AF_INET;
  1416. X  sa.sin_addr.s_addr = inet_addr(hostname);
  1417. X  if (sa.sin_addr.s_addr ==-1) {
  1418. X    if ((hp=gethostbyname(hostname))==NULL) {
  1419. X      errno=ECONNREFUSED;
  1420. X      return(-1);
  1421. X    }
  1422. X    sa.sin_family = hp->h_addrtype;
  1423. X    bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
  1424. X  }
  1425. X  sa.sin_port = htons((u_short)DEFAULTPORT);
  1426. X
  1427. X  if((s=socket(sa.sin_family, SOCK_STREAM, 0)) < 0)
  1428. X    return(-1);
  1429. X  if(connect(s, &sa, sizeof(sa)) < 0) {
  1430. X    close(s);
  1431. X    return(-1);
  1432. X  }
  1433. X  return(s);
  1434. X}
  1435. X
  1436. Xint dcc_socket(host,sock)
  1437. Xunsigned long int host;
  1438. Xint sock;
  1439. X{
  1440. Xstruct sockaddr_in sa;
  1441. Xint    a, d;
  1442. X
  1443. X  bzero(&sa, sizeof(sa));
  1444. X  bcopy(&host, (char *)&sa.sin_addr, sizeof(host));
  1445. X  sa.sin_family = AF_INET;
  1446. X  sa.sin_port = htons((u_short)sock);
  1447. X
  1448. X  if((d=socket(PF_INET, SOCK_STREAM, 0)) < 0)
  1449. X    return(-1);
  1450. X  if(connect(s, &sa, sizeof(sa)) < 0) {
  1451. X    close(d);
  1452. X    return(-1);
  1453. X  }
  1454. Xreturn(d);
  1455. X}
  1456. X
  1457. X
  1458. Xint readln(buf)
  1459. X  char *buf;
  1460. X{
  1461. X  int to=0;
  1462. X  char c;
  1463. X  do { /* will never overflow 'cause 
  1464. X    server can't send more than 512 bytes */
  1465. X      if(read(s, &c, 1)<1) return(0);
  1466. X      buf[to++] = c;
  1467. X  } while (c != '\n');
  1468. X  buf[to-1] = '\0';
  1469. X  return(1);
  1470. X}
  1471. X
  1472. Xint writeln(buf)
  1473. X  char *buf;
  1474. X{
  1475. X  int to=0;
  1476. X  if( write(s, buf, strlen(buf)) < to )
  1477. X    return(0);
  1478. X  return(1);
  1479. X}
  1480. X
  1481. Xint dcc_getblock(so,fi)
  1482. Xchar *so,*fi;
  1483. X{ char r;
  1484. X   if (r=read(so, dccbuf, 2048)) {
  1485. X        dcclength += r;
  1486. X        printf("[%08x]",dcclength);
  1487. X        write(so, htons((unsigned long int) dcclength), sizeof(dcclength));
  1488. X        write(fi, dccbuf, r);
  1489. X    return(1);
  1490. X        } /* if block is still there */
  1491. X    close(fi); close(so);
  1492. X    printf("DCC successful!\n");
  1493. X    return (0); /* done */
  1494. X}
  1495. X
  1496. Xdojoin() /* had to separate because the language is dumb */
  1497. X{
  1498. X    if(strcmp(token[0],IRCNAME)==0) {
  1499. X      printf("*** Current channel is now %s",token[2]);
  1500. X      strcpy(curchan,token[2]);
  1501. X      } /* case change current channel (nick=ircnick) */
  1502. X    else printf("*** %s has joined channel %s",token[0],token[2]);
  1503. X} /* end of dojoin */
  1504. X
  1505. Xdopart() /* see above */
  1506. X{
  1507. X    if(strcmp(token[0],IRCNAME)==0) {
  1508. X      if(strcmp(curchan,token[2])==0) { /* yur leaving your curent channel */
  1509. X        printf("*** Current channel is now invalid until you use join");
  1510. X/* you could probably implement a get last channel in if you wanted */
  1511. X        strcpy(curchan,"=invalid"); /* literally :-) */
  1512. X        } /* case invalidate current channel */
  1513. X      } /* damn I hate this */
  1514. X    else printf("*** %s has left channel %s",token[0],token[2]);
  1515. X} /* end of part garbage */
  1516. X
  1517. Xdonick()
  1518. X{
  1519. Xif(strcmp(token[0],IRCNAME)==0) { strcpy(IRCNAME,token[2]);
  1520. X    printf("*** You have changed your nickname to %s", token[2]);
  1521. X    } /* if you're doing this to yourself */
  1522. X    else printf("*** %s is now known as %s",token[0],token[2]);
  1523. X} /* I hate this language - if only it could read my mind */
  1524. X
  1525. Xdoprivmsg(tokencount)
  1526. Xint tokencount;
  1527. X{ int i;
  1528. X  char *p;
  1529. X
  1530. X    if(*(++token[3])=='\01') /* ctcp reply */
  1531. X      printf("*** CTCP MESSAGE FROM %s: ",token[0]);
  1532. X    else {
  1533. X      printf("<%s-%s> ",token[0],token[2]);
  1534. X/* decrypt here */
  1535. X      p=decode(token+3,tokencount-3);
  1536. X      if(p) {               /* if not encoded drop through */
  1537. X        printf("%s",p);
  1538. X        return;
  1539. X      }
  1540. X    }
  1541. X    for(i=3;i<tokencount; i++) printf("%s ",token[i]);
  1542. X
  1543. X/*  DO CTCP GOES HERE (INCLUDES DCC)  */
  1544. X} /* privmsg */
  1545. X
  1546. Xdonotice(tokencount)
  1547. Xint tokencount;
  1548. X{ int i;
  1549. X    if(*(++token[3])=='\01') /* ctcp reply */
  1550. X      printf("*** CTCP REPLY FROM %s: ",token[0]);
  1551. X    /* if there's a . in nick we KNOW it's not a user */
  1552. X    else if (strchr(token[0],'.')==0) printf("-%s- ",token[0]);
  1553. X    for(i=3;i<tokencount; i++) printf("%s ",token[i]);
  1554. X} /* notice */
  1555. X
  1556. Xint spitout(servstr) /* filter line to make more pleasing and spit out */
  1557. Xchar *servstr;
  1558. X{ int i;
  1559. X  char *temp;
  1560. X  int tokencount=0;
  1561. X  if (strncmp(servstr,"PING",4)==0) { /* make pings/pongs transparent */
  1562. X    temp=strncpy(servstr,"PO",2);
  1563. X    return(writeln(strcat(temp,"\n"))); /* needs new line-gone before */
  1564. X  }
  1565. X  /* tokenize */
  1566. X  token[0]=strtok(servstr," "); tokencount++;
  1567. X  while(token[tokencount++]=strtok(NULL, " "));
  1568. X  tokencount -= 1; /* need to fix for newline */
  1569. X  /* each token contains exactly one word, and only one now */
  1570. X  if(*token[0] != ':') { /* notice message from server usually */
  1571. X    for(i=0;i<tokencount; i++) printf("%s ",token[i]);
  1572. X    printf("\n");
  1573. X    return(0);
  1574. X    } /* if first char not : */
  1575. X  else token[0]++; /* point at next char past colon */
  1576. X  if(temp=strchr(token[0],'!')) *temp='\0'; /* strip address if there */
  1577. X
  1578. X/* main parsing stuff - follows parse.c in ircII pretty closely */
  1579. X
  1580. X  if(strcmp(token[1],"PRIVMSG")==0) doprivmsg(tokencount);
  1581. X  else if(strcmp(token[1],"NOTICE")==0) donotice(tokencount);
  1582. X  else if(strlen(token[1])==3)  /* server message, just print */
  1583. X    for(i=3;i<tokencount; i++) printf("%s ",token[i]);
  1584. X  else if(strcmp(token[1],"JOIN")==0) dojoin();
  1585. X  else if(strcmp(token[1],"PART")==0) dopart();
  1586. X  else if(strcmp(token[1],"QUIT")==0) {
  1587. X    printf("*** signoff (%s)",token[0]);
  1588. X    for(i=2;i<tokencount; i++) printf(" %s",token[i]);
  1589. X    } /* if someone's leaving irc */ 
  1590. X  else if(strcmp(token[1],"TOPIC")==0) {
  1591. X    printf("*** %s has changed the topic on %s to",token[0],token[2]);
  1592. X    for(i=3;i<tokencount; i++) printf(" %s",token[i]); }
  1593. X  else if(strcmp(token[1],"INVITE")==0)
  1594. X    printf("*** You have been invited to join channel %s by %s",token[2],
  1595. X        token[0]);
  1596. X  else if(strcmp(token[1],"NICK")==0) donick();
  1597. X  else if(strcmp(token[1],"KILL")==0) /* Hmmm, never got one, but hell */
  1598. X    printf("*** %s killed by %s",token[2],token[0]);
  1599. X  else if(strcmp(token[1],"MODE")==0) /* well, there are mode changes */
  1600. X    printf("*** Mode change on %s by %s to %s",token[2],token[0],token[3]);
  1601. X  else if(strcmp(token[1],"KICK")==0)
  1602. X    printf("*** %s has kicked %s from %s",token[0], token[2], token[3]);
  1603. X  else if(strncmp(token[1],"ERROR",5)==0) {
  1604. X    printf("*** ERROR:");
  1605. X    for(i=2;i<tokencount; i++) printf(" %s",token[i]); }
  1606. X  else /* if all else fails */
  1607. X  { printf("***"); for(i=0;i<tokencount; i++) printf(" %s",token[i]); }
  1608. Xputchar('\n'); /* if you get a blank line at this point this code sucks */
  1609. Xreturn(0);
  1610. X}
  1611. X
  1612. Xint dottyinput()
  1613. X{
  1614. X   char c;
  1615. X  int to=0;
  1616. X  do {
  1617. X  if(read(1, &c, 1)<1) return(0);
  1618. X    inputbuf[to++] = c;
  1619. X   } while (c != '\n');
  1620. X   inputbuf[to] = '\0';
  1621. X   if (inputbuf[0]==COMMANDCHAR){
  1622. X     if(strncmp(inputbuf+1,"key",3)==0)
  1623. X       sendkey(inputbuf+4);
  1624. X     else
  1625. X       writeln(inputbuf+1);
  1626. X   }
  1627. X   else {
  1628. X
  1629. X/* encrypt here */
  1630. X   sprintf(buf,"PRIVMSG %s %s",curchan,encode(inputbuf));
  1631. X   writeln(buf);
  1632. X   } /* no cmd character tried default */
  1633. X   return(1);
  1634. X}
  1635. X
  1636. Xmain(argc, argv)
  1637. X  int argc;
  1638. X  char **argv;
  1639. X{
  1640. X  char hostname[64];
  1641. X  char *logfile=NULL;
  1642. X  int c, errflag;
  1643. X  extern int optind, opterr;
  1644. X  extern char *optarg;
  1645. X  char line[512];
  1646. X
  1647. X  int i;
  1648. X
  1649. X  /* pick random 8 bit key -> K           */
  1650. X  /* encrypt  crypt(K,K) -> serial number */
  1651. X  /* pick random 8 bits  L                */
  1652. X  /* encrypt  crypt(L,K) -> our DES key   */
  1653. X  srand(time(0));
  1654. X  for(i=0;i<KEYLEN;i++)
  1655. X    keys[0][i]= (char)((rand()&0xff00)>>8);
  1656. X  set_key(keys[0]);
  1657. X  en_crypt(keys[0],KEYLEN,&i);
  1658. X  sers[0] = (int) *((int *)keys[0]);  /* pick serial number */
  1659. X  /* if(sers[0]<0) sers[0]=-sers[0];     /* problem with negative ser #'s */
  1660. X  for(i=0;i<KEYLEN;i++)
  1661. X    keys[0][i]= (char)((rand()&0xff00)>>8);
  1662. X  en_crypt(keys[0],KEYLEN,&i);
  1663. X
  1664. X  if(getenv("IRCNICK")==NULL || getenv("LOGNAME")==NULL || 
  1665. X     getenv("IRCNAME")==NULL) {
  1666. X  printf("The following settings in your environment are not set properly:\n");
  1667. X  if (getenv("IRCNICK")==NULL) printf("IRCNICK should be set with a nick\n");
  1668. X  if (getenv("LOGNAME")==NULL) printf("LOGNAME should contain user id\n");
  1669. X  if (getenv("IRCNAME")==NULL) printf("IRCNAME should contain real name\n");
  1670. X  exit(0);
  1671. X  }
  1672. Xif(argc>1) { /* assume only one param, hostname */
  1673. X  if (strchr(argv[1],'.')==0) { /* shouldn't a host have a period? */
  1674. X    fprintf(stderr,"usage: %s ircservername initialchannel\n", argv[0]);
  1675. X   exit(0); }
  1676. X  strcpy(hostname,argv[1]); }
  1677. X  else strcpy(hostname,DEFAULTSERVER);
  1678. X  gethostname(localhost, 64);
  1679. X  if ((s=call_socket(hostname))==-1) {
  1680. X    fprintf(stderr, "Could not connect to %s, aborting\n", hostname);
  1681. X    exit(0);
  1682. X  }
  1683. X  sprintf(buf, "NICK %s\n", getenv("IRCNICK"));
  1684. X  writeln(buf);
  1685. X  sprintf(buf, "USER %s 1 1 %s\n", getenv("LOGNAME"), getenv("IRCNAME"));
  1686. X  writeln(buf);
  1687. X  strcpy(curchan,"=invalid");
  1688. X  strncpy(IRCNAME,getenv("IRCNICK"),sizeof(IRCNAME));
  1689. X  if(argc>2) /* well we'll call this the channel to join */
  1690. X  { sprintf(buf, "JOIN %s\n", argv[2]); writeln(buf); }
  1691. X  if(argc>3) { /* assume you don't know what the hell you want */
  1692. X    fprintf(stderr,"usage: %s ircservername initialchannel\n", argv[0]);
  1693. X    exit(0); }
  1694. X  FD_ZERO(&readfs);
  1695. X  FD_SET(s,&readfs);
  1696. X  FD_SET(1,&readfs);
  1697. X  orig = readfs;
  1698. X  while(sok) {
  1699. X/* notice how when one character is there, we assume a whole line is
  1700. X   waiting for us to read.  This is because we're doing cooked i/o to
  1701. X   keep resources minimal */
  1702. X    if(select(FD_SETSIZE, &readfs, NULL, NULL, NULL)) {
  1703. X    if(FD_ISSET(1,&readfs)) if(!dottyinput()) return(1);
  1704. X    if(FD_ISSET(s,&readfs)) { 
  1705. X    sok = readln(line); 
  1706. X    if (sok) spitout(line);
  1707. X    } /* if s */
  1708. X    } /* if select */
  1709. Xreadfs = orig;
  1710. X}
  1711. X  return(1); /* assume that these files will be properly closed */
  1712. X}
  1713. END_OF_FILE
  1714.   if test 17161 -ne `wc -c <'Circ/sock2.c'`; then
  1715.     echo shar: \"'Circ/sock2.c'\" unpacked with wrong size!
  1716.   fi
  1717.   # end of 'Circ/sock2.c'
  1718. fi
  1719. echo shar: End of archive 1 \(of 3\).
  1720. cp /dev/null ark1isdone
  1721. MISSING=""
  1722. for I in 1 2 3 ; do
  1723.     if test ! -f ark${I}isdone ; then
  1724.     MISSING="${MISSING} ${I}"
  1725.     fi
  1726. done
  1727. if test "${MISSING}" = "" ; then
  1728.     echo You have unpacked all 3 archives.
  1729.     rm -f ark[1-9]isdone
  1730. else
  1731.     echo You still must unpack the following archives:
  1732.     echo "        " ${MISSING}
  1733. fi
  1734. exit 0
  1735. exit 0 # Just in case...
  1736.