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