"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/pdes.c" (21 May 2000, 3472 Bytes) of package /linux/misc/old/pidentd-3.0.19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pdes.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** pdes.c - Pidentd DES encryption stuff
    3 **
    4 ** Copyright (c) 1997-1999 Peter Eriksson <pen@lysator.liu.se>
    5 **
    6 ** Original source written by Planar 1994.02.21.
    7 **
    8 ** This program is free software; you can redistribute it and/or
    9 ** modify it as you wish - as long as you don't claim that you wrote
   10 ** it.
   11 **
   12 ** This program is distributed in the hope that it will be useful,
   13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   15 */
   16 
   17 #include "config.h"
   18 
   19 #ifdef HAVE_LIBDES
   20 
   21 #include <stdio.h>
   22 #include <fcntl.h>
   23 #ifdef HAVE_UNISTD_H
   24 #include <unistd.h>
   25 #endif
   26 #include <errno.h>
   27 
   28 #include <sys/types.h>
   29 #include <netinet/in.h>
   30 
   31 #include <sys/stat.h>
   32 #include <sys/time.h>
   33 
   34 #ifdef HAVE_DES_H
   35 #include <des.h>
   36 #elif HAVE_OPENSSL_DES_H
   37 #include <openssl/des.h>
   38 #endif
   39 
   40 #include "pdes.h"
   41 
   42 #include "pidentd.h"
   43 
   44 const static char to_asc[] =
   45     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
   46 
   47 
   48 
   49 static des_key_schedule sched;
   50 
   51 
   52 
   53 int
   54 pdes_init(char *keyfile)
   55 {
   56     char keybuf[1024+1];
   57     int fd, res;
   58     des_cblock key_bin;
   59 
   60 
   61     if (keyfile == NULL)
   62     {
   63     errno = EINVAL;
   64     return -1;
   65     }
   66     
   67     fd = s_open(keyfile, O_RDONLY);
   68     if (fd < 0)
   69     return -1;
   70     
   71     res = s_read(fd, keybuf, sizeof(keybuf)-1);
   72     if (res != sizeof(keybuf)-1)
   73     {
   74     /* Key file did not contain atleast one valid key */
   75 
   76     if (debug)
   77         fprintf(stderr, "pdes: First key was not complete (%d bytes)\n",
   78             res);
   79     
   80     s_close(fd);
   81     errno = EINVAL;
   82     return -1;
   83     }
   84 
   85     /* Locate the last key in the key file */
   86     while ((res = s_read(fd, keybuf, sizeof(keybuf)-1)) == sizeof(keybuf)-1)
   87     ;
   88     s_close(fd);
   89 
   90     if (res > 0 && res != sizeof(keybuf)-1)
   91     {
   92     /* Last key was not complete */
   93     
   94     if (debug)
   95         fprintf(stderr, "pdes: Last key was not complete (%d bytes)\n",
   96             res);
   97     
   98     errno = EINVAL;
   99     return -1;
  100     }
  101 
  102     keybuf[sizeof(keybuf)-1] = '\0';
  103     des_string_to_key(keybuf, &key_bin);
  104     des_set_key(&key_bin, sched);
  105 
  106     return 0;
  107 }
  108 
  109 
  110 
  111 int
  112 pdes_encrypt(struct kernel *kp,
  113          char result[33])
  114 {
  115     union data r;
  116     int i, j;
  117     time_t bt;
  118     
  119 
  120     r.fields.random = s_random();
  121     /* FIXME: uid_t isn't necessarily short.  */
  122     if (kp->ruid == NO_UID)
  123     r.fields.uid = htons(kp->euid);
  124     else
  125     r.fields.uid = htons(kp->ruid);
  126 
  127     time(&bt);
  128     r.fields.date = htonl(bt);
  129        
  130     r.fields.ip_local    = kp->local.sin_addr.s_addr;
  131     r.fields.ip_remote   = kp->remote.sin_addr.s_addr;
  132     r.fields.port_local  = kp->local.sin_port;
  133     r.fields.port_remote = kp->remote.sin_port;
  134 
  135     r.fields.checksum = 0;
  136     for (i = 1; i < 6; i++)
  137     r.longs[0] ^= r.longs[i];
  138 
  139     des_ecb_encrypt((des_cblock *)&(r.longs[0]), (des_cblock *)&(r.longs[0]),
  140             sched, DES_ENCRYPT);
  141     
  142     r.longs[2] ^= r.longs[0];
  143     r.longs[3] ^= r.longs[1];
  144     
  145     des_ecb_encrypt((des_cblock *)&(r.longs[2]), (des_cblock *)&(r.longs[2]),
  146             sched, DES_ENCRYPT);
  147     
  148     r.longs[4] ^= r.longs[2];
  149     r.longs[5] ^= r.longs[3];
  150     
  151     des_ecb_encrypt((des_cblock *)&(r.longs[4]), (des_cblock *)&(r.longs[4]),
  152             sched, DES_ENCRYPT);
  153 
  154     for (i = 0, j = 0; i < 24; i+=3, j+=4)
  155     {
  156     result[j  ] = to_asc[63 & (r.chars[i  ] >> 2)];
  157     result[j+1] = to_asc[63 & ((r.chars[i  ] << 4) + (r.chars[i+1] >> 4))];
  158     result[j+2] = to_asc[63 & ((r.chars[i+1] << 2) + (r.chars[i+2] >> 6))];
  159     result[j+3] = to_asc[63 & (r.chars[i+2])];
  160     }
  161     result[32] = '\0';
  162 
  163     return 0;
  164 }
  165 
  166 
  167 #endif