SHARE
TWEET

Custom Secure '64-bit' Time and Date

Phr0zen_Penguin Nov 30th, 2013 218 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*============================================================================
  2.   ----------------------------------------------------------------------------
  3.   myTimeDate.c - Custom secure '64-bit' time and date.
  4.                 (c) Damion 'Phr0z3n.Dev' Tapper, 2013.
  5.                 Email: Phr0z3n.Dev@Gmail.com
  6.  
  7.   NOTE: References made to K&R in the code are referring to the book:
  8.                 The C programming Language (Second Edition) by Kernighan, Brian W.
  9.                 and Ritchie, Dennis M.
  10.   ----------------------------------------------------------------------------
  11.   ============================================================================*/
  12.  
  13. /*
  14.  * Initialize the MinGW secure API.  Other compilers such as the one in Visual Studio
  15.  * and RAD Studio will ignore this directive.
  16.  */
  17. #define MINGW_HAS_SECURE_API    1
  18.  
  19. /*
  20.  * 1 display the output using the (Windows API) Message Box.
  21.  * 2 display the output via the console.
  22.  *
  23.  * NOTE: GCC and some other compilers may/will allow this code to be compiled at
  24.  * the command line with method 1 defined but, for Visual Studio (C++) (and other IDEs)
  25.  * you have to create a new (Win32/64) project and add this file (as source) for it to build.
  26.  */
  27. #define DATE_DISP_METHOD                1
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <time.h>
  32. #include <string.h>
  33.  
  34. #if DATE_DISP_METHOD == 1
  35.         #include <windows.h>
  36. #endif
  37.  
  38. /*=====================================--=====================================
  39.                         VARIABLE NAME DEFINITIONS
  40.   ----------------------------------------------------------------------------*/
  41. #define MY_TIME_AND_DATE_STRUCT myTimeAndDate
  42. #define MY_TIME_VALUE           myTimeValue
  43.  
  44. #define SECOND                  myTimeAndDate->second
  45. #define MINUTE                  myTimeAndDate->minute
  46. #define HOUR                    myTimeAndDate->hour
  47. #define DAY_OF_THE_MONTH        myTimeAndDate->monthDay
  48. #define MONTH                   myTimeAndDate->month
  49. #define YEAR                    myTimeAndDate->year
  50. #define WEEKDAY                 myTimeAndDate->weekDay
  51. #define DAY_OF_THE_YEAR         myTimeAndDate->yearDay
  52. #define DST_ON_OFF              myTimeAndDate->dstValue
  53.  
  54. #define DAY_NAME                dayName
  55. #define MONTH_NAME              monthName
  56.  
  57. #define ERROR_BUFFER            errorBuffer
  58. #define ERROR_BUFFER_SIZE       75
  59.  
  60. #if DATE_DISP_METHOD == 1
  61.         #define MESSAGE_BUFFER          messageBuffer
  62.         #define MESSAGE_BUFFER_SIZE     50
  63.         #define TOTAL_CHARS_WRITTEN     tcw
  64.         #define CHARS_WRITTEN           MESSAGE_BUFFER + TOTAL_CHARS_WRITTEN
  65.         #define REM_BUFFER_SIZE         MESSAGE_BUFFER_SIZE - TOTAL_CHARS_WRITTEN
  66. #endif
  67.  
  68. /*=====================================--=====================================
  69.                                 TYPE DEFINITIONS
  70.   ----------------------------------------------------------------------------*/
  71. /*
  72.  * The Microsoft Visual C++ documentation states that localtime_s is an inline
  73.  * function which evaluates to _localtime64_s, and time_t is equivalent to __time64_t.
  74.  * If you need to force the compiler to interpret time_t as the old 32-bit time_t,
  75.  * you can define _USE_32BIT_TIME_T.
  76.  *
  77.  * It further states that this is not recommended because your application may
  78.  * fail after January 19, 2038 coordinated universal time (UTC), and it is not
  79.  * allowed on 64-bit platforms, and that __time64_t allows dates to be expressed
  80.  * up through 23:59:59, December 31, 3000 (UTC).
  81.  *
  82.  * NOTE: The size of time_t remains 4 bytes, on some compilers, which is the same
  83.  * size as the 'long' type, __int32, or __time32_t, even with the '_USE_32BIT_TIME_T'
  84.  * directive undefined.  Also note that the size of the 'long long' type, __int64
  85.  * or __time64_t is 8 bytes.
  86.  *
  87.  * The Microsoft Visual C++ documentation also states that the __int64 type has no
  88.  * ANSI equivalent.  With this extra bit of info in hand, one can logically
  89.  * extrapolate that, either the definition of __int64 as different types in different
  90.  * libraries/platforms or, inappropriately defined/omitted/included code, could be blamed
  91.  * for the aforementioned anomaly, being that, __time64_t is defined as the __int64 type
  92.  * in the time.h header file, which is a part of the standard C Library.
  93.  *
  94.  * As a result, in the greatest interest of system/application security, adjustment
  95.  * will be made to the code to ensure that time_t is always (regardless of compiler/platform)
  96.  * be the same size as 'long long': 8 bytes.
  97.  */
  98. #ifdef  _USE_32BIT_TIME_T
  99.         #undef  _USE_32BIT_TIME_T
  100. #endif
  101.  
  102. /* And if time_t is still equivalent to __time32_t (__int32) */
  103. #if (time_t == __time32_t)
  104.         #undef time_t
  105.         #define time_t __time64_t /* '#define', for 'typedef' conflicts within this scope. */
  106. #endif
  107.  
  108. typedef time_t                  TT;
  109. typedef time_t*                 PTT;    /* Hungarian notation. */
  110.  
  111. typedef struct  tm              TM;             /* A bird in the hand... */
  112. typedef struct  tm*             PTM;
  113.  
  114. typedef         char            *PC;
  115. typedef const   char            *PCC;
  116.  
  117. /* Custom time structure.  time.h has 'struct tm' (with no type definitions). */
  118. typedef struct  _MTD
  119. {
  120.         int     second;         /* Seconds: 0-59 (K&R says 0-61?) */
  121.         int     minute;         /* Minutes: 0-59 */
  122.         int     hour;           /* Hours since midnight: 0-23 */
  123.         int     monthDay;       /* Day of the month: 1-31 */
  124.         int     month;          /* Months *since* January: 0-11 */
  125.         int     year;           /* Years since 1900 */
  126.         int     weekDay;        /* Days since Sunday (0-6) */
  127.         int     yearDay;        /* Days since Jan. 1: 0-365 */
  128.         int     dstValue;       /* +1 Daylight Savings Time, 0 No DST, -1 don't know */
  129. }MTD, *PMTD;            /* Other type definitions. */
  130. /*
  131.  * NOTE: Knowing the inner-workings of all the 'elements' of your code increases
  132.  * its security (and, ultimately, the security of the system it runs on)
  133.  * exponentially.  Such is the resounding motto of Open Source Software (OSS)
  134.  * and the Open Source Software community.
  135.  *
  136.  * Having your own defined time structure decreases the chances of time
  137.  * vulnerabilities exponentially, per se.  Besides, its the perfect way for
  138.  * learning for the overly inquisitive mind.
  139.  *
  140.  * NOTE TO SELF: 'I am the Architect.'
  141.  */
  142.  
  143. /*=====================================--=====================================
  144.                         FUNCTION PROTOTYPE DEFINITIONS
  145.   ----------------------------------------------------------------------------*/
  146. static void getTimeAndDate(PMTD); /* ...with limited scope (static) for optimum security. */
  147. static PCC getDayName(PMTD);
  148. static PCC getMonthName(PMTD);
  149.  
  150. /*
  151.  * PCC (const char *)?  A postman's job is to 'sort' and 'deliver' mail not to alter
  152.  * the contents of it.
  153.  */
  154. static void errorHandler(PCC, errno_t);
  155.  
  156. /*=====================================--=====================================
  157.                                 MAIN FUNCTION
  158.   ----------------------------------------------------------------------------*/
  159. #if DATE_DISP_METHOD == 1
  160. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
  161. #else
  162. int main(void)
  163. #endif
  164. {
  165.         /*
  166.          * NOTE: Only secure functions are used (where applicable), hence keeping up
  167.          * with the theme: secure time.
  168.          */
  169.  
  170.         /*
  171.          * The following declaration should be made anywhere a time or date value
  172.          * is needed...
  173.          */
  174.         PMTD    MY_TIME_AND_DATE_STRUCT;
  175.  
  176.         /*
  177.          * Relying on C to automatically change the types being operated on is definitely
  178.          * a gun to the head... a fully loaded revolver at that (or semi-automatic...), as
  179.          * the C++ (ANSI) standard denotes, hence, type-casting.
  180.          */
  181.         MY_TIME_AND_DATE_STRUCT = (PMTD)calloc(1, sizeof(MTD));
  182.  
  183.         /* ...the following call should be made accordingly. */
  184.         getTimeAndDate(MY_TIME_AND_DATE_STRUCT);
  185.  
  186.  
  187. /*----------------------------------------------------------------------------
  188.                                         TEST...
  189.   ----------------------------------------------------------------------------*/
  190. #if DATE_DISP_METHOD == 1
  191.         {
  192.                 PC              messageBuffer; /* Why pointer and not array will soon be obvious. */
  193.                 int             tcw;
  194.  
  195.                 MESSAGE_BUFFER = (PC)calloc(MESSAGE_BUFFER_SIZE, sizeof(char));
  196.  
  197.                 /* Print to the MESSAGE_BUFFER string that will be displayed by the message box. */
  198.                 TOTAL_CHARS_WRITTEN = sprintf_s(MESSAGE_BUFFER, MESSAGE_BUFFER_SIZE, "%s, ", getDayName(MY_TIME_AND_DATE_STRUCT));
  199.                 TOTAL_CHARS_WRITTEN += sprintf_s(CHARS_WRITTEN, REM_BUFFER_SIZE, "%s %.2d, ", getMonthName(MY_TIME_AND_DATE_STRUCT), DAY_OF_THE_MONTH); /* Pointer arithmetic. */
  200.                 TOTAL_CHARS_WRITTEN += sprintf_s(CHARS_WRITTEN, REM_BUFFER_SIZE, "%d", YEAR + 1900);
  201.                 TOTAL_CHARS_WRITTEN += sprintf_s(CHARS_WRITTEN, REM_BUFFER_SIZE, "\n\n\t%d:%.2d:%.2d", HOUR, MINUTE, SECOND);
  202.  
  203.                 /* Display date via a message box. */
  204.                 MessageBoxA(NULL, MESSAGE_BUFFER, "Date and Time", MB_ICONINFORMATION);
  205.                 /* Unicode (MessageBoxW) can be a pain. */
  206.  
  207.                 free(MESSAGE_BUFFER);
  208.         }
  209. #elif DATE_DISP_METHOD == 2
  210.         /* Print date to console. */
  211.         printf_s("%s, ", getDayName(MY_TIME_AND_DATE_STRUCT));
  212.         printf_s("%s %.2d, ", getMonthName(MY_TIME_AND_DATE_STRUCT), DAY_OF_THE_MONTH);
  213.         printf_s("%d", YEAR + 1900);
  214.         printf_s(" %d:%.2d:%.2d", HOUR, MINUTE, SECOND);
  215.  
  216. #endif
  217. /*----------------------------------------------------------------------------*/
  218.  
  219.         free(MY_TIME_AND_DATE_STRUCT);
  220.  
  221.         return 0;
  222. }
  223.  
  224. /*=====================================--=====================================
  225.                         GET TIME AND DATE FUNCTION
  226.   ----------------------------------------------------------------------------*/
  227. static void getTimeAndDate(PMTD MY_TIME_AND_DATE_STRUCT)
  228. {
  229.         PTT             MY_TIME_VALUE;
  230.  
  231.         MY_TIME_VALUE = (PTT)calloc(1, sizeof(TT));
  232.  
  233.                 if(_time64(MY_TIME_VALUE) == -1)
  234.                 {
  235.                         errorHandler(">> Error getting time value <<", errno);
  236.                 }
  237.  
  238.                 /*
  239.                  * _localtime64_s will ALWAYS be defined in the msvcr*.dll libraries on Windows
  240.                  * so consider this call 'probable cause'.
  241.                  *
  242.                  * WARNING: Do not use localtime_s with a grain of salt as some compilers will
  243.                  * resort to calling _localtime32_s even with _USE_32BIT_TIME_T undefined.
  244.                  */
  245.                 if(_localtime64_s((PTM)MY_TIME_AND_DATE_STRUCT, MY_TIME_VALUE))
  246.                 {
  247.                         errorHandler(">> Error converting the time value <<", errno);
  248.                 }
  249.  
  250.         free(MY_TIME_VALUE);
  251.         /*
  252.          * NOTE: Freeing this variable here is symbolically linked to the security
  253.          * of your code being that the function is finished with it, so there is no
  254.          * need (or, it would be absolutely unwise) to keep something as critical
  255.          * to the security of your system as time values in memory.
  256.          */
  257. }
  258.  
  259. /*=====================================--=====================================
  260.                         PRINT DAY NAME FUNCTION (Optional)
  261.   ----------------------------------------------------------------------------*/
  262. static PCC getDayName(PMTD MY_TIME_AND_DATE_STRUCT)
  263. {
  264. /* Calls to asctime (?!!!) or asctime_s could handle this formatting, but with
  265.  * abbreviated day/month names.  Also be reminded that function calls can be
  266.  * intercepted (in memory) upon execution. Then there is the 'obvious' standard
  267.  * library definitions.
  268.  */
  269.  
  270.         switch(WEEKDAY)
  271.         {
  272.                 case 0:
  273.                         return "Sunday"; /* Eliminating the need for extra variable declarations: security. */
  274.                 case 1:
  275.                         return "Monday";
  276.                 case 2:
  277.                         return "Tuesday";
  278.                 case 3:
  279.                         return "Wednesday";
  280.                 case 4:
  281.                         return "Thursday";
  282.                 case 5:
  283.                         return "Friday";
  284.                 case 6:
  285.                         return "Saturday";
  286.                 default:
  287.                         /*
  288.                          * Almost impossible... without 'divine intervention', but the Visual
  289.                          * C++ compiler complains like a mother without it.
  290.                          */
  291.                         return "Invalid day number.";
  292.                 }
  293. }
  294.  
  295. /*=====================================--=====================================
  296.                         PRINT MONTH NAME FUNCTION (Optional)
  297.   ----------------------------------------------------------------------------*/
  298. static PCC getMonthName(PMTD MY_TIME_AND_DATE_STRUCT)
  299. {
  300.         switch(MONTH)
  301.         {
  302.                 case 0:
  303.                         return "January";
  304.                 case 1:
  305.                         return "February";
  306.                 case 2:
  307.                         return "March";
  308.                 case 3:
  309.                         return "April";
  310.                 case 4:
  311.                         return "May";
  312.                 case 5:
  313.                         return "June";
  314.                 case 6:
  315.                         return "July";
  316.                 case 7:
  317.                         return "August";
  318.                 case 8:
  319.                         return "September";
  320.                 case 9:
  321.                         return "October";
  322.                 case 10:
  323.                         return "November";
  324.                 case 11:
  325.                         return "December";
  326.                 default:
  327.                         return "Invalid day number.";
  328.         }
  329. }
  330.  
  331. /*=====================================--=====================================
  332.                                 ERROR HANDLER FUNCTION
  333.   ----------------------------------------------------------------------------*/
  334. static void errorHandler(PCC myErrMsg, errno_t timeErrNo)
  335. {
  336.         char    *errorBuffer;
  337.  
  338.         ERROR_BUFFER = (PC)calloc(1, ERROR_BUFFER_SIZE);
  339.  
  340.                 if(strerror_s(ERROR_BUFFER, ERROR_BUFFER_SIZE, timeErrNo))
  341.                 {
  342.                         printf_s("%s", myErrMsg);
  343.                         printf_s("\n   Error message #: %d", timeErrNo);
  344.  
  345.                         printf_s("\n\n>> Error generating error message <<");
  346.                         printf_s("\n   Error message #: %d", errno);
  347.                 }
  348.                 else
  349.                 {
  350.                         printf_s("%s", myErrMsg);
  351.                         printf_s("\n   %s.", ERROR_BUFFER);
  352.                 }
  353.  
  354.         free(ERROR_BUFFER);
  355.         exit(EXIT_FAILURE);
  356. }
RAW Paste Data
Pastebin PRO Summer Special!
Get 40% OFF on Pastebin PRO accounts!
Top