Advertisement
Phr0zen_Penguin

Custom Secure '64-bit' Time and Date

Nov 30th, 2013
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.32 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement