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