17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * lib/kadm/str_conv.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1995, 1999 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate */
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate * str_conv.c - Convert between strings and Kerberos internal data.
367c478bd9Sstevel@tonic-gate */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate * Table of contents:
407c478bd9Sstevel@tonic-gate *
417c478bd9Sstevel@tonic-gate * String decoding:
427c478bd9Sstevel@tonic-gate * ----------------
437c478bd9Sstevel@tonic-gate * krb5_string_to_salttype() - Convert string to salttype (krb5_int32)
447c478bd9Sstevel@tonic-gate * krb5_string_to_timestamp() - Convert string to krb5_timestamp.
457c478bd9Sstevel@tonic-gate * krb5_string_to_deltat() - Convert string to krb5_deltat.
467c478bd9Sstevel@tonic-gate *
477c478bd9Sstevel@tonic-gate * String encoding:
487c478bd9Sstevel@tonic-gate * ----------------
497c478bd9Sstevel@tonic-gate * krb5_salttype_to_string() - Convert salttype (krb5_int32) to string.
507c478bd9Sstevel@tonic-gate * krb5_timestamp_to_string() - Convert krb5_timestamp to string.
517c478bd9Sstevel@tonic-gate * krb5_timestamp_to_sfstring() - Convert krb5_timestamp to short filled string
527c478bd9Sstevel@tonic-gate * krb5_deltat_to_string() - Convert krb5_deltat to string.
537c478bd9Sstevel@tonic-gate */
547c478bd9Sstevel@tonic-gate
55505d05c7Sgtb #include "k5-int.h"
56505d05c7Sgtb #include <ctype.h>
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate /* Salt type conversions */
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate /*
617c478bd9Sstevel@tonic-gate * Local data structures.
627c478bd9Sstevel@tonic-gate */
637c478bd9Sstevel@tonic-gate struct salttype_lookup_entry {
647c478bd9Sstevel@tonic-gate krb5_int32 stt_enctype; /* Salt type */
657c478bd9Sstevel@tonic-gate const char * stt_specifier; /* How to recognize it */
667c478bd9Sstevel@tonic-gate const char * stt_output; /* How to spit it out */
677c478bd9Sstevel@tonic-gate };
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate * Lookup tables.
717c478bd9Sstevel@tonic-gate */
72*159d09a2SMark Phalan
73*159d09a2SMark Phalan #include "kdb.h"
747c478bd9Sstevel@tonic-gate static const struct salttype_lookup_entry salttype_table[] = {
757c478bd9Sstevel@tonic-gate /* salt type input specifier output string */
767c478bd9Sstevel@tonic-gate /*----------------------------- --------------- ---------------*/
777c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NORMAL, "normal", "Version 5" },
787c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_V4, "v4", "Version 4" },
797c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_NOREALM, "norealm", "Version 5 - No Realm" },
807c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_ONLYREALM, "onlyrealm", "Version 5 - Realm Only" },
817c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_SPECIAL, "special", "Special" },
827c478bd9Sstevel@tonic-gate { KRB5_KDB_SALTTYPE_AFS3, "afs3", "AFS version 3" }
837c478bd9Sstevel@tonic-gate };
847c478bd9Sstevel@tonic-gate static const int salttype_table_nents = sizeof(salttype_table)/
857c478bd9Sstevel@tonic-gate sizeof(salttype_table[0]);
867c478bd9Sstevel@tonic-gate
87505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_string_to_salttype(char * string,krb5_int32 * salttypep)88505d05c7Sgtb krb5_string_to_salttype(char *string, krb5_int32 *salttypep)
897c478bd9Sstevel@tonic-gate {
907c478bd9Sstevel@tonic-gate int i;
917c478bd9Sstevel@tonic-gate int found;
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate found = 0;
947c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) {
957c478bd9Sstevel@tonic-gate if (!strcasecmp(string, salttype_table[i].stt_specifier)) {
967c478bd9Sstevel@tonic-gate found = 1;
977c478bd9Sstevel@tonic-gate *salttypep = salttype_table[i].stt_enctype;
987c478bd9Sstevel@tonic-gate break;
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate return((found) ? 0 : EINVAL);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate * Internal datatype to string routines.
1067c478bd9Sstevel@tonic-gate *
1077c478bd9Sstevel@tonic-gate * These routines return 0 for success, EINVAL for invalid parameter, ENOMEM
1087c478bd9Sstevel@tonic-gate * if the supplied buffer/length will not contain the output.
1097c478bd9Sstevel@tonic-gate */
110505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_salttype_to_string(krb5_int32 salttype,char * buffer,size_t buflen)111505d05c7Sgtb krb5_salttype_to_string(krb5_int32 salttype, char *buffer, size_t buflen)
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate int i;
1147c478bd9Sstevel@tonic-gate const char *out;
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate out = (char *) NULL;
1177c478bd9Sstevel@tonic-gate for (i=0; i<salttype_table_nents; i++) {
1187c478bd9Sstevel@tonic-gate if (salttype == salttype_table[i].stt_enctype) {
1197c478bd9Sstevel@tonic-gate out = salttype_table[i].stt_output;
1207c478bd9Sstevel@tonic-gate break;
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate if (out) {
1247c478bd9Sstevel@tonic-gate if (buflen > strlen(out))
1257c478bd9Sstevel@tonic-gate strcpy(buffer, out);
1267c478bd9Sstevel@tonic-gate else
1277c478bd9Sstevel@tonic-gate out = (char *) NULL;
1287c478bd9Sstevel@tonic-gate return((out) ? 0 : ENOMEM);
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate else
1317c478bd9Sstevel@tonic-gate return(EINVAL);
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate /* (absolute) time conversions */
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate #ifndef HAVE_STRFTIME
1377c478bd9Sstevel@tonic-gate #undef strftime
1387c478bd9Sstevel@tonic-gate #define strftime my_strftime
1397c478bd9Sstevel@tonic-gate static size_t strftime (char *, size_t, const char *, const struct tm *);
1407c478bd9Sstevel@tonic-gate #endif
1417c478bd9Sstevel@tonic-gate
142505d05c7Sgtb #ifdef HAVE_STRPTIME
143505d05c7Sgtb #ifdef NEED_STRPTIME_PROTO
144505d05c7Sgtb extern char *strptime (const char *, const char *,
145505d05c7Sgtb struct tm *)
146505d05c7Sgtb #ifdef __cplusplus
147505d05c7Sgtb throw()
148505d05c7Sgtb #endif
149505d05c7Sgtb ;
150505d05c7Sgtb #endif
151505d05c7Sgtb #else /* HAVE_STRPTIME */
1527c478bd9Sstevel@tonic-gate #undef strptime
1537c478bd9Sstevel@tonic-gate #define strptime my_strptime
1547c478bd9Sstevel@tonic-gate static char *strptime (const char *, const char *, struct tm *);
1557c478bd9Sstevel@tonic-gate #endif
1567c478bd9Sstevel@tonic-gate
157505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_string_to_timestamp(char * string,krb5_timestamp * timestampp)158505d05c7Sgtb krb5_string_to_timestamp(char *string, krb5_timestamp *timestampp)
1597c478bd9Sstevel@tonic-gate {
160505d05c7Sgtb int i;
161505d05c7Sgtb struct tm timebuf;
162505d05c7Sgtb time_t now, ret_time;
1637c478bd9Sstevel@tonic-gate char *s;
1647c478bd9Sstevel@tonic-gate static const char * const atime_format_table[] = {
165*159d09a2SMark Phalan "%Y%m%d%H%M%S", /* yyyymmddhhmmss */
1667c478bd9Sstevel@tonic-gate "%Y.%m.%d.%H.%M.%S", /* yyyy.mm.dd.hh.mm.ss */
167*159d09a2SMark Phalan "%y%m%d%H%M%S", /* yymmddhhmmss */
1687c478bd9Sstevel@tonic-gate "%y.%m.%d.%H.%M.%S", /* yy.mm.dd.hh.mm.ss */
169*159d09a2SMark Phalan "%y%m%d%H%M", /* yymmddhhmm */
170*159d09a2SMark Phalan "%H%M%S", /* hhmmss */
171*159d09a2SMark Phalan "%H%M", /* hhmm */
1727c478bd9Sstevel@tonic-gate "%T", /* hh:mm:ss */
1737c478bd9Sstevel@tonic-gate "%R", /* hh:mm */
1747c478bd9Sstevel@tonic-gate /* The following not really supported unless native strptime present */
1757c478bd9Sstevel@tonic-gate "%x:%X", /* locale-dependent short format */
1767c478bd9Sstevel@tonic-gate "%d-%b-%Y:%T", /* dd-month-yyyy:hh:mm:ss */
1777c478bd9Sstevel@tonic-gate "%d-%b-%Y:%R" /* dd-month-yyyy:hh:mm */
1787c478bd9Sstevel@tonic-gate };
1797c478bd9Sstevel@tonic-gate static const int atime_format_table_nents =
1807c478bd9Sstevel@tonic-gate sizeof(atime_format_table)/sizeof(atime_format_table[0]);
1817c478bd9Sstevel@tonic-gate
182505d05c7Sgtb
183505d05c7Sgtb now = time((time_t *) NULL);
1847c478bd9Sstevel@tonic-gate for (i=0; i<atime_format_table_nents; i++) {
185505d05c7Sgtb /* We reset every time throughout the loop as the manual page
186505d05c7Sgtb * indicated that no guarantees are made as to preserving timebuf
187505d05c7Sgtb * when parsing fails
188505d05c7Sgtb */
189505d05c7Sgtb #ifdef HAVE_LOCALTIME_R
190505d05c7Sgtb (void) localtime_r(&now, &timebuf);
191505d05c7Sgtb #else
192505d05c7Sgtb memcpy(&timebuf, localtime(&now), sizeof(timebuf));
193505d05c7Sgtb #endif
19454925bf6Swillf /*LINTED*/
195505d05c7Sgtb if ((s = strptime(string, atime_format_table[i], &timebuf))
196505d05c7Sgtb && (s != string)) {
197505d05c7Sgtb /* See if at end of buffer - otherwise partial processing */
198505d05c7Sgtb while(*s != 0 && isspace((int) *s)) s++;
199505d05c7Sgtb if (*s != 0)
200505d05c7Sgtb continue;
201505d05c7Sgtb if (timebuf.tm_year <= 0)
202505d05c7Sgtb continue; /* clearly confused */
203505d05c7Sgtb ret_time = mktime(&timebuf);
204505d05c7Sgtb if (ret_time == (time_t) -1)
205505d05c7Sgtb continue; /* clearly confused */
206505d05c7Sgtb *timestampp = (krb5_timestamp) ret_time;
207505d05c7Sgtb return 0;
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate }
210505d05c7Sgtb return(EINVAL);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
213505d05c7Sgtb krb5_error_code KRB5_CALLCONV
krb5_timestamp_to_string(krb5_timestamp timestamp,char * buffer,size_t buflen)214505d05c7Sgtb krb5_timestamp_to_string(krb5_timestamp timestamp, char *buffer, size_t buflen)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate int ret;
2177c478bd9Sstevel@tonic-gate time_t timestamp2 = timestamp;
218505d05c7Sgtb struct tm tmbuf;
219505d05c7Sgtb const char *fmt = "%c"; /* This is to get around gcc -Wall warning that
220505d05c7Sgtb the year returned might be two digits */
2217c478bd9Sstevel@tonic-gate
222505d05c7Sgtb #ifdef HAVE_LOCALTIME_R
223505d05c7Sgtb (void) localtime_r(×tamp2, &tmbuf);
224505d05c7Sgtb #else
225