"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/idecrypt.c" (23 Apr 2001, 6220 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 "idecrypt.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** idecrypt.c - Encrypted IDENT response decryption utility.
    3 **
    4 ** Copyright (c) 1997-2000 Peter Eriksson <pen@lysator.liu.se>
    5 **
    6 ** This program is free software; you can redistribute it and/or
    7 ** modify it as you wish - as long as you don't claim that you wrote
    8 ** it.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   13 */
   14 
   15 #include "config.h"
   16 
   17 #include <string.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 #include <arpa/inet.h>
   31 
   32 #include <sys/stat.h>
   33 #include <sys/time.h>
   34 
   35 #ifdef HAVE_DES_H
   36 #include <des.h>
   37 #elif HAVE_OPENSSL_DES_H
   38 #include <openssl/des.h>
   39 #endif
   40 
   41 #include "pidentd.h"
   42 
   43 int debug = 0; /* for linking with safeio.o */
   44 
   45 static char *keyfile_path = PATH_KEYFILE;
   46 
   47 static char
   48 is_base_64 [] =
   49 {
   50     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   51     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   52     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
   53     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
   54     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   55     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
   56     0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   57     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
   58     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   59     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   60     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   61     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   62     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   63     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   64     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   65     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   66 };
   67 
   68 static unsigned char
   69 to_bin[] =
   70 {
   71     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   72     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   73     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   74     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   75     0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   76     0x80, 0x80, 0x80, 0x3e, 0x80, 0x80, 0x80, 0x3f,
   77     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
   78     0x3c, 0x3d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
   79     0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
   80     0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
   81     0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
   82     0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80,
   83     0x80, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
   84     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
   85     0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
   86     0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80,
   87 };
   88 
   89 
   90 
   91 
   92 static char *
   93 decrypt_packet(unsigned char *packet)
   94 {
   95     union data r;
   96     int i, j;
   97     time_t date_in_sec;
   98     char *date_in_ascii;
   99     char keybuf[1024+1];
  100     char buf1[32], buf2[32];
  101     struct sockaddr_gen ip_local, ip_remote;
  102     int keyfile_fd;
  103     des_cblock key_bin;
  104     des_key_schedule sched;
  105     static char readable[256];
  106     
  107 
  108     keyfile_fd = open(keyfile_path, O_RDONLY);
  109     if (keyfile_fd < 0)
  110     {
  111     fprintf(stderr, "open: ");
  112     perror(keyfile_path);
  113     exit(1);
  114     }
  115 
  116     /* Try to decrypt with each key found in the key file */
  117     
  118     while (read(keyfile_fd, keybuf, sizeof(keybuf)-1) == sizeof(keybuf)-1)
  119     {
  120     keybuf[sizeof(keybuf)-1] = '\0';
  121     des_string_to_key(keybuf, &key_bin);
  122     des_set_key(&key_bin, sched);
  123     
  124     
  125     for (i = 0, j = 0; i < 24; i += 3, j += 4)
  126     {
  127         r.chars[i  ] = (to_bin[packet[j  ]] << 2) + (to_bin[packet[j+1]] >> 4);
  128         r.chars[i+1] = (to_bin[packet[j+1]] << 4) + (to_bin[packet[j+2]] >> 2);
  129         r.chars[i+2] = (to_bin[packet[j+2]] << 6) + (to_bin[packet[j+3]]);
  130     }
  131     
  132     des_ecb_encrypt((des_cblock *)&(r.longs[4]),
  133             (des_cblock *)&(r.longs[4]),
  134             sched, DES_DECRYPT);
  135     r.longs[4] ^= r.longs[2];
  136     r.longs[5] ^= r.longs[3];
  137     
  138     des_ecb_encrypt((des_cblock *)&(r.longs[2]),
  139             (des_cblock *)&(r.longs[2]),
  140             sched, DES_DECRYPT);
  141     
  142     r.longs[2] ^= r.longs[0];
  143     r.longs[3] ^= r.longs[1]; 
  144     des_ecb_encrypt((des_cblock *)&(r.longs[0]),
  145             (des_cblock *)&(r.longs[0]),
  146             sched, DES_DECRYPT);
  147 
  148     for (i = 1; i < 6; i++)
  149     {
  150         r.longs[0] ^= r.longs[i];
  151     }
  152     
  153     if (r.fields.checksum == 0)
  154         goto GoodKey;
  155     }
  156     close(keyfile_fd);
  157     return NULL;
  158     
  159   GoodKey:
  160     date_in_sec = ntohl(r.fields.date);
  161     date_in_ascii = ctime(&date_in_sec);
  162     
  163     memcpy(SGADDRP(ip_local), &(r.fields.ip_local), sizeof(ip_local));
  164     memcpy(SGADDRP(ip_remote), &(r.fields.ip_remote), sizeof(ip_remote));
  165 
  166     /* FIXME: uid_t isn't necessarily short.  */
  167 #ifdef HAVE_SNPRINTF
  168     snprintf(readable, sizeof(readable),
  169 #else
  170     sprintf(readable,
  171 #endif
  172             "%24.24s %u %s %u %s %u",
  173         date_in_ascii,
  174         ntohs(r.fields.uid),
  175         s_inet_ntox(&ip_local, buf1, sizeof(buf1)),
  176         (unsigned) ntohs(r.fields.port_local),
  177         s_inet_ntox(&ip_remote, buf2, sizeof(buf2)),
  178         (unsigned) ntohs(r.fields.port_remote));
  179     
  180     close(keyfile_fd);
  181     return readable;
  182 }
  183 
  184 
  185 static void
  186 decrypt_file(FILE *f)
  187 {
  188     int c;
  189     int i;
  190     char buf[32];
  191     char *result;
  192 
  193     
  194     while (1)
  195     {
  196     c = getc(f);
  197     
  198       Same:
  199     if (c == EOF)
  200         return;
  201     
  202     if (c != '[')
  203     {
  204         putchar(c);
  205         continue;
  206     }
  207     
  208     for (i = 0; i < 32; i++)
  209     {
  210         c = getc(f);
  211         if (c == EOF || c < 0 || c > 255)
  212         break;
  213         if (!is_base_64[c])
  214         break;
  215         buf[i] = c;
  216     }
  217     
  218     if (i == 32)
  219         c = getc(f);
  220     
  221     if (i < 32 || c != ']')
  222     {
  223         putchar('[');
  224         fwrite(buf, 1, i, stdout);
  225         goto Same;
  226     }
  227     
  228     
  229     if ((result = decrypt_packet((unsigned char *) buf)) == NULL)
  230     {
  231         putchar('[');
  232         fwrite(buf, 1, 32, stdout);
  233         putchar(']');
  234     }
  235     else
  236     {
  237         fputs(result, stdout);
  238     }
  239     }
  240 }
  241 
  242 
  243 int
  244 main(int argc,
  245      char *argv[])
  246 {
  247     int i;
  248     FILE *f;
  249 
  250 
  251     if (argc < 2)
  252     decrypt_file(stdin);
  253     else
  254     {
  255     for (i = 1; i < argc; i++)
  256     {
  257         if (!strcmp(argv[i], "-"))
  258         {
  259         decrypt_file(stdin);
  260         continue;
  261         }
  262         
  263         f = fopen(argv[i], "r");
  264         if (f == NULL)
  265         {
  266         perror(argv[i]);
  267         continue;
  268         }
  269         
  270         decrypt_file(f);
  271         fclose(f);
  272     }
  273     }
  274     
  275     exit(0);
  276 }
  277 
  278 #else /* no HAVE_LIBDES */
  279 
  280 #error Need a DES library to compile Idecrupt.
  281 
  282 #endif