root/source4/heimdal/lib/krb5/replay.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. krb5_rc_resolve
  2. krb5_rc_resolve_type
  3. krb5_rc_resolve_full
  4. krb5_rc_default_name
  5. krb5_rc_default_type
  6. krb5_rc_default
  7. krb5_rc_initialize
  8. krb5_rc_recover
  9. krb5_rc_destroy
  10. krb5_rc_close
  11. checksum_authenticator
  12. krb5_rc_store
  13. krb5_rc_expunge
  14. krb5_rc_get_lifespan
  15. krb5_rc_get_name
  16. krb5_rc_get_type
  17. krb5_get_server_rcache

   1 /*
   2  * Copyright (c) 1997-2001 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 #include <vis.h>
  36 
  37 RCSID("$Id$");
  38 
  39 struct krb5_rcache_data {
  40     char *name;
  41 };
  42 
  43 krb5_error_code KRB5_LIB_FUNCTION
  44 krb5_rc_resolve(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  45                 krb5_rcache id,
  46                 const char *name)
  47 {
  48     id->name = strdup(name);
  49     if(id->name == NULL) {
  50         krb5_set_error_message(context, KRB5_RC_MALLOC,
  51                                N_("malloc: out of memory", ""));
  52         return KRB5_RC_MALLOC;
  53     }
  54     return 0;
  55 }
  56 
  57 krb5_error_code KRB5_LIB_FUNCTION
  58 krb5_rc_resolve_type(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  59                      krb5_rcache *id,
  60                      const char *type)
  61 {
  62     *id = NULL;
  63     if(strcmp(type, "FILE")) {
  64         krb5_set_error_message (context, KRB5_RC_TYPE_NOTFOUND,
  65                                 N_("replay cache type %s not supported", ""),
  66                                 type);
  67         return KRB5_RC_TYPE_NOTFOUND;
  68     }
  69     *id = calloc(1, sizeof(**id));
  70     if(*id == NULL) {
  71         krb5_set_error_message(context, KRB5_RC_MALLOC,
  72                                N_("malloc: out of memory", ""));
  73         return KRB5_RC_MALLOC;
  74     }
  75     return 0;
  76 }
  77 
  78 krb5_error_code KRB5_LIB_FUNCTION
  79 krb5_rc_resolve_full(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
  80                      krb5_rcache *id,
  81                      const char *string_name)
  82 {
  83     krb5_error_code ret;
  84 
  85     *id = NULL;
  86 
  87     if(strncmp(string_name, "FILE:", 5)) {
  88         krb5_set_error_message(context, KRB5_RC_TYPE_NOTFOUND,
  89                                N_("replay cache type %s not supported", ""),
  90                                string_name);
  91         return KRB5_RC_TYPE_NOTFOUND;
  92     }
  93     ret = krb5_rc_resolve_type(context, id, "FILE");
  94     if(ret)
  95         return ret;
  96     ret = krb5_rc_resolve(context, *id, string_name + 5);
  97     if (ret) {
  98         krb5_rc_close(context, *id);
  99         *id = NULL;
 100     }
 101     return ret;
 102 }
 103 
 104 const char* KRB5_LIB_FUNCTION
 105 krb5_rc_default_name(krb5_context context)
     /* [<][>][^][v][top][bottom][index][help] */
 106 {
 107     return "FILE:/var/run/default_rcache";
 108 }
 109 
 110 const char* KRB5_LIB_FUNCTION
 111 krb5_rc_default_type(krb5_context context)
     /* [<][>][^][v][top][bottom][index][help] */
 112 {
 113     return "FILE";
 114 }
 115 
 116 krb5_error_code KRB5_LIB_FUNCTION
 117 krb5_rc_default(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 118                 krb5_rcache *id)
 119 {
 120     return krb5_rc_resolve_full(context, id, krb5_rc_default_name(context));
 121 }
 122 
 123 struct rc_entry{
 124     time_t stamp;
 125     unsigned char data[16];
 126 };
 127 
 128 krb5_error_code KRB5_LIB_FUNCTION
 129 krb5_rc_initialize(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 130                    krb5_rcache id,
 131                    krb5_deltat auth_lifespan)
 132 {
 133     FILE *f = fopen(id->name, "w");
 134     struct rc_entry tmp;
 135     int ret;
 136 
 137     if(f == NULL) {
 138         ret = errno;
 139         krb5_set_error_message(context, ret, "open(%s): %s", id->name,
 140                                strerror(ret));
 141         return ret;
 142     }
 143     tmp.stamp = auth_lifespan;
 144     fwrite(&tmp, 1, sizeof(tmp), f);
 145     fclose(f);
 146     return 0;
 147 }
 148 
 149 krb5_error_code KRB5_LIB_FUNCTION
 150 krb5_rc_recover(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 151                 krb5_rcache id)
 152 {
 153     return 0;
 154 }
 155 
 156 krb5_error_code KRB5_LIB_FUNCTION
 157 krb5_rc_destroy(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 158                 krb5_rcache id)
 159 {
 160     int ret;
 161 
 162     if(remove(id->name) < 0) {
 163         ret = errno;
 164         krb5_set_error_message(context, ret, "remove(%s): %s", id->name,
 165                                strerror(ret));
 166         return ret;
 167     }
 168     return krb5_rc_close(context, id);
 169 }
 170 
 171 krb5_error_code KRB5_LIB_FUNCTION
 172 krb5_rc_close(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 173               krb5_rcache id)
 174 {
 175     free(id->name);
 176     free(id);
 177     return 0;
 178 }
 179 
 180 static void
 181 checksum_authenticator(Authenticator *auth, void *data)
     /* [<][>][^][v][top][bottom][index][help] */
 182 {
 183     MD5_CTX md5;
 184     int i;
 185 
 186     MD5_Init (&md5);
 187     MD5_Update (&md5, auth->crealm, strlen(auth->crealm));
 188     for(i = 0; i < auth->cname.name_string.len; i++)
 189         MD5_Update(&md5, auth->cname.name_string.val[i],
 190                    strlen(auth->cname.name_string.val[i]));
 191     MD5_Update (&md5, &auth->ctime, sizeof(auth->ctime));
 192     MD5_Update (&md5, &auth->cusec, sizeof(auth->cusec));
 193     MD5_Final (data, &md5);
 194 }
 195 
 196 krb5_error_code KRB5_LIB_FUNCTION
 197 krb5_rc_store(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 198               krb5_rcache id,
 199               krb5_donot_replay *rep)
 200 {
 201     struct rc_entry ent, tmp;
 202     time_t t;
 203     FILE *f;
 204     int ret;
 205 
 206     ent.stamp = time(NULL);
 207     checksum_authenticator(rep, ent.data);
 208     f = fopen(id->name, "r");
 209     if(f == NULL) {
 210         ret = errno;
 211         krb5_set_error_message(context, ret, "open(%s): %s", id->name,
 212                                strerror(ret));
 213         return ret;
 214     }
 215     rk_cloexec_file(f);
 216     fread(&tmp, sizeof(ent), 1, f);
 217     t = ent.stamp - tmp.stamp;
 218     while(fread(&tmp, sizeof(ent), 1, f)){
 219         if(tmp.stamp < t)
 220             continue;
 221         if(memcmp(tmp.data, ent.data, sizeof(ent.data)) == 0){
 222             fclose(f);
 223             krb5_clear_error_message (context);
 224             return KRB5_RC_REPLAY;
 225         }
 226     }
 227     if(ferror(f)){
 228         ret = errno;
 229         fclose(f);
 230         krb5_set_error_message(context, ret, "%s: %s",
 231                                id->name, strerror(ret));
 232         return ret;
 233     }
 234     fclose(f);
 235     f = fopen(id->name, "a");
 236     if(f == NULL) {
 237         krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN,
 238                                "open(%s): %s", id->name,
 239                                strerror(errno));
 240         return KRB5_RC_IO_UNKNOWN;
 241     }
 242     fwrite(&ent, 1, sizeof(ent), f);
 243     fclose(f);
 244     return 0;
 245 }
 246 
 247 krb5_error_code KRB5_LIB_FUNCTION
 248 krb5_rc_expunge(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 249                 krb5_rcache id)
 250 {
 251     return 0;
 252 }
 253 
 254 krb5_error_code KRB5_LIB_FUNCTION
 255 krb5_rc_get_lifespan(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 256                      krb5_rcache id,
 257                      krb5_deltat *auth_lifespan)
 258 {
 259     FILE *f = fopen(id->name, "r");
 260     int r;
 261     struct rc_entry ent;
 262     r = fread(&ent, sizeof(ent), 1, f);
 263     fclose(f);
 264     if(r){
 265         *auth_lifespan = ent.stamp;
 266         return 0;
 267     }
 268     krb5_clear_error_message (context);
 269     return KRB5_RC_IO_UNKNOWN;
 270 }
 271 
 272 const char* KRB5_LIB_FUNCTION
 273 krb5_rc_get_name(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 274                  krb5_rcache id)
 275 {
 276     return id->name;
 277 }
 278                 
 279 const char* KRB5_LIB_FUNCTION
 280 krb5_rc_get_type(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 281                  krb5_rcache id)
 282 {
 283     return "FILE";
 284 }
 285                 
 286 krb5_error_code KRB5_LIB_FUNCTION
 287 krb5_get_server_rcache(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 288                        const krb5_data *piece,
 289                        krb5_rcache *id)
 290 {
 291     krb5_rcache rcache;
 292     krb5_error_code ret;
 293 
 294     char *tmp = malloc(4 * piece->length + 1);
 295     char *name;
 296 
 297     if(tmp == NULL) {
 298         krb5_set_error_message(context, ENOMEM,
 299                                N_("malloc: out of memory", ""));
 300         return ENOMEM;
 301     }
 302     strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL);
 303 #ifdef HAVE_GETEUID
 304     asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid());
 305 #else
 306     asprintf(&name, "FILE:rc_%s", tmp);
 307 #endif
 308     free(tmp);
 309     if(name == NULL) {
 310         krb5_set_error_message(context, ENOMEM,
 311                                N_("malloc: out of memory", ""));
 312         return ENOMEM;
 313     }
 314 
 315     ret = krb5_rc_resolve_full(context, &rcache, name);
 316     free(name);
 317     if(ret)
 318         return ret;
 319     *id = rcache;
 320     return ret;
 321 }

/* [<][>][^][v][top][bottom][index][help] */