Initial import from FreeBSD RELENG_4:
[dragonfly.git] / crypto / kerberosIV / lib / krb / lifetime.c
1 /*
2  * Ticket lifetime.  This defines the table used to lookup lifetime
3  * for the fixed part of rande of the one byte lifetime field.  Values
4  * less than 0x80 are intrpreted as the number of 5 minute intervals.
5  * Values from 0x80 to 0xBF should be looked up in this table.  The
6  * value of 0x80 is the same using both methods: 10 and two-thirds
7  * hours .  The lifetime of 0xBF is 30 days.  The intervening values
8  * of have a fixed ratio of roughly 1.06914.  The value 0xFF is
9  * defined to mean a ticket has no expiration time.  This should be
10  * used advisedly since individual servers may impose defacto
11  * upperbounds on ticket lifetimes.
12  */
13
14 #include "krb_locl.h"
15
16 RCSID("$Id: lifetime.c,v 1.9 1997/05/02 14:29:18 assar Exp $");
17
18 /* If you want to disable this feature */
19 int krb_no_long_lifetimes = 0;
20
21 #define TKTLIFENUMFIXED 64
22 #define TKTLIFEMINFIXED 0x80
23 #define TKTLIFEMAXFIXED 0xBF
24 #define TKTLIFENOEXPIRE 0xFF
25 #define MAXTKTLIFETIME  (30*24*3600)    /* 30 days */
26 #ifndef NEVERDATE
27 #define NEVERDATE ((unsigned long)0x7fffffffL)
28 #endif
29
30 static const int tkt_lifetimes[TKTLIFENUMFIXED] = {
31     38400,                              /* 10.67 hours, 0.44 days */ 
32     41055,                              /* 11.40 hours, 0.48 days */ 
33     43894,                              /* 12.19 hours, 0.51 days */ 
34     46929,                              /* 13.04 hours, 0.54 days */ 
35     50174,                              /* 13.94 hours, 0.58 days */ 
36     53643,                              /* 14.90 hours, 0.62 days */ 
37     57352,                              /* 15.93 hours, 0.66 days */ 
38     61318,                              /* 17.03 hours, 0.71 days */ 
39     65558,                              /* 18.21 hours, 0.76 days */ 
40     70091,                              /* 19.47 hours, 0.81 days */ 
41     74937,                              /* 20.82 hours, 0.87 days */ 
42     80119,                              /* 22.26 hours, 0.93 days */ 
43     85658,                              /* 23.79 hours, 0.99 days */ 
44     91581,                              /* 25.44 hours, 1.06 days */ 
45     97914,                              /* 27.20 hours, 1.13 days */ 
46     104684,                             /* 29.08 hours, 1.21 days */ 
47     111922,                             /* 31.09 hours, 1.30 days */ 
48     119661,                             /* 33.24 hours, 1.38 days */ 
49     127935,                             /* 35.54 hours, 1.48 days */ 
50     136781,                             /* 37.99 hours, 1.58 days */ 
51     146239,                             /* 40.62 hours, 1.69 days */ 
52     156350,                             /* 43.43 hours, 1.81 days */ 
53     167161,                             /* 46.43 hours, 1.93 days */ 
54     178720,                             /* 49.64 hours, 2.07 days */ 
55     191077,                             /* 53.08 hours, 2.21 days */ 
56     204289,                             /* 56.75 hours, 2.36 days */ 
57     218415,                             /* 60.67 hours, 2.53 days */ 
58     233517,                             /* 64.87 hours, 2.70 days */ 
59     249664,                             /* 69.35 hours, 2.89 days */ 
60     266926,                             /* 74.15 hours, 3.09 days */ 
61     285383,                             /* 79.27 hours, 3.30 days */ 
62     305116,                             /* 84.75 hours, 3.53 days */ 
63     326213,                             /* 90.61 hours, 3.78 days */ 
64     348769,                             /* 96.88 hours, 4.04 days */ 
65     372885,                             /* 103.58 hours, 4.32 days */ 
66     398668,                             /* 110.74 hours, 4.61 days */ 
67     426234,                             /* 118.40 hours, 4.93 days */ 
68     455705,                             /* 126.58 hours, 5.27 days */ 
69     487215,                             /* 135.34 hours, 5.64 days */ 
70     520904,                             /* 144.70 hours, 6.03 days */ 
71     556921,                             /* 154.70 hours, 6.45 days */ 
72     595430,                             /* 165.40 hours, 6.89 days */ 
73     636601,                             /* 176.83 hours, 7.37 days */ 
74     680618,                             /* 189.06 hours, 7.88 days */ 
75     727680,                             /* 202.13 hours, 8.42 days */ 
76     777995,                             /* 216.11 hours, 9.00 days */ 
77     831789,                             /* 231.05 hours, 9.63 days */ 
78     889303,                             /* 247.03 hours, 10.29 days */ 
79     950794,                             /* 264.11 hours, 11.00 days */ 
80     1016537,                            /* 282.37 hours, 11.77 days */ 
81     1086825,                            /* 301.90 hours, 12.58 days */ 
82     1161973,                            /* 322.77 hours, 13.45 days */ 
83     1242318,                            /* 345.09 hours, 14.38 days */ 
84     1328218,                            /* 368.95 hours, 15.37 days */ 
85     1420057,                            /* 394.46 hours, 16.44 days */ 
86     1518247,                            /* 421.74 hours, 17.57 days */ 
87     1623226,                            /* 450.90 hours, 18.79 days */ 
88     1735464,                            /* 482.07 hours, 20.09 days */ 
89     1855462,                            /* 515.41 hours, 21.48 days */ 
90     1983758,                            /* 551.04 hours, 22.96 days */ 
91     2120925,                            /* 589.15 hours, 24.55 days */ 
92     2267576,                            /* 629.88 hours, 26.25 days */ 
93     2424367,                            /* 673.44 hours, 28.06 days */ 
94     2592000};                           /* 720.00 hours, 30.00 days */ 
95
96 /*
97  * krb_life_to_time - takes a start time and a Kerberos standard
98  * lifetime char and returns the corresponding end time.  There are
99  * four simple cases to be handled.  The first is a life of 0xff,
100  * meaning no expiration, and results in an end time of 0xffffffff.
101  * The second is when life is less than the values covered by the
102  * table.  In this case, the end time is the start time plus the
103  * number of 5 minute intervals specified by life.  The third case
104  * returns start plus the MAXTKTLIFETIME if life is greater than
105  * TKTLIFEMAXFIXED.  The last case, uses the life value (minus
106  * TKTLIFEMINFIXED) as an index into the table to extract the lifetime
107  * in seconds, which is added to start to produce the end time.
108  */
109 u_int32_t
110 krb_life_to_time(u_int32_t start, int life_)
111 {
112     unsigned char life = (unsigned char) life_;
113
114     if (krb_no_long_lifetimes) return start + life*5*60;
115
116     if (life == TKTLIFENOEXPIRE) return NEVERDATE;
117     if (life < TKTLIFEMINFIXED) return start + life*5*60;
118     if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME;
119     return start + tkt_lifetimes[life - TKTLIFEMINFIXED];
120 }
121
122 /*
123  * krb_time_to_life - takes start and end times for the ticket and
124  * returns a Kerberos standard lifetime char, possibily using the
125  * tkt_lifetimes table for lifetimes above 127*5 minutes.  First, the
126  * special case of (end == NEVERDATE) is handled to mean no
127  * expiration.  Then negative lifetimes and those greater than the
128  * maximum ticket lifetime are rejected.  Then lifetimes less than the
129  * first table entry are handled by rounding the requested lifetime
130  * *up* to the next 5 minute interval.  The final step is to search
131  * the table for the smallest entry *greater than or equal* to the
132  * requested entry.
133  */
134 int krb_time_to_life(u_int32_t start, u_int32_t end)
135 {
136     int i;
137     long lifetime = end - start;
138
139     if (krb_no_long_lifetimes) return (lifetime + 5*60 - 1)/(5*60);
140
141     if (end >= NEVERDATE) return TKTLIFENOEXPIRE;
142     if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0;
143     if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60);
144     for (i=0; i<TKTLIFENUMFIXED; i++) {
145         if (lifetime <= tkt_lifetimes[i]) {
146             return i+TKTLIFEMINFIXED;
147         }
148     }
149     return 0;
150 }
151
152 char *
153 krb_life_to_atime(int life)
154 {
155     static char atime[11+1+2+1+2+1+2+1];
156     unsigned long when;
157     int secs, mins, hours;
158
159     if (life == TKTLIFENOEXPIRE && !krb_no_long_lifetimes)
160         return("Forever");
161     when = krb_life_to_time(0, life);
162     secs = when%60;
163     when /= 60;
164     mins = when%60;
165     when /= 60;
166     hours = when%24;
167     when /= 24;
168     snprintf(atime, sizeof(atime), "%d+%02d:%02d:%02d", (int)when, hours, mins, secs);
169     return(atime);
170 }
171
172 int
173 krb_atime_to_life(char *atime)
174 {
175     unsigned long when = 0;
176     char *cp;
177     int colon = 0, plus = 0;
178     int n = 0;
179
180     if (strcasecmp(atime, "forever") == 0)
181         return(TKTLIFENOEXPIRE);
182     
183     for (cp=atime; *cp; cp++) {
184         switch(*cp) {
185             case '0': case '1': case '2': case '3': case '4':
186             case '5': case '6': case '7': case '8': case '9':
187                 n = n*10 + *cp-'0';
188                 break;
189             case '+':
190                 plus++;
191                 when += n;
192                 when *= 24;
193                 n = 0;
194                 break;
195             case ':':
196                 colon++;
197                 when += n;
198                 when *= 60;
199                 n = 0;
200                 break;
201             default:
202                 break;
203         }
204     }
205     when += n;
206     if (plus == 0 && colon == 0)
207         return((unsigned char)when);
208     while (colon < 2) {
209         when *= 60;
210         colon++;
211     }
212     return(krb_time_to_life(0,when));
213 }