lots of new stuff
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@299 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							| @@ -4,7 +4,8 @@ CFLAGS=-g | ||||
|  | ||||
| YFLAGS = -d | ||||
|  | ||||
| SOURCES = principal.c principal_p.c data.c context.c misc.c string2key.c | ||||
| SOURCES = principal.c principal_p.c data.c context.c misc.c string2key.c \ | ||||
| 	  krbhst.c getport.c send_to_kdc.c | ||||
|  | ||||
| OBJECTS = $(SOURCES:%.c=%.o) config_file.o | ||||
|  | ||||
|   | ||||
							
								
								
									
										256
									
								
								d.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								d.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,256 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <time.h> | ||||
| #include <d.h> | ||||
|  | ||||
| int | ||||
| buf_getbyte (Buffer *b) | ||||
| { | ||||
|      if (b->p >= b->buf + b->len) | ||||
| 	  return EOF; | ||||
|      return *b->p++; | ||||
| } | ||||
|  | ||||
| void | ||||
| buf_init (Buffer *b, char *ptr, unsigned len) | ||||
| { | ||||
|      b->buf = b->p = ptr; | ||||
|      b->len = len; | ||||
| } | ||||
|  | ||||
| Buffer * | ||||
| buf_derive (Buffer *b, Buffer *tmp, int len) | ||||
| { | ||||
|      tmp->buf = tmp->p = b->p; | ||||
|      if(len == -1) | ||||
| 	  tmp->len = buf_bytesleft (b); | ||||
|      else | ||||
| 	  tmp->len = len; | ||||
|      return tmp; | ||||
| } | ||||
|  | ||||
| int | ||||
| buf_bytesleft (Buffer *b) | ||||
| { | ||||
|      return b->len - (b->p - b->buf); | ||||
| } | ||||
|  | ||||
| void | ||||
| buf_advance (Buffer *b, int n) | ||||
| { | ||||
|      b->p += n; | ||||
| } | ||||
|  | ||||
| int | ||||
| buf_length (Buffer *b) | ||||
| { | ||||
|      return b->p - b->buf; | ||||
| } | ||||
|  | ||||
| Identifier * | ||||
| getid (Buffer *b, Identifier *i) | ||||
| { | ||||
|      int c, len; | ||||
|  | ||||
|      c = buf_getbyte (b); | ||||
|      if (c == EOF) | ||||
| 	  return NULL; | ||||
|      i->class = c >> 6; | ||||
|      i->type  = (c >> 5) & 1; | ||||
|      i->tag   = c & 0x1F; | ||||
|      if (i->tag == 0x1F) { | ||||
| 	  do { | ||||
| 	       c = buf_getbyte (b); | ||||
| 	       if (c == EOF) | ||||
| 		    return NULL; | ||||
| 	       i->tag = i->tag * 0x80 + (c & 0x7F); | ||||
| 	  } while( c & 0x80); | ||||
|      } | ||||
|  | ||||
|      c = buf_getbyte (b); | ||||
|      if (c == EOF) | ||||
| 	  return NULL; | ||||
|      len = c; | ||||
|      if (len < 0x80) { | ||||
| 	  i->len = len; | ||||
|      } else if(len > 0x80) { | ||||
| 	  len &= 0x7F; | ||||
| 	  i->len = 0; | ||||
| 	  while (len--) { | ||||
| 	       c = buf_getbyte (b); | ||||
| 	       if (c == EOF) | ||||
| 		    return NULL; | ||||
| 	       i->len = i->len * 0x100 + c; | ||||
| 	  } | ||||
|      } else if (len == 0x80) | ||||
| 	  i->len = -1; | ||||
|      return i; | ||||
| } | ||||
|  | ||||
| Identifier * | ||||
| matchid (Buffer *b, Identifier *i) | ||||
| { | ||||
|      Identifier tmp; | ||||
|  | ||||
|      if (getid (b, &tmp) == NULL) | ||||
| 	  return NULL; | ||||
|      if (tmp.class == i->class && tmp.type == i->type && tmp.tag == i->tag) { | ||||
| 	  i->len = tmp.len; | ||||
| 	  return i; | ||||
|      } else | ||||
| 	  return NULL; | ||||
| } | ||||
|  | ||||
| static Identifier dummy; | ||||
|  | ||||
| Identifier * | ||||
| matchid3 (Buffer *b, Identifier *i, Der_class class, Der_type type, | ||||
| 	  unsigned tag) | ||||
| { | ||||
|      i->class = class; | ||||
|      i->type  = type; | ||||
|      i->tag   = tag; | ||||
|      return matchid (b, i); | ||||
| } | ||||
|  | ||||
| Identifier * | ||||
| matchcontextid (Buffer *b, Identifier *i, int tag) | ||||
| { | ||||
|      Identifier tmp; | ||||
|       | ||||
|      if (matchid3 (b, &tmp, CONTEXT, CONS, tag) == NULL || | ||||
| 	 matchid (b, i) == NULL) | ||||
| 	  return NULL; | ||||
|      return i; | ||||
| } | ||||
|  | ||||
| Identifier * | ||||
| matchcontextid3 (Buffer *b, Identifier *i, Der_class class, | ||||
| 		 Der_type dtype, | ||||
| 		 int type, | ||||
| 		 unsigned tag) | ||||
| { | ||||
|      i->class = class; | ||||
|      i->type  = dtype; | ||||
|      i->tag   = type; | ||||
|      return matchcontextid (b, i, tag); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_integer (Buffer *b, void *val) | ||||
| { | ||||
|      int c; | ||||
|      int res; | ||||
|      int len; | ||||
|  | ||||
|      res = len = 0; | ||||
|      while ((c = buf_getbyte (b)) != EOF) { | ||||
| 	  res = res * 0x100 + c; | ||||
| 	  ++len; | ||||
|      } | ||||
|      *((int *)val) = res; | ||||
|      return len; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_octetstring (Buffer *b, void *val) | ||||
| { | ||||
|      krb5_data *str = (krb5_data *)val; | ||||
|      int len, c; | ||||
|      char *p; | ||||
|  | ||||
|      len = buf_bytesleft (b); | ||||
|      str->len = len; | ||||
|      str->data = p = malloc (len + 1); | ||||
|      while (len && (c = buf_getbyte (b)) != EOF) { | ||||
| 	  *p++ = c; | ||||
| 	  --len; | ||||
|      } | ||||
|      *p++ = '\0'; | ||||
|      return len; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_generalizedtime (Buffer *b, void *val) | ||||
| { | ||||
|      time_t *t = (time_t *)val; | ||||
|      int len; | ||||
|      krb5_data str; | ||||
|      struct tm tm; | ||||
|  | ||||
|      len = der_get_octetstring (b, &str); | ||||
|      sscanf (str.data, "%04d%02d%02d%02d%02d%02dZ", | ||||
| 	     &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, | ||||
| 	     &tm.tm_min, &tm.tm_sec); | ||||
|      tm.tm_year -= 1900; | ||||
|      tm.tm_mon -= 1; | ||||
|      tm.tm_isdst = 0; | ||||
|  | ||||
|      *t = mktime (&tm); | ||||
|      *t -= timezone; | ||||
|  | ||||
|      string_free (str); | ||||
|      return len; | ||||
| } | ||||
|  | ||||
| static int (*get_univ_funcs[])(Buffer *, void *val) = { | ||||
|      NULL,			/*  0 */ | ||||
|      NULL,			/*  1 */ | ||||
|      der_get_integer,		/*  2 */ | ||||
|      NULL,			/*  3 */ | ||||
|      der_get_octetstring,	/*  4 */ | ||||
|      NULL,			/*  5 */ | ||||
|      NULL,			/*  6 */ | ||||
|      NULL,			/*  7 */ | ||||
|      NULL,			/*  8 */ | ||||
|      NULL,			/*  9 */ | ||||
|      NULL,			/* 10 */ | ||||
|      NULL,			/* 11 */ | ||||
|      NULL,			/* 12 */ | ||||
|      NULL,			/* 13 */ | ||||
|      NULL,			/* 14 */ | ||||
|      NULL,			/* 15 */ | ||||
|      NULL,			/* 16 */ | ||||
|      NULL,			/* 17 */ | ||||
|      NULL,			/* 18 */ | ||||
|      NULL,			/* 19 */ | ||||
|      NULL,			/* 20 */ | ||||
|      NULL,			/* 21 */ | ||||
|      NULL,			/* 22 */ | ||||
|      NULL,			/* 23 */ | ||||
|      der_get_generalizedtime,	/* 24 */ | ||||
|      NULL,			/* 25 */ | ||||
|      NULL,			/* 26 */ | ||||
|      der_get_octetstring,	/* 27 */ | ||||
| }; | ||||
|  | ||||
| int | ||||
| der_get_val (Buffer *b, int type, void *val) | ||||
| { | ||||
|      return (*(get_univ_funcs[type]))(b, val); | ||||
| } | ||||
|  | ||||
| void | ||||
| getzeros (Buffer *b, int len) | ||||
| { | ||||
|      if (len == -1) { | ||||
| 	  buf_getbyte (b); | ||||
| 	  buf_getbyte (b); | ||||
|      } | ||||
| } | ||||
|  | ||||
| int | ||||
| getdata (Buffer *b, Identifier *i, void *arg) | ||||
| { | ||||
|      Buffer tmp; | ||||
|      int res; | ||||
|  | ||||
|      buf_derive (b, &tmp, i->len); | ||||
|      res = der_get_val (&tmp, i->tag, arg); | ||||
|      if (i->len == -1) { | ||||
| 	  getzeros (b, i->len); | ||||
| 	  buf_advance (b, res); | ||||
|      } else | ||||
| 	  buf_advance (b, i->len); | ||||
|      return res; | ||||
| } | ||||
							
								
								
									
										27
									
								
								d.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								d.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include <der.h> | ||||
|  | ||||
| struct Buffer { | ||||
|      unsigned char *buf; | ||||
|      unsigned char *p; | ||||
|      unsigned len; | ||||
| }; | ||||
|  | ||||
| typedef struct Buffer Buffer; | ||||
|  | ||||
| int  buf_getbyte (Buffer *); | ||||
| void buf_init (Buffer *, char *, unsigned); | ||||
| Buffer *buf_derive (Buffer *, Buffer *, int); | ||||
| int  buf_bytesleft (Buffer *b); | ||||
| void buf_advance (Buffer *b, int n); | ||||
| int buf_length (Buffer *b); | ||||
|  | ||||
| struct Identifier { | ||||
|      Der_class class; | ||||
|      Der_type type; | ||||
|      unsigned tag; | ||||
|      int len; | ||||
| }; | ||||
|  | ||||
| typedef struct Identifier Identifier; | ||||
|  | ||||
| Identifier *getid (Buffer *b, Identifier *i); | ||||
							
								
								
									
										29
									
								
								der.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								der.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <der.h> | ||||
|  | ||||
| /* | ||||
|  * Type functions | ||||
|  */ | ||||
|  | ||||
| krb5_data | ||||
| string_make_n (int n, char *s) | ||||
| { | ||||
|      krb5_data ret; | ||||
|  | ||||
|      ret.len = n; | ||||
|      ret.data = s; | ||||
|      return ret; | ||||
| } | ||||
|  | ||||
| krb5_data | ||||
| string_make (char *s) | ||||
| { | ||||
|      return string_make_n (strlen (s), s); | ||||
| } | ||||
|  | ||||
| void | ||||
| string_free (krb5_data s) | ||||
| { | ||||
|      free (s.data); | ||||
| } | ||||
							
								
								
									
										30
									
								
								der.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								der.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef DER_H | ||||
|  | ||||
| #define DER_H | ||||
|  | ||||
| typedef enum {UNIV = 0, APPL = 1, CONTEXT = 2 , PRIVATE = 3} Der_class; | ||||
|  | ||||
| typedef enum {PRIM = 0, CONS = 1} Der_type; | ||||
|  | ||||
| /* Universal tags */ | ||||
|  | ||||
| enum { | ||||
|      UT_Integer = 2,	 | ||||
|      UT_BitString = 3, | ||||
|      UT_OctetString = 4, | ||||
|      UT_Null = 5, | ||||
|      UT_ObjID = 6, | ||||
|      UT_Sequence = 16, | ||||
|      UT_Set = 17, | ||||
|      UT_PrintableString = 19, | ||||
|      UT_IA5String = 22, | ||||
|      UT_UTCTime = 23, | ||||
|      UT_GeneralizedTime = 24, | ||||
|      UT_GeneralString = 27, | ||||
| }; | ||||
|  | ||||
| krb5_data string_make (char *); | ||||
| krb5_data string_make_n (int len, char *); | ||||
| void string_free (krb5_data); | ||||
|  | ||||
| #endif /* DER_H */ | ||||
							
								
								
									
										179
									
								
								der_get.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								der_get.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| #include <malloc.h> | ||||
| #include <string.h> | ||||
| #include <der.h> | ||||
|  | ||||
| /* | ||||
|  * Functions for parsing DER | ||||
|  */ | ||||
|  | ||||
| unsigned | ||||
| der_get_length (unsigned char *ptr, unsigned *res) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned char c; | ||||
|  | ||||
|      c = *p++; | ||||
|      if (c < 0x80) { | ||||
| 	  *res = c; | ||||
| 	  return 1; | ||||
|      } else { | ||||
| 	  c &= 0x7F; | ||||
| 	  *res = 0; | ||||
| 	  while (c--) | ||||
| 	       *res = *res * 0x100 + *p++; | ||||
| 	  return p - ptr; | ||||
|      } | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_get_tag (unsigned char *ptr, Der_class *class, Der_type *type, | ||||
| 	     unsigned *tag) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned char o1; | ||||
|  | ||||
|      o1 = *p++; | ||||
|      *class = o1 >> 6; | ||||
|      *type  = (o1 >> 5) & 1; | ||||
|      *tag = o1 & 0x1F; | ||||
|      if (*tag == 0x1F) { | ||||
| 	  do { | ||||
| 	       o1 = *p++; | ||||
| 	       *tag = *tag * 0x80 + (o1 & 0x7F); | ||||
| 	  } while( o1 & 0x80); | ||||
|      } | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_get_integer (unsigned char *ptr, int len, void *v) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned *res = v; | ||||
|  | ||||
|      *res = 0; | ||||
|      while(len--) | ||||
| 	  *res = *res * 0x100 + *p++; | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_get_octetstring (unsigned char *ptr, int len, void *v) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      krb5_data *res = v; | ||||
|  | ||||
|      res->data = malloc(len + 1); | ||||
|      res->len = len; | ||||
|      memcpy (*res, p, len); | ||||
|      (*res)[len] = '\0'; | ||||
|      p += len; | ||||
|  | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| static unsigned (*get_univ_funcs[])(unsigned char *, int len, void *val) = { | ||||
|      NULL,			/*  0 */ | ||||
|      NULL,			/*  1 */ | ||||
|      der_get_integer,		/*  2 */ | ||||
|      NULL,			/*  3 */ | ||||
|      der_get_octetstring,	/*  4 */ | ||||
|      NULL,			/*  5 */ | ||||
|      NULL,			/*  6 */ | ||||
|      NULL,			/*  7 */ | ||||
|      NULL,			/*  8 */ | ||||
|      NULL,			/*  9 */ | ||||
|      NULL,			/* 10 */ | ||||
|      NULL,			/* 11 */ | ||||
|      NULL,			/* 12 */ | ||||
|      NULL,			/* 13 */ | ||||
|      NULL,			/* 14 */ | ||||
|      NULL,			/* 15 */ | ||||
|      NULL,			/* 16 */ | ||||
|      NULL,			/* 17 */ | ||||
|      NULL,			/* 18 */ | ||||
|      NULL,			/* 19 */ | ||||
|      NULL,			/* 20 */ | ||||
|      NULL,			/* 21 */ | ||||
|      NULL,			/* 22 */ | ||||
|      NULL,			/* 23 */ | ||||
|      der_get_octetstring,	/* 24 */ | ||||
|      NULL,			/* 25 */ | ||||
|      NULL,			/* 26 */ | ||||
|      der_get_octetstring,	/* 27 */ | ||||
| }; | ||||
|  | ||||
| unsigned | ||||
| der_get_val (unsigned char *ptr, int type, int len, void *val) | ||||
| { | ||||
|      return (*(get_univ_funcs[type]))(ptr, len, val); | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_get_type (unsigned char *ptr, Der_class *class, Der_type *type, | ||||
| 	      unsigned *tag, unsigned *len) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|  | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_match_type (unsigned char **ptr, Der_class class, Der_type type, | ||||
| 		unsigned tag, unsigned *len) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      Der_class c1; | ||||
|      Der_type t1; | ||||
|      unsigned tag1; | ||||
|  | ||||
|      p += der_get_tag (p, &c1, &t1, &tag1); | ||||
|      if (c1 != class || t1 != type || tag != tag1) | ||||
| 	  return -1; | ||||
|      p += der_get_length (p, len); | ||||
|       | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_context (unsigned char *ptr, unsigned *tag, unsigned *type, | ||||
| 		 unsigned *len) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      Der_class class; | ||||
|      Der_type foo; | ||||
|  | ||||
|      p += der_get_tag (p, &class, &foo, tag); | ||||
|      if (class != CONTEXT || foo != CONS ) | ||||
| 	  return -1; | ||||
|      p += der_get_length (p, len); | ||||
|      p += der_get_tag (p, &class, &foo, type); | ||||
|      if (class != UNIV || foo != PRIM) | ||||
| 	  return -1; | ||||
|      p += der_get_length (p, len); | ||||
|  | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_match_context (unsigned char *ptr, unsigned tag, int type, void *arg) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      int len; | ||||
|      int tlen; | ||||
|  | ||||
|      len = der_match_type (p, CONTEXT, CONS, tag, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      len = der_match_type (p, UNIV, PRIM, type, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|  | ||||
|      p += der_get_val (p, type, tlen, arg); | ||||
|  | ||||
|      return p - ptr; | ||||
| } | ||||
							
								
								
									
										384
									
								
								e.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										384
									
								
								e.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,384 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <d.h> | ||||
| #include <k5_der.h> | ||||
|  | ||||
| int | ||||
| der_get_principalname (Buffer *b, PrincipalName *p) | ||||
| { | ||||
|      Identifier i; | ||||
|      int cur, max; | ||||
|      char *str; | ||||
|      int len; | ||||
|  | ||||
|      p->num_strings = 0; | ||||
|  | ||||
|      if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &p->name_type); | ||||
|      if (matchcontextid3 (b, &i, UNIV, CONS, UT_Sequence, 1) == NULL) | ||||
| 	  return -1; | ||||
|      cur = 0; | ||||
|      max = 1; | ||||
|      p->names = malloc(sizeof(char *) * max); | ||||
|      while (matchid3 (b, &i, UNIV, PRIM, UT_GeneralString)) { | ||||
| 	  if (cur >= max) { | ||||
| 	       max *= 2; | ||||
| 	       p->names = realloc (p->names, sizeof(char *) * max); | ||||
| 	  } | ||||
| 	  getdata (b, &i, &p->names[cur++]); | ||||
|      } | ||||
|      p->num_strings = cur; | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_encrypteddata (Buffer *b, EncryptedData *e) | ||||
| { | ||||
|      Identifier i0, i1, i; | ||||
|      int len; | ||||
|  | ||||
|      if (matchid3 (b, &i0, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &e->etype); | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 1) { | ||||
| 	  int kvno; | ||||
|  | ||||
| 	  if (matchid3 (b, &i, UNIV, PRIM, UT_Integer) == NULL) | ||||
| 	       return -1; | ||||
| 	  getdata (b, &i, &kvno); | ||||
| 	  e->kvno = malloc (sizeof (int)); | ||||
| 	  *(e->kvno) = kvno; | ||||
|      } else | ||||
| 	  e->kvno = NULL; | ||||
|      if (matchid3 (b, &i1, CONTEXT, CONS, 2) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchid3 (b, &i, UNIV, PRIM, UT_OctetString) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &e->cipher); | ||||
|      getzeros (b, i1.len); | ||||
|      getzeros (b, i0.len); | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_ticket (Buffer *b, Ticket *t) | ||||
| { | ||||
|      Identifier i0, i1, i; | ||||
|      Buffer tmp; | ||||
|      int len; | ||||
|  | ||||
|      if (matchid3 (b, &i0, APPL, CONS, APPL_TICKET) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchid3 (b, &i1, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &t->tkt_vno); | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_GeneralString, 1) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &t->realm); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 2) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive(b, &tmp, i.len); | ||||
|      len = der_get_principalname (&tmp, &t->sname); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 3) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive (b, &tmp, i.len); | ||||
|      len = der_get_encrypteddata (&tmp, &t->enc_part); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      getzeros (b, i1.len); | ||||
|      getzeros (b, i0.len); | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_kdc_rep (Buffer *b, int msg, Kdc_Rep *k) | ||||
| { | ||||
|      Identifier i, i0; | ||||
|      Buffer tmp; | ||||
|      int len; | ||||
|  | ||||
|      if (matchid3 (b, &i0, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	  return -1; | ||||
|  | ||||
|      getdata (b, &i, &k->pvno); | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 1) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &k->msg_type); | ||||
|      if (k->msg_type != msg) | ||||
| 	  return -1; | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 2) | ||||
| 	  abort ();		/* XXX */ | ||||
|      if (i.tag != 3) | ||||
| 	  return -1; | ||||
|      if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralString) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &k->realm); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 4) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive(b, &tmp, i.len); | ||||
|      len = der_get_principalname (&tmp, &k->cname); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 5) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive(b, &tmp, i.len); | ||||
|      len = der_get_ticket (&tmp, &k->ticket); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 6) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive(b, &tmp, i.len); | ||||
|      len = der_get_encrypteddata (&tmp, &k->enc_part); | ||||
|      if(len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      getzeros (b, i0.len); | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| static int | ||||
| der_get_kdc_rep_msg (Buffer *b, int msg, Kdc_Rep *a) | ||||
| { | ||||
|      Identifier i; | ||||
|  | ||||
|      if (matchid3(b, &i, APPL, CONS, msg) == NULL) | ||||
| 	  return -1; | ||||
|      return der_get_kdc_rep (b, msg, a); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_as_rep (Buffer *b, As_Rep *a) | ||||
| { | ||||
|      return der_get_kdc_rep_msg (b, KRB_AS_REP, a); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_tgs_rep (Buffer *b, Tgs_Rep *a) | ||||
| { | ||||
|      return der_get_kdc_rep_msg (b, KRB_TGS_REP, a); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_encryptionkey (Buffer *b, EncryptionKey *k) | ||||
| { | ||||
|      Identifier i; | ||||
|  | ||||
|      if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &k->keytype); | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_OctetString, 1) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &k->keyvalue); | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_hostaddresses (Buffer *b, HostAddresses *h) | ||||
| { | ||||
|      Identifier i; | ||||
|      int cur, max; | ||||
|  | ||||
|      if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      cur = 0; | ||||
|      max = 1; | ||||
|      h->addrs = malloc (sizeof (*h->addrs)); | ||||
|      while (matchid3 (b, &i, UNIV, CONS, UT_Sequence)) { | ||||
| 	  if (cur >= max) { | ||||
| 	       max *= 2; | ||||
| 	       h->addrs = realloc (h->addrs, sizeof(*h->addrs) * max); | ||||
| 	  } | ||||
| 	  if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	       return -1; | ||||
| 	  getdata (b, &i, &h->addrs[cur].addr_type); | ||||
| 	  if (matchcontextid3 (b, &i, UNIV, PRIM, UT_OctetString, 1) == NULL) | ||||
| 	       return -1; | ||||
| 	  getdata (b, &i, &h->addrs[cur].addr); | ||||
| 	  ++cur; | ||||
|      } | ||||
|      h->number = cur; | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_lastreq (Buffer *b, LastReq *l) | ||||
| { | ||||
|      Identifier i; | ||||
|      int cur, max; | ||||
|       | ||||
|      if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      cur = 0; | ||||
|      max = 1; | ||||
|      l->values = malloc (sizeof(*l->values)); | ||||
|      while (matchid3 (b, &i, UNIV, CONS, UT_Sequence)) { | ||||
| 	  if (cur >= max) { | ||||
| 	       max *= 2; | ||||
| 	       l->values = realloc (l->values, sizeof (*l->values) * max); | ||||
| 	  } | ||||
| 	  if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 0) == NULL) | ||||
| 	       return -1; | ||||
| 	  getdata (b, &i, &l->values[cur].lr_type); | ||||
| 	  if (matchcontextid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime, 1) == NULL) | ||||
| 	       return -1; | ||||
| 	  getdata (b, &i, &l->values[cur].lr_value); | ||||
| 	  ++cur; | ||||
|      } | ||||
|      l->number = cur; | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_ticketflags (Buffer *b, TicketFlags *t) | ||||
| { | ||||
|      Identifier i; | ||||
|  | ||||
|      return buf_bytesleft (b); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_enckdcreppart (Buffer *b, int msg, EncKdcRepPart *a) | ||||
| { | ||||
|      Identifier i; | ||||
|      Buffer tmp; | ||||
|      int len; | ||||
|  | ||||
|      if (matchid3 (b, &i, UNIV, CONS, UT_Sequence) == NULL) | ||||
| 	  return -1; | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 0) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive (b, &tmp, i.len); | ||||
|      len = der_get_encryptionkey (&tmp, &a->key); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 1) == NULL) | ||||
| 	  return -1; | ||||
|      buf_derive (b, &tmp, i.len); | ||||
|      len = der_get_lastreq (&tmp, &a->req); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_Integer, 2) == NULL) | ||||
| 	  return -1; | ||||
|      getdata (b, &i, &a->nonce); | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 3) { | ||||
| 	  if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime) == NULL) | ||||
| 	       return NULL; | ||||
|  | ||||
| 	  a->key_expiration = malloc (sizeof(*a->key_expiration)); | ||||
| 	  getdata (b, &i, a->key_expiration); | ||||
| 	  getid (b, &i); | ||||
|      } else | ||||
| 	  a->key_expiration = NULL; | ||||
|      if (i.tag != 4) | ||||
| 	  return NULL; | ||||
|      buf_derive (b, &tmp, i.len); | ||||
|      len = der_get_ticketflags (&tmp, &a->flags); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      if (matchcontextid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime, 5) == NULL) | ||||
| 	  return NULL; | ||||
|      getdata (b, &i, &a->authtime); | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 6) { | ||||
| 	  if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime) == NULL) | ||||
| 	       return NULL; | ||||
|  | ||||
| 	  a->starttime = malloc (sizeof(*a->starttime)); | ||||
| 	  getdata (b, &i, a->starttime); | ||||
| 	  getid (b, &i); | ||||
|      } else | ||||
| 	  a->starttime = NULL; | ||||
|      if (i.tag != 7) | ||||
| 	  return NULL; | ||||
|      if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime) == NULL) | ||||
| 	  return NULL; | ||||
|      getdata (b, &i, &a->authtime); | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 8) { | ||||
| 	  if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralizedTime) == NULL) | ||||
| 	       return NULL; | ||||
|  | ||||
| 	  a->renew_till = malloc (sizeof(*a->renew_till)); | ||||
| 	  getdata (b, &i, a->renew_till); | ||||
| 	  getid (b, &i); | ||||
|      } else | ||||
| 	  a->renew_till = NULL; | ||||
|      if (i.tag != 9) | ||||
| 	  return NULL; | ||||
|      if (matchid3 (b, &i, UNIV, PRIM, UT_GeneralString) == NULL) | ||||
| 	  return NULL; | ||||
|      getdata (b, &i, &a->srealm); | ||||
|      if (matchid3 (b, &i, CONTEXT, CONS, 10) == NULL) | ||||
| 	  return NULL; | ||||
|      buf_derive(b, &tmp, i.len); | ||||
|      len = der_get_principalname (&tmp, &a->sname); | ||||
|      if (len == -1) | ||||
| 	  return -1; | ||||
|      buf_advance (b, len); | ||||
|      getzeros (b, i.len); | ||||
|      getid (b, &i); | ||||
|      if (i.tag == 11) { | ||||
| 	  buf_derive (b, &tmp, i.len); | ||||
| 	  len = der_get_hostaddresses (&tmp, &a->caddr); | ||||
| 	  if (len == -1) | ||||
| 	       return -1; | ||||
| 	  buf_advance (b, len); | ||||
| 	  getzeros (b, i.len); | ||||
|      } else | ||||
| 	  a->caddr.number = 0; | ||||
|      return buf_length (b); | ||||
| } | ||||
|  | ||||
| static int | ||||
| der_get_enckdcreppart_msg (Buffer *b, int msg, EncKdcRepPart *a) | ||||
| { | ||||
|      Identifier i; | ||||
|  | ||||
|      if (matchid3 (b, &i, APPL, CONS, msg) == NULL) | ||||
| 	  return -1; | ||||
|      return der_get_enckdcreppart (b, msg, a); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_encasreppart (Buffer *b, EncASRepPart *a) | ||||
| { | ||||
|      return der_get_enckdcreppart_msg (b, KRB_ENCASREPPART, a); | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_enctgsreppart (Buffer *b, EncTGSRepPart *a) | ||||
| { | ||||
|      return der_get_enckdcreppart_msg (b, KRB_ENCKDCREPPART, a); | ||||
| } | ||||
							
								
								
									
										92
									
								
								get_in_tkt.c
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								get_in_tkt.c
									
									
									
									
									
								
							| @@ -1,5 +1,35 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static krb5_error_code | ||||
| krb5_get_salt (krb5_principal princ, | ||||
| 	       krb5_data realm, | ||||
| 	       krb5_data *salt) | ||||
| { | ||||
|      size_t len; | ||||
|      int i; | ||||
|      krb5_error_code err; | ||||
|      char *p; | ||||
|       | ||||
|      len = realm->len; | ||||
|      for (i = 0; i < princ->ncomp; ++i) | ||||
| 	  len += princ->comp[i].length; | ||||
|      err = krb5_alloc (salt, len); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      p = salt->data; | ||||
|      strncpy (p, realm->data, realm->len); | ||||
|      p += realm->len; | ||||
|      for (i = 0; i < princ->cnomp; ++i) { | ||||
| 	  strncpy (p, princ->comp[i].data, princ->comp[i].length); | ||||
| 	  p += princ->comp[i].length; | ||||
|      } | ||||
|      return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_in_tkt(krb5_context context, | ||||
| 		krb5_flags options, | ||||
| @@ -14,5 +44,65 @@ krb5_get_in_tkt(krb5_context context, | ||||
| 		krb5_ccache ccache, | ||||
| 		krb5_kdc_rep **ret_as_reply) | ||||
| { | ||||
|    | ||||
|      As_Req a; | ||||
|      Kdc_Rep rep; | ||||
|      krb5_principal server; | ||||
|      krb5_data req, resp; | ||||
|      char buf[BUFSIZ]; | ||||
|      Buffer buf; | ||||
|      krb5_data salt; | ||||
|      krb5_keyblock *key; | ||||
|  | ||||
|      server.type = KRB_NT_SRV_INST; | ||||
|      server.ncomp = 2; | ||||
|      server.comp = malloc (sizeof(*server.comp) * server.ncomp); | ||||
|      server.comp[0] = string_make ("krbtgt"); | ||||
|      server.comp[1] = creds->client.realm; | ||||
|  | ||||
|      a.pvno = 5; | ||||
|      a.msg_type = KRB_AS_REQ; | ||||
| /* a.kdc_options */ | ||||
|      a.cname = &creds->client; | ||||
|      a.sname = &server; | ||||
|      a.realm = creds->client.realm; | ||||
|      a.till  = creds->times.endtime; | ||||
|      a.nonce = 17; | ||||
|      if (etypes) | ||||
| 	  a.etypes = etypes; | ||||
|      else | ||||
| 	  a.etypes = context->etypes; | ||||
|      if (addrs) | ||||
| 	  a.addresses = addrs; | ||||
|      else | ||||
| 	  a.addresses = krb5_get_all_client_addrs (); | ||||
|       | ||||
|      req.data = buf; | ||||
|  | ||||
|      req.len = der_put_as_req (req.data + sizeof(buf) - 1, &a); | ||||
|      string_free (server.comp[0]); | ||||
|      free (server.comp); | ||||
|      if (addrs == NULL) | ||||
| 	  free (a.addresses); | ||||
|  | ||||
|      err = krb5_sendto_kdc (context, &req, a.realm, &resp); | ||||
|      if (err) { | ||||
| 	  return err; | ||||
|      } | ||||
|      buf_init (&buffer, resp.data, resp.len); | ||||
|      if (der_get_as_rep (&buffer, &rep) == -1) { | ||||
| 	  return ASN1_PARSE_ERROR; | ||||
|      } | ||||
|      err = krb5_get_salt (creds->client, creds->client.realm, &salt); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      err = (*key_proc)(context, b.enc_part.etype, salt, keyseed, &key); | ||||
|      krb5_data_free (&salt); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|       | ||||
|      err = (*decrypt_proc)(context, key, decryptarg, &rep); | ||||
|      memset (&key.contents.data, 0, key.contents.length); | ||||
|      krb5_data_free (&key.contents); | ||||
|      if (err) | ||||
| 	  return err; | ||||
| } | ||||
|   | ||||
							
								
								
									
										41
									
								
								get_in_tkt_pw.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								get_in_tkt_pw.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static krb5_error_code | ||||
| key_proc (krb5_context context, | ||||
| 	  krb5_keytype type, | ||||
| 	  krb5_data *salt, | ||||
| 	  krb5_const_pointer keyseed, | ||||
| 	  krb5_keyblock **key) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char *password = (char *)keyseed; | ||||
|      char buf[BUFSIZ]; | ||||
|       | ||||
|      key = malloc (sizeof (*key)); | ||||
|      if (key == NULL) | ||||
| 	  return ENOMEM; | ||||
|      key->keytype = type; | ||||
|      if (password == NULL) { | ||||
| 	  des_read_pw_string (buf, sizeof(buf), "Password: ", 0); | ||||
| 	  password = buf; | ||||
|      } | ||||
|      err = krb5_string_to_key (password, salt, key); | ||||
|      memset (buf, 0, sizeof(buf)); | ||||
|      return err; | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_in_tkt_with_password (krb5_context context, | ||||
| 			       krb5_flags options, | ||||
| 			       krb5_address *const *addrs, | ||||
| 			       const krb5_enctype *etypes, | ||||
| 			       const krb5_preauthtype *pre_auth_types, | ||||
| 			       const char *password, | ||||
| 			       krb5_ccache ccache, | ||||
| 			       krb5_creds *creds, | ||||
| 			       krb5_kdc-rep **ret_as_reply) | ||||
| { | ||||
|      return krb5_get_in_tkt (context, options, addrs, etypes, | ||||
| 			     pre_auth_types, key_proc, password, | ||||
| 			     NULL, NULL, creds, cache, ret_as_reply); | ||||
| } | ||||
							
								
								
									
										17
									
								
								get_port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								get_port.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #include <krb5_locl.h> | ||||
|  | ||||
| int | ||||
| krb5_getportbyname (const char *service, | ||||
| 		    const char *proto, | ||||
| 		    int default_port) | ||||
| { | ||||
|     struct servent *sp; | ||||
|  | ||||
|     if ((sp = getservbyname (service, proto)) == NULL) { | ||||
| 	 fprintf (stderr, "%s/%s unknown service, " | ||||
| 		  "using default port %d\n", service, proto, | ||||
| 		  ntohs(default_port)); | ||||
| 	 return default_port; | ||||
|     } else | ||||
| 	 return sp->s_port; | ||||
| } | ||||
							
								
								
									
										252
									
								
								k5_der.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								k5_der.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,252 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/types.h> | ||||
| #include <time.h> | ||||
| #include <sys/time.h> | ||||
| #include <k5_der.h> | ||||
|  | ||||
| static void | ||||
| time2generalizedtime (krb5_data *s, time_t t) | ||||
| { | ||||
|      struct tm *tm; | ||||
|  | ||||
|      s->data = malloc(16); | ||||
|      s->len = 15; | ||||
|      tm = gmtime (&t); | ||||
|      sprintf (s->data, "%04d%02d%02d%02d%02d%02dZ", tm->tm_year + 1900, | ||||
| 	      tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, | ||||
| 	      tm->tm_sec); | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_context_etypes (unsigned char *ptr, int tag, | ||||
| 			EncryptionType *etypes, unsigned num_etypes) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      int i; | ||||
|  | ||||
|      for (i = num_etypes - 1; i >= 0; --i) | ||||
| 	  p -= der_put_type_and_value (p, UT_Integer, &etypes[i]); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_context_principalname (unsigned char *ptr, int tag, | ||||
| 			       PrincipalName *name) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      int i; | ||||
|  | ||||
|      if (name == NULL) | ||||
| 	  return 0; | ||||
|      for (i = name->num_strings - 1; i >= 0; --i) | ||||
| 	  p -= der_put_type_and_value (p, UT_GeneralString, | ||||
| 				       &name->names[i]); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      p -= der_put_type (p, CONTEXT, CONS, 1, ptr - p); | ||||
|      p -= der_put_context (p, 0, UT_Integer, &name->name_type); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_context_kdcoptions (unsigned char *ptr, int tag, KdcOptions *k) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      /* XXX */ | ||||
|       | ||||
|      *p-- = '\0'; | ||||
|      *p-- = '\0'; | ||||
|      *p-- = '\0'; | ||||
|      *p-- = '\0'; | ||||
|      *p-- = '\0'; | ||||
|      *p-- = 5; | ||||
|      *p-- = 3; | ||||
|      p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_context_hostaddresses (unsigned char *ptr, int tag, | ||||
| 			       HostAddress *addrs, | ||||
| 			       unsigned naddr) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      int i; | ||||
|       | ||||
|      for(i = naddr - 1; i >= 0; --i) { | ||||
| 	  p -= der_put_context (p, 1, UT_OctetString, &addrs[i].addr); | ||||
| 	  p -= der_put_context (p, 0, UT_Integer, &addrs[i].addr_type); | ||||
|      } | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      p -= der_put_type (p, CONTEXT, CONS, tag, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_kdc_req_body (unsigned char *ptr, Kdc_Req *k) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned random = 17; | ||||
|  | ||||
|      /* additional-tickets[11] SEQUENCE OF Ticket OPTIONAL */ | ||||
|      /* enc-authorization-data[10] EncryptedData OPTIONAL */ | ||||
|      p -= der_put_context_hostaddresses (p, 9, k->addrs, | ||||
| 					 k->num_addrs); | ||||
|      /* addresses[9] HostAddresses OPTIONAL */ | ||||
|      p -= der_put_context_etypes (p, 8, k->etypes, k->num_etypes); | ||||
|      p -= der_put_context (p, 7, UT_Integer, &random); | ||||
|      /* rtime[6] KerberosTime OPTIONAL */ | ||||
|      { | ||||
| 	  krb5_data t; | ||||
|  | ||||
| 	  time2generalizedtime (&t, k->till); | ||||
| 	  p -= der_put_context (p, 5, UT_GeneralizedTime, &t); | ||||
| 	  string_free (t); | ||||
|      } | ||||
|      /* from[4] KerberosTime OPTIONAL */ | ||||
|      p -= der_put_context_principalname (p, 3, k->sname); | ||||
|      p -= der_put_context (p, 2, UT_GeneralString, &k->realm); | ||||
|      p -= der_put_context_principalname (p, 1, k->cname); | ||||
|      p -= der_put_context_kdcoptions (p, 0, &k->kdc_options); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_kdc_req (unsigned char *ptr, int msg_type, Kdc_Req *k) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|  | ||||
|      p -= der_put_kdc_req_body (p, k); | ||||
|      p -= der_put_type (p, CONTEXT, CONS, 4, ptr - p); | ||||
|      /* padata[3] SEQUENCE OF PA-DATA OPTIONAL */ | ||||
|      p -= der_put_context (p, 2, UT_Integer, &k->msg_type); | ||||
|      p -= der_put_context (p, 1, UT_Integer, &k->pvno); | ||||
|      p -= der_put_type (p, UNIV, CONS, UT_Sequence, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| unsigned | ||||
| der_put_as_req (unsigned char *ptr, As_Req *a) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|  | ||||
|      p -= der_put_kdc_req (p, a->msg_type, a); | ||||
|      p -= der_put_type (p, APPL, CONS, a->msg_type, ptr - p); | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
|  | ||||
| /* | ||||
|  * Get functions | ||||
|  */ | ||||
|  | ||||
| int | ||||
| der_get_principalname (unsigned char *ptr, Principalname *name) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned char *p0; | ||||
|      int tlen, tlen2; | ||||
|  | ||||
|      len = der_match_type (p, UNIV, CONS, UT_Sequence, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      p0 = p; | ||||
|      len = der_match_context (p, 0, UT_Integer, &name->name_type); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      len = der_match_type (p, CONTEXT, CONS, 1, &tlen2); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p =+ len; | ||||
|      len = der_match_type () | ||||
|      while(p < p0 + tlen) { | ||||
|      } | ||||
|  | ||||
|  | ||||
|      return ptr - p; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_kdc_rep (unsigned char *ptr, unsigned mylen, int msg_type, | ||||
| 		 Kdc_Rep *k) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      unsigned tlen, slen; | ||||
|      int len; | ||||
|      unsigned kvno, msg1; | ||||
|      unsigned tag; | ||||
|      int type; | ||||
| 	   | ||||
|      len = der_match_type (p, UNIV, CONS, UT_Sequence, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      len = der_match_context (p, 0, UT_Integer, &kvno); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      if (kvno != 5) | ||||
| 	  return -1; | ||||
|      len = der_match_context (p, 1, UT_Integer, &msg1); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      if (msg1 != msg_type) | ||||
| 	  return -1; | ||||
|      len = der_get_context (p, &tag, &type, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      if (tag == 2) | ||||
| 	  abort ();		/* XXX */ | ||||
|      else if (tag == 3) { | ||||
| 	  p += der_get_val (p, UT_GeneralString, tlen, &k->realm); | ||||
|      } | ||||
|      len = der_get_context (p, &tag, &type, &tlen); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      der_get_principalname | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| int | ||||
| der_get_as_rep (unsigned char *ptr, As_Rep *a) | ||||
| { | ||||
|      unsigned char *p = ptr; | ||||
|      int len; | ||||
|      unsigned tlen; | ||||
|  | ||||
|      len = der_match_type (p, APPL, CONS, KRB_AS_REP, &tlen); | ||||
|      if(len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|      len = der_get_kdc_rep (p, tlen, KRB_AS_REP, a); | ||||
|      if (len < 0) | ||||
| 	  return len; | ||||
|      else | ||||
| 	  p += len; | ||||
|       | ||||
|      return p - ptr; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										189
									
								
								k5_der.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								k5_der.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| #include <der.h> | ||||
| #include <time.h> | ||||
|  | ||||
| /* | ||||
|  * Message types. | ||||
|  */ | ||||
|  | ||||
| enum { | ||||
|   KRB_AS_REQ  = 10, | ||||
|   KRB_AS_REP  = 11, | ||||
|   KRB_TGS_REQ = 12, | ||||
|   KRB_TGS_REP = 13, | ||||
|   KRB_AP_REQ  = 14, | ||||
|   KRB_AP_REP  = 15, | ||||
|   KRB_SAFE    = 20, | ||||
|   KRB_PRIV    = 21, | ||||
|   KRB_CRED    = 22, | ||||
|   KRB_ENCASREPPART = 25, | ||||
|   KRB_ENCKDCREPPART = 26, | ||||
|   KRB_ERROR   = 30 | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Application | ||||
|  */ | ||||
|  | ||||
| enum { | ||||
|   APPL_TICKET = 1 | ||||
| }; | ||||
|  | ||||
| struct HostAddress { | ||||
|      int addr_type; | ||||
|      krb5_data addr; | ||||
| }; | ||||
|  | ||||
| typedef struct HostAddress HostAddress; | ||||
|  | ||||
| struct HostAddresses { | ||||
|      int number; | ||||
|      HostAddress *addrs; | ||||
| }; | ||||
|  | ||||
| typedef struct HostAddresses HostAddresses; | ||||
|  | ||||
| struct PrincipalName { | ||||
|      int name_type; | ||||
|      unsigned num_strings; | ||||
|      krb5_data *names; | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|      nt_unknown = 0, | ||||
|      nt_principal = 1, | ||||
|      nt_srv_inst = 2, | ||||
|      nt_srv_hst = 3, | ||||
|      nt_srv_xhst = 4, | ||||
|      nt_uid = 5 | ||||
| }; | ||||
|  | ||||
| typedef struct PrincipalName PrincipalName; | ||||
|  | ||||
| struct KdcOptions { | ||||
|      unsigned | ||||
| 	  reserved : 1, | ||||
| 	  forwardable : 1, | ||||
| 	  forwarded : 1, | ||||
| 	  proxiable : 1, | ||||
| 	  proxy : 1, | ||||
| 	  allow_postdate : 1, | ||||
| 	  postdated : 1, | ||||
| 	  unused7 : 1, | ||||
| 	  renewable : 1, | ||||
| 	  unused9 : 1, | ||||
| 	  unused10 : 1, | ||||
| 	  unused11 : 1, | ||||
| 	  renewable_ok : 1, | ||||
| 	  enc_tkt_in_skey : 1, | ||||
| 	  renew : 1, | ||||
| 	  validate : 1; | ||||
| }; | ||||
|  | ||||
| typedef struct KdcOptions KdcOptions; | ||||
|  | ||||
| typedef krb5_data Realm; | ||||
|  | ||||
| typedef int EncryptionType; | ||||
|  | ||||
| struct  Kdc_Req { | ||||
|      int pvno; | ||||
|      int msg_type; | ||||
|      KdcOptions kdc_options; | ||||
|      PrincipalName *cname; | ||||
|      Realm realm; | ||||
|      PrincipalName *sname; | ||||
|      time_t till; | ||||
|      unsigned num_etypes; | ||||
|      EncryptionType *etypes; | ||||
|      HostAddress *addrs; | ||||
|      unsigned num_addrs; | ||||
| }; | ||||
|  | ||||
| typedef struct Kdc_Req Kdc_Req; | ||||
|  | ||||
| typedef Kdc_Req As_Req; | ||||
|  | ||||
| struct EncryptedData { | ||||
|      int etype; | ||||
|      int *kvno; | ||||
|      krb5_data cipher; | ||||
| }; | ||||
|  | ||||
| typedef struct EncryptedData EncryptedData; | ||||
|  | ||||
| struct Ticket { | ||||
|      int tkt_vno; | ||||
|      Realm realm; | ||||
|      PrincipalName sname; | ||||
|      EncryptedData enc_part; | ||||
| }; | ||||
|  | ||||
| typedef struct Ticket Ticket; | ||||
|  | ||||
| struct Kdc_Rep { | ||||
|      int pvno; | ||||
|      int msg_type; | ||||
|      Realm realm; | ||||
|      PrincipalName cname; | ||||
|      Ticket ticket; | ||||
|      EncryptedData enc_part; | ||||
| }; | ||||
|  | ||||
| typedef struct Kdc_Rep Kdc_Rep; | ||||
|  | ||||
| typedef Kdc_Rep As_Rep; | ||||
|  | ||||
| typedef Kdc_Rep Tgs_Rep; | ||||
|  | ||||
| struct EncryptionKey { | ||||
|      int keytype; | ||||
|      krb5_data keyvalue; | ||||
| }; | ||||
|  | ||||
| typedef struct EncryptionKey EncryptionKey; | ||||
|  | ||||
| struct LastReq { | ||||
|      int number; | ||||
|      struct { | ||||
| 	  int lr_type; | ||||
| 	  time_t lr_value; | ||||
|      } *values; | ||||
| }; | ||||
|  | ||||
| typedef struct LastReq LastReq; | ||||
|  | ||||
| struct TicketFlags { | ||||
|      unsigned forwardable:1, | ||||
| 	  forwarded:1, | ||||
| 	  proxiable:1, | ||||
| 	  proxy:1, | ||||
| 	  may_postdate:1, | ||||
| 	  postdated:1, | ||||
| 	  invalid:1, | ||||
| 	  renewable:1, | ||||
| 	  initial:1, | ||||
| 	  pre_authent:1, | ||||
| 	  hw_authent:1; | ||||
| }; | ||||
|  | ||||
| typedef struct TicketFlags TicketFlags; | ||||
|  | ||||
| struct EncKdcRepPart { | ||||
|      EncryptionKey key; | ||||
|      LastReq req; | ||||
|      int nonce; | ||||
|      time_t *key_expiration; | ||||
|      TicketFlags flags; | ||||
|      time_t authtime; | ||||
|      time_t *starttime; | ||||
|      time_t endtime; | ||||
|      time_t *renew_till; | ||||
|      Realm srealm; | ||||
|      PrincipalName sname; | ||||
|      HostAddresses caddr; | ||||
| }; | ||||
|  | ||||
| typedef struct EncKdcRepPart EncKdcRepPart; | ||||
|  | ||||
| typedef EncKdcRepPart EncASRepPart; | ||||
| typedef EncKdcRepPart EncTGSRepPart; | ||||
							
								
								
									
										27
									
								
								krbhst.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								krbhst.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_krbhst (krb5_context context, | ||||
| 		 const krb5_data *realm, | ||||
| 		 char ***hostlist) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char buf[BUFSIZ]; | ||||
|      char *val; | ||||
|       | ||||
|      sprintf (buf, "realms %s kdc", realm.data); | ||||
|      err = krb5_get_config_tag (context.cf, buf, &val); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      **hostlist = malloc (2 * sizeof (char *)); | ||||
|      (*hostlist)[0] = val; | ||||
|      (*hostlist)[1] = NULL; | ||||
|      return 0; | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_free_krbhst (krb5_context context, | ||||
| 		  char *const *hostlist) | ||||
| { | ||||
|      free (hostlist); | ||||
| } | ||||
| @@ -1,5 +1,35 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static krb5_error_code | ||||
| krb5_get_salt (krb5_principal princ, | ||||
| 	       krb5_data realm, | ||||
| 	       krb5_data *salt) | ||||
| { | ||||
|      size_t len; | ||||
|      int i; | ||||
|      krb5_error_code err; | ||||
|      char *p; | ||||
|       | ||||
|      len = realm->len; | ||||
|      for (i = 0; i < princ->ncomp; ++i) | ||||
| 	  len += princ->comp[i].length; | ||||
|      err = krb5_alloc (salt, len); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      p = salt->data; | ||||
|      strncpy (p, realm->data, realm->len); | ||||
|      p += realm->len; | ||||
|      for (i = 0; i < princ->cnomp; ++i) { | ||||
| 	  strncpy (p, princ->comp[i].data, princ->comp[i].length); | ||||
| 	  p += princ->comp[i].length; | ||||
|      } | ||||
|      return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_in_tkt(krb5_context context, | ||||
| 		krb5_flags options, | ||||
| @@ -14,5 +44,65 @@ krb5_get_in_tkt(krb5_context context, | ||||
| 		krb5_ccache ccache, | ||||
| 		krb5_kdc_rep **ret_as_reply) | ||||
| { | ||||
|    | ||||
|      As_Req a; | ||||
|      Kdc_Rep rep; | ||||
|      krb5_principal server; | ||||
|      krb5_data req, resp; | ||||
|      char buf[BUFSIZ]; | ||||
|      Buffer buf; | ||||
|      krb5_data salt; | ||||
|      krb5_keyblock *key; | ||||
|  | ||||
|      server.type = KRB_NT_SRV_INST; | ||||
|      server.ncomp = 2; | ||||
|      server.comp = malloc (sizeof(*server.comp) * server.ncomp); | ||||
|      server.comp[0] = string_make ("krbtgt"); | ||||
|      server.comp[1] = creds->client.realm; | ||||
|  | ||||
|      a.pvno = 5; | ||||
|      a.msg_type = KRB_AS_REQ; | ||||
| /* a.kdc_options */ | ||||
|      a.cname = &creds->client; | ||||
|      a.sname = &server; | ||||
|      a.realm = creds->client.realm; | ||||
|      a.till  = creds->times.endtime; | ||||
|      a.nonce = 17; | ||||
|      if (etypes) | ||||
| 	  a.etypes = etypes; | ||||
|      else | ||||
| 	  a.etypes = context->etypes; | ||||
|      if (addrs) | ||||
| 	  a.addresses = addrs; | ||||
|      else | ||||
| 	  a.addresses = krb5_get_all_client_addrs (); | ||||
|       | ||||
|      req.data = buf; | ||||
|  | ||||
|      req.len = der_put_as_req (req.data + sizeof(buf) - 1, &a); | ||||
|      string_free (server.comp[0]); | ||||
|      free (server.comp); | ||||
|      if (addrs == NULL) | ||||
| 	  free (a.addresses); | ||||
|  | ||||
|      err = krb5_sendto_kdc (context, &req, a.realm, &resp); | ||||
|      if (err) { | ||||
| 	  return err; | ||||
|      } | ||||
|      buf_init (&buffer, resp.data, resp.len); | ||||
|      if (der_get_as_rep (&buffer, &rep) == -1) { | ||||
| 	  return ASN1_PARSE_ERROR; | ||||
|      } | ||||
|      err = krb5_get_salt (creds->client, creds->client.realm, &salt); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      err = (*key_proc)(context, b.enc_part.etype, salt, keyseed, &key); | ||||
|      krb5_data_free (&salt); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|       | ||||
|      err = (*decrypt_proc)(context, key, decryptarg, &rep); | ||||
|      memset (&key.contents.data, 0, key.contents.length); | ||||
|      krb5_data_free (&key.contents); | ||||
|      if (err) | ||||
| 	  return err; | ||||
| } | ||||
|   | ||||
							
								
								
									
										41
									
								
								lib/krb5/get_in_tkt_pw.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								lib/krb5/get_in_tkt_pw.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static krb5_error_code | ||||
| key_proc (krb5_context context, | ||||
| 	  krb5_keytype type, | ||||
| 	  krb5_data *salt, | ||||
| 	  krb5_const_pointer keyseed, | ||||
| 	  krb5_keyblock **key) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char *password = (char *)keyseed; | ||||
|      char buf[BUFSIZ]; | ||||
|       | ||||
|      key = malloc (sizeof (*key)); | ||||
|      if (key == NULL) | ||||
| 	  return ENOMEM; | ||||
|      key->keytype = type; | ||||
|      if (password == NULL) { | ||||
| 	  des_read_pw_string (buf, sizeof(buf), "Password: ", 0); | ||||
| 	  password = buf; | ||||
|      } | ||||
|      err = krb5_string_to_key (password, salt, key); | ||||
|      memset (buf, 0, sizeof(buf)); | ||||
|      return err; | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_in_tkt_with_password (krb5_context context, | ||||
| 			       krb5_flags options, | ||||
| 			       krb5_address *const *addrs, | ||||
| 			       const krb5_enctype *etypes, | ||||
| 			       const krb5_preauthtype *pre_auth_types, | ||||
| 			       const char *password, | ||||
| 			       krb5_ccache ccache, | ||||
| 			       krb5_creds *creds, | ||||
| 			       krb5_kdc-rep **ret_as_reply) | ||||
| { | ||||
|      return krb5_get_in_tkt (context, options, addrs, etypes, | ||||
| 			     pre_auth_types, key_proc, password, | ||||
| 			     NULL, NULL, creds, cache, ret_as_reply); | ||||
| } | ||||
							
								
								
									
										17
									
								
								lib/krb5/get_port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								lib/krb5/get_port.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #include <krb5_locl.h> | ||||
|  | ||||
| int | ||||
| krb5_getportbyname (const char *service, | ||||
| 		    const char *proto, | ||||
| 		    int default_port) | ||||
| { | ||||
|     struct servent *sp; | ||||
|  | ||||
|     if ((sp = getservbyname (service, proto)) == NULL) { | ||||
| 	 fprintf (stderr, "%s/%s unknown service, " | ||||
| 		  "using default port %d\n", service, proto, | ||||
| 		  ntohs(default_port)); | ||||
| 	 return default_port; | ||||
|     } else | ||||
| 	 return sp->s_port; | ||||
| } | ||||
							
								
								
									
										27
									
								
								lib/krb5/krbhst.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								lib/krb5/krbhst.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_get_krbhst (krb5_context context, | ||||
| 		 const krb5_data *realm, | ||||
| 		 char ***hostlist) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char buf[BUFSIZ]; | ||||
|      char *val; | ||||
|       | ||||
|      sprintf (buf, "realms %s kdc", realm.data); | ||||
|      err = krb5_get_config_tag (context.cf, buf, &val); | ||||
|      if (err) | ||||
| 	  return err; | ||||
|      **hostlist = malloc (2 * sizeof (char *)); | ||||
|      (*hostlist)[0] = val; | ||||
|      (*hostlist)[1] = NULL; | ||||
|      return 0; | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_free_krbhst (krb5_context context, | ||||
| 		  char *const *hostlist) | ||||
| { | ||||
|      free (hostlist); | ||||
| } | ||||
							
								
								
									
										85
									
								
								lib/krb5/send_to_kdc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/krb5/send_to_kdc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static int | ||||
| send_and_recv (int fd, | ||||
| 	       struct sockaddr_in *addr, | ||||
| 	       krb5_data *send, | ||||
| 	       krb5_data *recv) | ||||
| { | ||||
|      struct fdset fdset; | ||||
|      struct timeval timeout; | ||||
|      int ret; | ||||
|      long nbytes; | ||||
|  | ||||
|      if (sendto (fd, send->data, send->len, 0, | ||||
| 		 (struct sockaddr *)addr, sizeof(*addr)) < 0) | ||||
| 	  return -1; | ||||
|      FD_ZERO(&fdset); | ||||
|      FD_SET(fd, &fdset); | ||||
|      timeout.tv_sec  = 3; | ||||
|      timeout.tv_usec = 0; | ||||
|      ret = select (fd + 1, &fdset, NULL, NULL, &timeout); | ||||
|      if (ret <= 0) | ||||
| 	  return -1; | ||||
|      else { | ||||
| 	  ioctl (fd, FIONREAD, &nbytes); | ||||
|  | ||||
| 	  nbytes -= sizeof(struct udphdr) + sizeof(struct iphdr); | ||||
|  | ||||
| 	  recv->data = malloc (nbytes); | ||||
| 	  ret = recvfrom (fd, recv->data, nbytes, 0, NULL, 0); | ||||
| 	  if (ret < 0) { | ||||
| 	       free (recv->data); | ||||
| 	       return -1; | ||||
| 	  } | ||||
| 	  recv->data = realloc (recv->data, ret); | ||||
| 	  recv->len  = ret; | ||||
| 	  return 0; | ||||
|      } | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_sentdo_kdc (krb5_context context, | ||||
| 		 const krb5_data *send, | ||||
| 		 const krb5_data *realm, | ||||
| 		 krb5_data *receive) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char **hostlist, **hp, *p; | ||||
|      struct hostent *hostent; | ||||
|      int fd; | ||||
|      int port; | ||||
|      int i; | ||||
|  | ||||
|      port = krb5_getportbyname ("kerberos", "udp", htons(750)); | ||||
|      fd = socket (AF_INET, SOCK_DGRAM, 0); | ||||
|      if (fd < 0) | ||||
| 	  return errno; | ||||
|  | ||||
|      err = krb5_get_krbhst (context, realm, &hostlist); | ||||
|      if (err) { | ||||
| 	  close (fd); | ||||
| 	  return err; | ||||
|      } | ||||
|      for (i = 0; i < 3; ++i) | ||||
| 	  for (hp = hostlist; p = *hp; ++hp) { | ||||
| 	       char *addr; | ||||
|  | ||||
| 	       hostent = gethostbyname (p); | ||||
| 	       while (addr = *hostent->h_addr_list++) { | ||||
| 		    struct sockaddr_in a; | ||||
| 		     | ||||
| 		    memset (a, 0, sizeof(a)); | ||||
| 		    a.sin_family = AF_INET; | ||||
| 		    a.sin_port   = port; | ||||
| 		    a.sin_addr   = *((struct in_addr *)addr); | ||||
| 		     | ||||
| 		    if (send_and_recv (fd, &a, send, recv) == 0) { | ||||
| 			 krb5_free_krbhst (context, hostlist); | ||||
| 			 return KDC_ERR_NONE; | ||||
| 		    } | ||||
| 	       } | ||||
| 	  } | ||||
|      krb5_free_krbhst (context, hostlist); | ||||
|      return KRB5_KDC_UNREACH; | ||||
| } | ||||
							
								
								
									
										141
									
								
								lib/krb5/str2key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								lib/krb5/str2key.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| #include <krb5_locl.h> | ||||
|  | ||||
| /* | ||||
|  * Reverse 8 bytes | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| reverse (unsigned char *s) | ||||
| { | ||||
|      static unsigned char tbl[] = { | ||||
| 	  0x0, | ||||
| 	  0x8, | ||||
| 	  0x4, | ||||
| 	  0xC, | ||||
| 	  0x2, | ||||
| 	  0xA, | ||||
| 	  0x6, | ||||
| 	  0xE, | ||||
| 	  0x1, | ||||
| 	  0x9, | ||||
| 	  0x5, | ||||
| 	  0xD, | ||||
| 	  0x3, | ||||
| 	  0xB, | ||||
| 	  0x7, | ||||
| 	  0xF | ||||
|      }; | ||||
|  | ||||
|      char tmp; | ||||
|  | ||||
| #define REVONE(str, i, j) \ | ||||
| do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0) | ||||
|  | ||||
|      REVONE(s,0,7); | ||||
|      REVONE(s,1,6); | ||||
|      REVONE(s,2,5); | ||||
|      REVONE(s,3,4); | ||||
| #undef REVONE | ||||
|  | ||||
| #define REVTWO(q) \ | ||||
| q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4]) | ||||
|  | ||||
|      REVTWO(s[0]); | ||||
|      REVTWO(s[1]); | ||||
|      REVTWO(s[2]); | ||||
|      REVTWO(s[3]); | ||||
|      REVTWO(s[4]); | ||||
|      REVTWO(s[5]); | ||||
|      REVTWO(s[6]); | ||||
|      REVTWO(s[7]); | ||||
|  | ||||
| #undef REVTWO | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * A = A xor B. A & B is 8 bytes. | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| xor (unsigned char *a, unsigned char *b) | ||||
| { | ||||
|      a[0] ^= b[0]; | ||||
|      a[1] ^= b[1]; | ||||
|      a[2] ^= b[2]; | ||||
|      a[3] ^= b[3]; | ||||
|      a[4] ^= b[4]; | ||||
|      a[5] ^= b[5]; | ||||
|      a[6] ^= b[6]; | ||||
|      a[7] ^= b[7]; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Init a from b | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| init (unsigned char *a, unsigned char *b) | ||||
| { | ||||
|      a[0] = b[0] << 1; | ||||
|      a[1] = b[1] << 1; | ||||
|      a[2] = b[2] << 1; | ||||
|      a[3] = b[3] << 1; | ||||
|      a[4] = b[4] << 1; | ||||
|      a[5] = b[5] << 1; | ||||
|      a[6] = b[6] << 1; | ||||
|      a[7] = b[7] << 1; | ||||
| } | ||||
|  | ||||
| void | ||||
| krb5_string_to_key (char *str, | ||||
| 		    krb5_data *salt, | ||||
| 		    krb5_keyblock *key) | ||||
| { | ||||
|      int odd, i; | ||||
|      size_t len; | ||||
|      char *s, *p; | ||||
|      des_cblock tempkey; | ||||
|      des_key_schedule sched; | ||||
|      krb5_error_code err; | ||||
|  | ||||
|      len = strlen(str) + salt->len; | ||||
| #if 1 | ||||
|      len = (len + 7) / 8 * 8; | ||||
| #endif | ||||
|      p = s = malloc (len); | ||||
|      if (p == NULL) | ||||
| 	  return ENOMEM; | ||||
|      err = krb5_data_alloc (&key->contents, sizeof(des_cblock)); | ||||
|      if (err) { | ||||
| 	  free (p); | ||||
| 	  return err; | ||||
|      } | ||||
|      memset (s, 0, len); | ||||
|      strncpy (p, str, strlen(str)); | ||||
|      p += strlen(str); | ||||
|      strncpy (p, salt->data, salt->len); | ||||
|      odd = 1; | ||||
|      memset (tempkey, 0, sizeof(tempkey)); | ||||
|      for (i = 0; i < len; i += 8) { | ||||
| 	  unsigned char tmp[8]; | ||||
|  | ||||
| 	  init (tmp, &s[i]); | ||||
|  | ||||
| 	  if (odd == 0) { | ||||
| 	       odd = 1; | ||||
| 	       reverse (tmp); | ||||
| 	       init (tmp, tmp); | ||||
| 	  } else | ||||
| 	       odd = 0; | ||||
| 	  xor (tempkey, tmp); | ||||
|      } | ||||
|      des_set_odd_parity (&tempkey); | ||||
|      des_set_key (&tempkey, sched); | ||||
|      des_cbc_cksum ((des_cblock *)s, &tempkey, len, sched, &tempkey); | ||||
|      free (s); | ||||
|      des_set_odd_parity (&tempkey); | ||||
|      if (des_is_weak_key (&tempkey)) | ||||
| 	  xor ((char *)&tempkey, "0x000x000x000x000x000x000x000xF0"); | ||||
|      memcpy (key->contents.data, &tempkey, sizeof(tempkey)); | ||||
|      return 0; | ||||
| } | ||||
							
								
								
									
										85
									
								
								send_to_kdc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								send_to_kdc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| #include "krb5_locl.h" | ||||
|  | ||||
| static int | ||||
| send_and_recv (int fd, | ||||
| 	       struct sockaddr_in *addr, | ||||
| 	       krb5_data *send, | ||||
| 	       krb5_data *recv) | ||||
| { | ||||
|      struct fdset fdset; | ||||
|      struct timeval timeout; | ||||
|      int ret; | ||||
|      long nbytes; | ||||
|  | ||||
|      if (sendto (fd, send->data, send->len, 0, | ||||
| 		 (struct sockaddr *)addr, sizeof(*addr)) < 0) | ||||
| 	  return -1; | ||||
|      FD_ZERO(&fdset); | ||||
|      FD_SET(fd, &fdset); | ||||
|      timeout.tv_sec  = 3; | ||||
|      timeout.tv_usec = 0; | ||||
|      ret = select (fd + 1, &fdset, NULL, NULL, &timeout); | ||||
|      if (ret <= 0) | ||||
| 	  return -1; | ||||
|      else { | ||||
| 	  ioctl (fd, FIONREAD, &nbytes); | ||||
|  | ||||
| 	  nbytes -= sizeof(struct udphdr) + sizeof(struct iphdr); | ||||
|  | ||||
| 	  recv->data = malloc (nbytes); | ||||
| 	  ret = recvfrom (fd, recv->data, nbytes, 0, NULL, 0); | ||||
| 	  if (ret < 0) { | ||||
| 	       free (recv->data); | ||||
| 	       return -1; | ||||
| 	  } | ||||
| 	  recv->data = realloc (recv->data, ret); | ||||
| 	  recv->len  = ret; | ||||
| 	  return 0; | ||||
|      } | ||||
| } | ||||
|  | ||||
| krb5_error_code | ||||
| krb5_sentdo_kdc (krb5_context context, | ||||
| 		 const krb5_data *send, | ||||
| 		 const krb5_data *realm, | ||||
| 		 krb5_data *receive) | ||||
| { | ||||
|      krb5_error_code err; | ||||
|      char **hostlist, **hp, *p; | ||||
|      struct hostent *hostent; | ||||
|      int fd; | ||||
|      int port; | ||||
|      int i; | ||||
|  | ||||
|      port = krb5_getportbyname ("kerberos", "udp", htons(750)); | ||||
|      fd = socket (AF_INET, SOCK_DGRAM, 0); | ||||
|      if (fd < 0) | ||||
| 	  return errno; | ||||
|  | ||||
|      err = krb5_get_krbhst (context, realm, &hostlist); | ||||
|      if (err) { | ||||
| 	  close (fd); | ||||
| 	  return err; | ||||
|      } | ||||
|      for (i = 0; i < 3; ++i) | ||||
| 	  for (hp = hostlist; p = *hp; ++hp) { | ||||
| 	       char *addr; | ||||
|  | ||||
| 	       hostent = gethostbyname (p); | ||||
| 	       while (addr = *hostent->h_addr_list++) { | ||||
| 		    struct sockaddr_in a; | ||||
| 		     | ||||
| 		    memset (a, 0, sizeof(a)); | ||||
| 		    a.sin_family = AF_INET; | ||||
| 		    a.sin_port   = port; | ||||
| 		    a.sin_addr   = *((struct in_addr *)addr); | ||||
| 		     | ||||
| 		    if (send_and_recv (fd, &a, send, recv) == 0) { | ||||
| 			 krb5_free_krbhst (context, hostlist); | ||||
| 			 return KDC_ERR_NONE; | ||||
| 		    } | ||||
| 	       } | ||||
| 	  } | ||||
|      krb5_free_krbhst (context, hostlist); | ||||
|      return KRB5_KDC_UNREACH; | ||||
| } | ||||
							
								
								
									
										141
									
								
								str2key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								str2key.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| #include <krb5_locl.h> | ||||
|  | ||||
| /* | ||||
|  * Reverse 8 bytes | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| reverse (unsigned char *s) | ||||
| { | ||||
|      static unsigned char tbl[] = { | ||||
| 	  0x0, | ||||
| 	  0x8, | ||||
| 	  0x4, | ||||
| 	  0xC, | ||||
| 	  0x2, | ||||
| 	  0xA, | ||||
| 	  0x6, | ||||
| 	  0xE, | ||||
| 	  0x1, | ||||
| 	  0x9, | ||||
| 	  0x5, | ||||
| 	  0xD, | ||||
| 	  0x3, | ||||
| 	  0xB, | ||||
| 	  0x7, | ||||
| 	  0xF | ||||
|      }; | ||||
|  | ||||
|      char tmp; | ||||
|  | ||||
| #define REVONE(str, i, j) \ | ||||
| do { tmp = str[i]; str[i] = str[j]; str[j] = tmp;} while(0) | ||||
|  | ||||
|      REVONE(s,0,7); | ||||
|      REVONE(s,1,6); | ||||
|      REVONE(s,2,5); | ||||
|      REVONE(s,3,4); | ||||
| #undef REVONE | ||||
|  | ||||
| #define REVTWO(q) \ | ||||
| q = (tbl[q & 0x0F] << 4) | (tbl[q >> 4]) | ||||
|  | ||||
|      REVTWO(s[0]); | ||||
|      REVTWO(s[1]); | ||||
|      REVTWO(s[2]); | ||||
|      REVTWO(s[3]); | ||||
|      REVTWO(s[4]); | ||||
|      REVTWO(s[5]); | ||||
|      REVTWO(s[6]); | ||||
|      REVTWO(s[7]); | ||||
|  | ||||
| #undef REVTWO | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * A = A xor B. A & B is 8 bytes. | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| xor (unsigned char *a, unsigned char *b) | ||||
| { | ||||
|      a[0] ^= b[0]; | ||||
|      a[1] ^= b[1]; | ||||
|      a[2] ^= b[2]; | ||||
|      a[3] ^= b[3]; | ||||
|      a[4] ^= b[4]; | ||||
|      a[5] ^= b[5]; | ||||
|      a[6] ^= b[6]; | ||||
|      a[7] ^= b[7]; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Init a from b | ||||
|  */ | ||||
|  | ||||
| static void | ||||
| init (unsigned char *a, unsigned char *b) | ||||
| { | ||||
|      a[0] = b[0] << 1; | ||||
|      a[1] = b[1] << 1; | ||||
|      a[2] = b[2] << 1; | ||||
|      a[3] = b[3] << 1; | ||||
|      a[4] = b[4] << 1; | ||||
|      a[5] = b[5] << 1; | ||||
|      a[6] = b[6] << 1; | ||||
|      a[7] = b[7] << 1; | ||||
| } | ||||
|  | ||||
| void | ||||
| krb5_string_to_key (char *str, | ||||
| 		    krb5_data *salt, | ||||
| 		    krb5_keyblock *key) | ||||
| { | ||||
|      int odd, i; | ||||
|      size_t len; | ||||
|      char *s, *p; | ||||
|      des_cblock tempkey; | ||||
|      des_key_schedule sched; | ||||
|      krb5_error_code err; | ||||
|  | ||||
|      len = strlen(str) + salt->len; | ||||
| #if 1 | ||||
|      len = (len + 7) / 8 * 8; | ||||
| #endif | ||||
|      p = s = malloc (len); | ||||
|      if (p == NULL) | ||||
| 	  return ENOMEM; | ||||
|      err = krb5_data_alloc (&key->contents, sizeof(des_cblock)); | ||||
|      if (err) { | ||||
| 	  free (p); | ||||
| 	  return err; | ||||
|      } | ||||
|      memset (s, 0, len); | ||||
|      strncpy (p, str, strlen(str)); | ||||
|      p += strlen(str); | ||||
|      strncpy (p, salt->data, salt->len); | ||||
|      odd = 1; | ||||
|      memset (tempkey, 0, sizeof(tempkey)); | ||||
|      for (i = 0; i < len; i += 8) { | ||||
| 	  unsigned char tmp[8]; | ||||
|  | ||||
| 	  init (tmp, &s[i]); | ||||
|  | ||||
| 	  if (odd == 0) { | ||||
| 	       odd = 1; | ||||
| 	       reverse (tmp); | ||||
| 	       init (tmp, tmp); | ||||
| 	  } else | ||||
| 	       odd = 0; | ||||
| 	  xor (tempkey, tmp); | ||||
|      } | ||||
|      des_set_odd_parity (&tempkey); | ||||
|      des_set_key (&tempkey, sched); | ||||
|      des_cbc_cksum ((des_cblock *)s, &tempkey, len, sched, &tempkey); | ||||
|      free (s); | ||||
|      des_set_odd_parity (&tempkey); | ||||
|      if (des_is_weak_key (&tempkey)) | ||||
| 	  xor ((char *)&tempkey, "0x000x000x000x000x000x000x000xF0"); | ||||
|      memcpy (key->contents.data, &tempkey, sizeof(tempkey)); | ||||
|      return 0; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Assar Westerlund
					Assar Westerlund