Remove the RCSID macro
[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
14 #include <afs/stds.h>
15 #include <sys/types.h>
16 #ifdef AFS_NT40_ENV
17 #include <winsock2.h>
18 #else
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <sys/file.h>
22 #endif
23 #include <string.h>
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
39 ka_PrintUserID(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)
43 {                               /* for output following userID */
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
50             printf("\\%.3o", *c);
51     if (instance && strlen(instance)) {
52         printf(".");
53         for (c = (unsigned char *)instance; *c; c++)
54             if (isalnum(*c) || (ispunct(*c) && (*c != '@')))
55                 printf("%c", *c);
56             else
57                 printf("\\%.3o", *c);
58     }
59     printf("%s", postfix);
60 }
61
62 void
63 ka_PrintBytes(char bs[], int bl)
64 {
65     int i = 0;
66
67     for (i = 0; i < bl; i++) {
68         unsigned char c = bs[i];
69         printf("\\%.3o", c);
70     }
71 }
72
73 /* converts a byte string to ascii.  Return the number of unconverted bytes. */
74
75 int
76 ka_ConvertBytes(char *ascii,    /* output buffer */
77                 int alen,       /* buffer length */
78                 char bs[],      /* byte string */
79                 int bl)
80 {                               /* number of bytes */
81     int i;
82     unsigned char c;
83
84     alen--;                     /* make room for termination */
85     for (i = 0; i < bl; i++) {
86         c = bs[i];
87         if (alen <= 0)
88             return bl - i;
89         if (isalnum(c) || ispunct(c))
90             (*ascii++ = c), alen--;
91         else {
92             if (alen <= 3)
93                 return bl - i;
94             *ascii++ = '\\';
95             *ascii++ = (c >> 6) + '0';
96             *ascii++ = (c >> 3 & 7) + '0';
97             *ascii++ = (c & 7) + '0';
98             alen -= 4;
99         }
100     }
101     *ascii = 0;                 /* terminate string */
102     return 0;                   /* all OK */
103 }
104
105 /* This is the inverse of the above function.  The return value is the number
106    of bytes read.  The blen parameter gived the maximum size of the output
107    buffer (binary). */
108
109 int
110 ka_ReadBytes(char *ascii, char *binary, int blen)
111 {
112     char *cp = ascii;
113     char c;
114     int i = 0;
115     while ((i < blen) && *cp) { /* get byte till null or full */
116         if (*cp == '\\') {      /* get byte in octal */
117             c = (*++cp) - '0';
118             c = (c << 3) + (*++cp) - '0';
119             c = (c << 3) + (*++cp) - '0';
120             cp++;
121         } else
122             c = *cp++;          /* get byte */
123         binary[i++] = c;
124     }
125     return i;
126 }
127
128 int
129 umin(afs_uint32 a, afs_uint32 b)
130 {
131     if (a < b)
132         return a;
133     else
134         return b;
135 }
136
137 /* ka_KeyCheckSum - returns a 32 bit cryptographic checksum of a DES encryption
138  * key.  It encrypts a block of zeros and uses first 4 bytes as cksum. */
139
140 afs_int32
141 ka_KeyCheckSum(char *key, afs_uint32 * cksumP)
142 {
143     des_key_schedule s;
144     char block[8];
145     afs_uint32 cksum;
146     afs_int32 code;
147
148     *cksumP = 0;
149     memset(block, 0, 8);
150     code = des_key_sched(key, s);
151     if (code)
152         return KABADKEY;
153     des_ecb_encrypt(block, block, s, ENCRYPT);
154     memcpy(&cksum, block, sizeof(afs_int32));
155     *cksumP = ntohl(cksum);
156     return 0;
157 }
158
159 /* is the key all zeros? */
160 int
161 ka_KeyIsZero(register char *akey, register int alen)
162 {
163     register int i;
164     for (i = 0; i < alen; i++) {
165         if (*akey++ != 0)
166             return 0;
167     }
168     return 1;
169 }
170
171 void
172 ka_timestr(afs_int32 time, char *tstr, afs_int32 tlen)
173 {
174     char tbuffer[32];           /* need at least 26 bytes */
175     time_t passtime;            /* modern systems have 64 bit time */
176
177     if (!time)
178         strcpy(tstr, "no date");        /* special case this */
179     else if (time == NEVERDATE)
180         strcpy(tstr, "never");
181     else {
182         passtime = time;
183         strncpy(tstr, afs_ctime(&passtime, tbuffer, sizeof(tbuffer)), tlen);
184         tstr[strlen(tstr) - 1] = '\0';  /* punt the newline character */
185     }
186 }