include-afsconfig-before-param-h-20010712
[openafs.git] / src / kauth / kautils.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 RCSID("$Header$");
14
15 #include <afs/stds.h>
16 #include <sys/types.h>
17 #ifdef AFS_NT40_ENV
18 #include <winsock2.h>
19 #else
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <sys/file.h>
23 #endif
24 #include <time.h>
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <rx/xdr.h>
28 #include <rx/rx.h>
29 #include <des.h>
30 #include "kauth.h"
31 #include "kautils.h"
32
33
34 /* This should match the behavior of ParseLoginName on input so that the output
35  * and input are compatible.  In names "." should show as \056 and in names and
36  * instances "@" should show as \100 */
37
38 void ka_PrintUserID (
39   char *prefix,                         /* part to be output before userID */
40   char *name,                           /* user name */
41   char *instance,                       /* instance, possible null or len=0 */
42   char *postfix)                        /* for output following userID */
43 {
44     unsigned char *c;
45     printf ("%s", prefix);
46     for (c=(unsigned char *)name; *c; c++)
47         if (isalnum(*c) || (ispunct(*c) && (*c != '.') && (*c != '@')))
48             printf ("%c", *c);
49         else printf ("\\%0.3o", *c);
50     if (instance && strlen (instance)) {
51         printf (".");
52         for (c=(unsigned char *)instance; *c; c++)
53             if (isalnum(*c) || (ispunct(*c) && (*c != '@'))) printf ("%c", *c);
54             else printf ("\\%0.3o", *c);
55     }
56     printf ("%s", postfix);
57 }
58
59 void ka_PrintBytes (
60   char bs[],
61   int  bl)
62 {
63     int i = 0;
64
65     for (i=0; i < bl; i++) {
66         unsigned char c = bs[i];
67         printf ("\\%0.3o", c);
68     }
69 }
70
71 /* converts a byte string to ascii.  Return the number of unconverted bytes. */
72
73 int ka_ConvertBytes (
74   char *ascii,                          /* output buffer */
75   int   alen,                           /* buffer length */
76   char  bs[],                           /* byte string */
77   int   bl)                             /* number of bytes */
78 {
79     int i;
80     unsigned char c;
81
82     alen--;                             /* make room for termination */
83     for (i=0; i < bl; i++) {
84         c = bs[i];
85         if (alen <= 0) return bl-i;
86         if (isalnum(c) || ispunct(c)) (*ascii++ = c), alen--;
87         else {
88             if (alen <= 3) return bl-i;
89             *ascii++ = '\\';
90             *ascii++ = (c>>6) + '0';
91             *ascii++ = (c>>3 & 7) + '0';
92             *ascii++ = (c&7) + '0';
93             alen -= 4;
94         }
95     }
96     *ascii = 0;                         /* terminate string */
97     return 0;                           /* all OK */
98 }
99
100 /* This is the inverse of the above function.  The return value is the number
101    of bytes read.  The blen parameter gived the maximum size of the output
102    buffer (binary). */
103
104 int ka_ReadBytes (
105   char *ascii,
106   char *binary,
107   int   blen)
108 {
109     char *cp = ascii;
110     char  c;
111     int   i = 0;
112     while ((i < blen) && *cp) {         /* get byte till null or full */
113         if (*cp == '\\') {              /* get byte in octal */
114             c = (*++cp) - '0';
115             c = (c<<3) + (*++cp) - '0';
116             c = (c<<3) + (*++cp) - '0';
117             cp++;
118         } else c = *cp++;               /* get byte */
119         binary[i++] = c;
120     }
121     return i;
122 }
123
124 int umin (
125   afs_uint32 a,
126   afs_uint32 b)
127 {
128     if (a < b) return a;
129     else return b;
130 }
131
132 /* ka_KeyCheckSum - returns a 32 bit cryptographic checksum of a DES encryption
133  * key.  It encrypts a block of zeros and uses first 4 bytes as cksum. */
134
135 afs_int32 ka_KeyCheckSum (
136   char *key,
137   afs_uint32 *cksumP)
138 {
139     des_key_schedule s;
140     char block[8];
141     afs_uint32 cksum;
142     afs_int32 code;
143
144     *cksumP = 0;
145     bzero (block, 8);
146     code = des_key_sched (key, s);
147     if (code) return KABADKEY;
148     des_ecb_encrypt (block, block, s, ENCRYPT);
149     bcopy (block, &cksum, sizeof(afs_int32));
150     *cksumP = ntohl(cksum);
151     return 0;
152 }
153
154 /* is the key all zeros? */
155 int ka_KeyIsZero(
156   register char *akey,
157   register int alen)
158 {
159     register int i;
160     for(i=0;i<alen;i++) {
161         if (*akey++ != 0) return 0;
162     }
163     return 1;
164 }
165
166 void ka_timestr (
167   afs_int32 time,
168   char *tstr,
169   afs_int32 tlen)
170 {
171     char tbuffer[32]; /* need at least 26 bytes */
172     time_t passtime; /* modern systems have 64 bit time */
173
174     if (!time) strcpy (tstr, "no date");/* special case this */
175     else if (time == NEVERDATE) strcpy(tstr, "never");
176     else {
177         passtime = time;
178         strncpy(tstr,
179                 afs_ctime(&passtime, tbuffer, sizeof(tbuffer)), tlen);
180         tstr[strlen(tstr)-1] = '\0';    /* punt the newline character */
181     }
182 }