xref: /freebsd/crypto/heimdal/lib/krb5/replay.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include "krb5_locl.h"
35 
36 struct krb5_rcache_data {
37     char *name;
38 };
39 
40 krb5_error_code
41 krb5_rc_resolve(krb5_context context,
42 		krb5_rcache id,
43 		const char *name)
44 {
45     id->name = strdup(name);
46     if(id->name == NULL)
47 	return KRB5_RC_MALLOC;
48     return 0;
49 }
50 
51 krb5_error_code
52 krb5_rc_resolve_type(krb5_context context,
53 		     krb5_rcache *id,
54 		     const char *type)
55 {
56     if(strcmp(type, "FILE"))
57 	return KRB5_RC_TYPE_NOTFOUND;
58     *id = calloc(1, sizeof(**id));
59     if(*id == NULL)
60 	return KRB5_RC_MALLOC;
61     return 0;
62 }
63 
64 krb5_error_code
65 krb5_rc_resolve_full(krb5_context context,
66 		     krb5_rcache *id,
67 		     const char *string_name)
68 {
69     krb5_error_code ret;
70     if(strncmp(string_name, "FILE:", 5))
71 	return KRB5_RC_TYPE_NOTFOUND;
72     ret = krb5_rc_resolve_type(context, id, "FILE");
73     if(ret)
74 	return ret;
75     ret = krb5_rc_resolve(context, *id, string_name + 5);
76     return ret;
77 }
78 
79 const char *
80 krb5_rc_default_name(krb5_context context)
81 {
82     return "FILE:/var/run/default_rcache";
83 }
84 
85 krb5_error_code
86 krb5_rc_default(krb5_context context,
87 		krb5_rcache *id)
88 {
89     return krb5_rc_resolve_full(context, id, krb5_rc_default_name(context));
90 }
91 
92 struct rc_entry{
93     time_t stamp;
94     unsigned char data[16];
95 };
96 
97 krb5_error_code
98 krb5_rc_initialize(krb5_context context,
99 		   krb5_rcache id,
100 		   krb5_deltat auth_lifespan)
101 {
102     FILE *f = fopen(id->name, "w");
103     struct rc_entry tmp;
104     if(f == NULL)
105 	return errno;
106     tmp.stamp = auth_lifespan;
107     fwrite(&tmp, 1, sizeof(tmp), f);
108     fclose(f);
109     return 0;
110 }
111 
112 krb5_error_code
113 krb5_rc_recover(krb5_context context,
114 		krb5_rcache id)
115 {
116     return 0;
117 }
118 
119 krb5_error_code
120 krb5_rc_destroy(krb5_context context,
121 		krb5_rcache id)
122 {
123     if(remove(id->name) < 0)
124 	return errno;
125     return krb5_rc_close(context, id);
126 }
127 
128 krb5_error_code
129 krb5_rc_close(krb5_context context,
130 	      krb5_rcache id)
131 {
132     free(id->name);
133     free(id);
134     return 0;
135 }
136 
137 static void
138 checksum_authenticator(Authenticator *auth, void *data)
139 {
140     MD5_CTX md5;
141     int i;
142 
143     MD5Init (&md5);
144     MD5Update (&md5, auth->crealm, strlen(auth->crealm));
145     for(i = 0; i < auth->cname.name_string.len; i++)
146 	MD5Update(&md5, auth->cname.name_string.val[i],
147 		  strlen(auth->cname.name_string.val[i]));
148     MD5Update (&md5, &auth->ctime, sizeof(auth->ctime));
149     MD5Update (&md5, &auth->cusec, sizeof(auth->cusec));
150     MD5Final (&md5, data);
151 }
152 
153 krb5_error_code
154 krb5_rc_store(krb5_context context,
155 	      krb5_rcache id,
156 	      krb5_donot_reply *rep)
157 {
158     struct rc_entry ent, tmp;
159     time_t t;
160     FILE *f;
161     ent.stamp = time(NULL);
162     checksum_authenticator(rep, ent.data);
163     f = fopen(id->name, "r");
164     if(f == NULL)
165 	return errno;
166     fread(&tmp, sizeof(ent), 1, f);
167     t = ent.stamp - tmp.stamp;
168     while(fread(&tmp, sizeof(ent), 1, f)){
169 	if(tmp.stamp < t)
170 	    continue;
171 	if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){
172 	    fclose(f);
173 	    return KRB5_RC_REPLAY;
174 	}
175     }
176     if(ferror(f)){
177 	fclose(f);
178 	return errno;
179     }
180     fclose(f);
181     f = fopen(id->name, "a");
182     if(f == NULL)
183 	return KRB5_RC_IO_UNKNOWN;
184     fwrite(&ent, 1, sizeof(ent), f);
185     fclose(f);
186     return 0;
187 }
188 
189 krb5_error_code
190 krb5_rc_expunge(krb5_context context,
191 		krb5_rcache id)
192 {
193     return 0;
194 }
195 
196 krb5_error_code
197 krb5_rc_get_lifespan(krb5_context context,
198 		     krb5_rcache id,
199 		     krb5_deltat *auth_lifespan)
200 {
201     FILE *f = fopen(id->name, "r");
202     int r;
203     struct rc_entry ent;
204     r = fread(&ent, sizeof(ent), 1, f);
205     fclose(f);
206     if(r){
207 	*auth_lifespan = ent.stamp;
208 	return 0;
209     }
210     return KRB5_RC_IO_UNKNOWN;
211 }
212 const char*
213 krb5_rc_get_name(krb5_context context,
214 		 krb5_rcache id)
215 {
216     return id->name;
217 }
218 
219 const char*
220 krb5_rc_get_type(krb5_context context,
221 		 krb5_rcache id)
222 {
223     return "FILE";
224 }
225 
226