xref: /freebsd/crypto/krb5/src/windows/leashdll/timesync.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* timesync stuff for leash - 7/28/94 - evanr */
2*7f2fe78bSCy Schubert 
3*7f2fe78bSCy Schubert #include <windows.h>
4*7f2fe78bSCy Schubert #include "leashdll.h"
5*7f2fe78bSCy Schubert 
6*7f2fe78bSCy Schubert #include <time.h>
7*7f2fe78bSCy Schubert #include <sys\timeb.h>
8*7f2fe78bSCy Schubert #include <stdlib.h>
9*7f2fe78bSCy Schubert #include <string.h>
10*7f2fe78bSCy Schubert 
11*7f2fe78bSCy Schubert #include <winsock2.h>
12*7f2fe78bSCy Schubert 
13*7f2fe78bSCy Schubert #include <stdio.h>
14*7f2fe78bSCy Schubert #include "leasherr.h"
15*7f2fe78bSCy Schubert #include "leashids.h"
16*7f2fe78bSCy Schubert 
17*7f2fe78bSCy Schubert int ProcessTimeSync(char *, int, char *);
18*7f2fe78bSCy Schubert 
19*7f2fe78bSCy Schubert #define TM_OFFSET 2208988800
20*7f2fe78bSCy Schubert 
21*7f2fe78bSCy Schubert /* timezone.h has a winsock.h conflict */
22*7f2fe78bSCy Schubert struct timezone {
23*7f2fe78bSCy Schubert     int     tz_minuteswest;
24*7f2fe78bSCy Schubert     int     tz_dsttime;
25*7f2fe78bSCy Schubert };
26*7f2fe78bSCy Schubert 
27*7f2fe78bSCy Schubert /************************************/
28*7f2fe78bSCy Schubert /* settimeofday():                  */
29*7f2fe78bSCy Schubert /************************************/
30*7f2fe78bSCy Schubert int
settimeofday(struct timeval * tv,struct timezone * tz)31*7f2fe78bSCy Schubert settimeofday(
32*7f2fe78bSCy Schubert     struct timeval *tv,
33*7f2fe78bSCy Schubert     struct timezone *tz
34*7f2fe78bSCy Schubert     )
35*7f2fe78bSCy Schubert {
36*7f2fe78bSCy Schubert     SYSTEMTIME systime;
37*7f2fe78bSCy Schubert     struct tm *newtime;
38*7f2fe78bSCy Schubert 
39*7f2fe78bSCy Schubert     newtime = gmtime((time_t *)&(tv->tv_sec));
40*7f2fe78bSCy Schubert     systime.wYear = 1900+newtime->tm_year;
41*7f2fe78bSCy Schubert     systime.wMonth = 1+newtime->tm_mon;
42*7f2fe78bSCy Schubert     systime.wDay = newtime->tm_mday;
43*7f2fe78bSCy Schubert     systime.wHour = newtime->tm_hour;
44*7f2fe78bSCy Schubert     systime.wMinute = newtime->tm_min;
45*7f2fe78bSCy Schubert     systime.wSecond = newtime->tm_sec;
46*7f2fe78bSCy Schubert     systime.wMilliseconds = 0;
47*7f2fe78bSCy Schubert     return SetSystemTime(&systime);
48*7f2fe78bSCy Schubert }
49*7f2fe78bSCy Schubert 
50*7f2fe78bSCy Schubert /************************************/
51*7f2fe78bSCy Schubert /* gettimeofday():                  */
52*7f2fe78bSCy Schubert /************************************/
53*7f2fe78bSCy Schubert int
gettimeofday(struct timeval * tv,struct timezone * tz)54*7f2fe78bSCy Schubert gettimeofday(
55*7f2fe78bSCy Schubert     struct timeval *tv,
56*7f2fe78bSCy Schubert     struct timezone *tz
57*7f2fe78bSCy Schubert     )
58*7f2fe78bSCy Schubert {
59*7f2fe78bSCy Schubert     struct _timeb tb;
60*7f2fe78bSCy Schubert     _tzset();
61*7f2fe78bSCy Schubert     _ftime(&tb);
62*7f2fe78bSCy Schubert     if (tv) {
63*7f2fe78bSCy Schubert 	tv->tv_sec = tb.time;
64*7f2fe78bSCy Schubert 	tv->tv_usec = tb.millitm * 1000;
65*7f2fe78bSCy Schubert     }
66*7f2fe78bSCy Schubert     if (tz) {
67*7f2fe78bSCy Schubert 	tz->tz_minuteswest = tb.timezone;
68*7f2fe78bSCy Schubert 	tz->tz_dsttime = tb.dstflag;
69*7f2fe78bSCy Schubert     }
70*7f2fe78bSCy Schubert     return 0;
71*7f2fe78bSCy Schubert }
72*7f2fe78bSCy Schubert 
73*7f2fe78bSCy Schubert 
74*7f2fe78bSCy Schubert LONG
get_time_server_name(char * timeServerName,const char * valueName)75*7f2fe78bSCy Schubert get_time_server_name(
76*7f2fe78bSCy Schubert     char *timeServerName,
77*7f2fe78bSCy Schubert     const char *valueName
78*7f2fe78bSCy Schubert     )
79*7f2fe78bSCy Schubert {
80*7f2fe78bSCy Schubert     HMODULE     hmLeash;
81*7f2fe78bSCy Schubert     char        hostname[128];
82*7f2fe78bSCy Schubert     char        value[80];
83*7f2fe78bSCy Schubert     DWORD       dwType;
84*7f2fe78bSCy Schubert     DWORD       dwCount;
85*7f2fe78bSCy Schubert     int         check = 0;
86*7f2fe78bSCy Schubert     HKEY    	hKey;
87*7f2fe78bSCy Schubert     HKEY        rKey1;
88*7f2fe78bSCy Schubert     HKEY        rKey2;
89*7f2fe78bSCy Schubert     LONG        lResult;
90*7f2fe78bSCy Schubert     BOOL 	bEnv;
91*7f2fe78bSCy Schubert 
92*7f2fe78bSCy Schubert     memset(value, '\0', sizeof(value));
93*7f2fe78bSCy Schubert     memset(hostname, '\0', sizeof(hostname));
94*7f2fe78bSCy Schubert 
95*7f2fe78bSCy Schubert     GetEnvironmentVariable("TIMEHOST", hostname, sizeof(hostname));
96*7f2fe78bSCy Schubert     bEnv = (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
97*7f2fe78bSCy Schubert 
98*7f2fe78bSCy Schubert     if (!(bEnv && hostname[0]))
99*7f2fe78bSCy Schubert     {
100*7f2fe78bSCy Schubert         // Check registry for TIMEHOST
101*7f2fe78bSCy Schubert         rKey1 = HKEY_CURRENT_USER;
102*7f2fe78bSCy Schubert         rKey2 = HKEY_LOCAL_MACHINE;
103*7f2fe78bSCy Schubert 
104*7f2fe78bSCy Schubert         for (check = 0; check < 2; check++)
105*7f2fe78bSCy Schubert         {
106*7f2fe78bSCy Schubert             if (ERROR_SUCCESS == RegOpenKeyEx(check == 0 ? rKey1 : rKey2,
107*7f2fe78bSCy Schubert                                               "Software\\MIT\\Leash32\\Settings",
108*7f2fe78bSCy Schubert                                               0, KEY_QUERY_VALUE, &hKey))
109*7f2fe78bSCy Schubert             {
110*7f2fe78bSCy Schubert                 memset(value, '\0', sizeof(value));
111*7f2fe78bSCy Schubert                 lResult = RegQueryValueEx(hKey, (LPTSTR)valueName, NULL,
112*7f2fe78bSCy Schubert                                           &dwType, NULL, &dwCount);
113*7f2fe78bSCy Schubert                 if (lResult == ERROR_SUCCESS)
114*7f2fe78bSCy Schubert                 {
115*7f2fe78bSCy Schubert                     lResult = RegQueryValueEx(hKey, (LPTSTR)valueName,
116*7f2fe78bSCy Schubert                                               NULL, &dwType,
117*7f2fe78bSCy Schubert                                               (LPTSTR)value, &dwCount);
118*7f2fe78bSCy Schubert                     if (lResult == ERROR_SUCCESS && *value)
119*7f2fe78bSCy Schubert                     {
120*7f2fe78bSCy Schubert                         // found
121*7f2fe78bSCy Schubert                         strcpy(hostname, value);
122*7f2fe78bSCy Schubert                         break;
123*7f2fe78bSCy Schubert                     }
124*7f2fe78bSCy Schubert                 }
125*7f2fe78bSCy Schubert             }
126*7f2fe78bSCy Schubert         }
127*7f2fe78bSCy Schubert 
128*7f2fe78bSCy Schubert         if (!*hostname)
129*7f2fe78bSCy Schubert         {
130*7f2fe78bSCy Schubert             // Check resource string for TIMEHOST
131*7f2fe78bSCy Schubert             if ((hmLeash = GetModuleHandle(LEASH_DLL)) != NULL)
132*7f2fe78bSCy Schubert             {
133*7f2fe78bSCy Schubert                 if (!LoadString(hmLeash, LSH_TIME_HOST, hostname,
134*7f2fe78bSCy Schubert                                 sizeof(hostname)))
135*7f2fe78bSCy Schubert                     memset(hostname, '\0', sizeof(hostname));
136*7f2fe78bSCy Schubert             }
137*7f2fe78bSCy Schubert         }
138*7f2fe78bSCy Schubert         if (!*hostname)
139*7f2fe78bSCy Schubert         {
140*7f2fe78bSCy Schubert             // OK, _Default_ it will be! :)
141*7f2fe78bSCy Schubert             strcpy(hostname, "time");
142*7f2fe78bSCy Schubert         }
143*7f2fe78bSCy Schubert     }
144*7f2fe78bSCy Schubert     strcpy(timeServerName, hostname);
145*7f2fe78bSCy Schubert     return 0;
146*7f2fe78bSCy Schubert }
147*7f2fe78bSCy Schubert 
148*7f2fe78bSCy Schubert /************************************/
149*7f2fe78bSCy Schubert /* Leash_timesync():                */
150*7f2fe78bSCy Schubert /************************************/
Leash_timesync(int MessageP)151*7f2fe78bSCy Schubert LONG Leash_timesync(int MessageP)
152*7f2fe78bSCy Schubert {
153*7f2fe78bSCy Schubert     char                tmpstr[2048];
154*7f2fe78bSCy Schubert     char                hostname[128];
155*7f2fe78bSCy Schubert     int                 Port;
156*7f2fe78bSCy Schubert     int                 rc;
157*7f2fe78bSCy Schubert     struct servent      *sp;
158*7f2fe78bSCy Schubert     WORD                wVersionRequested;
159*7f2fe78bSCy Schubert     WSADATA             wsaData;
160*7f2fe78bSCy Schubert     char                name[80];
161*7f2fe78bSCy Schubert 
162*7f2fe78bSCy Schubert     if (pkrb5_init_context == NULL)
163*7f2fe78bSCy Schubert         return(0);
164*7f2fe78bSCy Schubert 
165*7f2fe78bSCy Schubert     wVersionRequested = 0x0101;
166*7f2fe78bSCy Schubert     memset(name, '\0', sizeof(name));
167*7f2fe78bSCy Schubert     memset(hostname, '\0', sizeof(hostname));
168*7f2fe78bSCy Schubert     memset(tmpstr, '\0', sizeof(tmpstr));
169*7f2fe78bSCy Schubert 
170*7f2fe78bSCy Schubert     if ((rc = WSAStartup(wVersionRequested, &wsaData)))
171*7f2fe78bSCy Schubert     {
172*7f2fe78bSCy Schubert         wsprintf(tmpstr, "Couldn't initialize WinSock to synchronize time\n\rError Number: %d", rc);
173*7f2fe78bSCy Schubert         WSACleanup();
174*7f2fe78bSCy Schubert         return(LSH_BADWINSOCK);
175*7f2fe78bSCy Schubert     }
176*7f2fe78bSCy Schubert 
177*7f2fe78bSCy Schubert     sp = getservbyname("time", "udp");
178*7f2fe78bSCy Schubert     if (sp == 0)
179*7f2fe78bSCy Schubert         Port = htons(IPPORT_TIMESERVER);
180*7f2fe78bSCy Schubert     else
181*7f2fe78bSCy Schubert         Port = sp->s_port;
182*7f2fe78bSCy Schubert 
183*7f2fe78bSCy Schubert     get_time_server_name(hostname, TIMEHOST);
184*7f2fe78bSCy Schubert 
185*7f2fe78bSCy Schubert     rc = ProcessTimeSync(hostname, Port, tmpstr);
186*7f2fe78bSCy Schubert 
187*7f2fe78bSCy Schubert #ifdef USE_MESSAGE_BOX
188*7f2fe78bSCy Schubert     if(MessageP != 0)
189*7f2fe78bSCy Schubert     {
190*7f2fe78bSCy Schubert         if (rc && !*tmpstr)
191*7f2fe78bSCy Schubert         {
192*7f2fe78bSCy Schubert             strcpy(tmpstr, "Unable to synchronize time!\n\n");
193*7f2fe78bSCy Schubert             if (*hostname)
194*7f2fe78bSCy Schubert             {
195*7f2fe78bSCy Schubert                 char                tmpstr1[2048];
196*7f2fe78bSCy Schubert 
197*7f2fe78bSCy Schubert                 memset(tmpstr1, '\0', sizeof(tmpstr1));
198*7f2fe78bSCy Schubert                 sprintf(tmpstr1, "Unreachable server: %s\n", hostname);
199*7f2fe78bSCy Schubert                 strcat(tmpstr, tmpstr1);
200*7f2fe78bSCy Schubert             }
201*7f2fe78bSCy Schubert         }
202*7f2fe78bSCy Schubert 
203*7f2fe78bSCy Schubert 	MessageBox(NULL, tmpstr, "Time Server",
204*7f2fe78bSCy Schubert                    MB_ICONERROR | MB_OK);
205*7f2fe78bSCy Schubert     }
206*7f2fe78bSCy Schubert #endif /* USE_MESSAGE_BOX */
207*7f2fe78bSCy Schubert     WSACleanup();
208*7f2fe78bSCy Schubert     return(rc);
209*7f2fe78bSCy Schubert }
210*7f2fe78bSCy Schubert 
211*7f2fe78bSCy Schubert 
212*7f2fe78bSCy Schubert /************************************/
213*7f2fe78bSCy Schubert /* ProcessTimeSync():               */
214*7f2fe78bSCy Schubert /************************************/
ProcessTimeSync(char * hostname,int Port,char * tmpstr)215*7f2fe78bSCy Schubert int ProcessTimeSync(char *hostname, int Port, char *tmpstr)
216*7f2fe78bSCy Schubert {
217*7f2fe78bSCy Schubert     char                buffer[512];
218*7f2fe78bSCy Schubert     int                 cc;
219*7f2fe78bSCy Schubert     long                *nettime;
220*7f2fe78bSCy Schubert     int                 s;
221*7f2fe78bSCy Schubert     long                hosttime;
222*7f2fe78bSCy Schubert     struct hostent      *host;
223*7f2fe78bSCy Schubert     struct              timeval tv;
224*7f2fe78bSCy Schubert     struct              timezone tz;
225*7f2fe78bSCy Schubert     u_long              argp;
226*7f2fe78bSCy Schubert     struct sockaddr_in  sin;
227*7f2fe78bSCy Schubert     int                 i;
228*7f2fe78bSCy Schubert 
229*7f2fe78bSCy Schubert     if ((host = gethostbyname(hostname)) == NULL)
230*7f2fe78bSCy Schubert         return(LSH_BADTIMESERV);
231*7f2fe78bSCy Schubert 
232*7f2fe78bSCy Schubert     sin.sin_port = (short)Port;
233*7f2fe78bSCy Schubert     sin.sin_family = host->h_addrtype;
234*7f2fe78bSCy Schubert     memcpy((struct sockaddr *)&sin.sin_addr, host->h_addr, host->h_length);
235*7f2fe78bSCy Schubert     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
236*7f2fe78bSCy Schubert     {
237*7f2fe78bSCy Schubert         return(LSH_NOSOCKET);
238*7f2fe78bSCy Schubert     }
239*7f2fe78bSCy Schubert 
240*7f2fe78bSCy Schubert     argp = 1;
241*7f2fe78bSCy Schubert     if (ioctlsocket(s, FIONBIO, &argp) != 0)
242*7f2fe78bSCy Schubert     {
243*7f2fe78bSCy Schubert         closesocket(s);
244*7f2fe78bSCy Schubert         return(LSH_NOCONNECT);
245*7f2fe78bSCy Schubert     }
246*7f2fe78bSCy Schubert 
247*7f2fe78bSCy Schubert     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
248*7f2fe78bSCy Schubert     {
249*7f2fe78bSCy Schubert         closesocket(s);
250*7f2fe78bSCy Schubert         return(LSH_NOCONNECT);
251*7f2fe78bSCy Schubert     }
252*7f2fe78bSCy Schubert     send(s, buffer, 40, 0);
253*7f2fe78bSCy Schubert     if (gettimeofday (&tv, &tz) < 0)
254*7f2fe78bSCy Schubert     {
255*7f2fe78bSCy Schubert         closesocket(s);
256*7f2fe78bSCy Schubert         return(LSH_GETTIMEOFDAY);
257*7f2fe78bSCy Schubert     }
258*7f2fe78bSCy Schubert 
259*7f2fe78bSCy Schubert     for (i = 0; i < 4; i++)
260*7f2fe78bSCy Schubert     {
261*7f2fe78bSCy Schubert         if ((cc = recv(s, buffer, 512, 0)) > 0)
262*7f2fe78bSCy Schubert             break;
263*7f2fe78bSCy Schubert         Sleep(500);
264*7f2fe78bSCy Schubert     }
265*7f2fe78bSCy Schubert     if (i == 4)
266*7f2fe78bSCy Schubert     {
267*7f2fe78bSCy Schubert         closesocket(s);
268*7f2fe78bSCy Schubert         return(LSH_RECVTIME);
269*7f2fe78bSCy Schubert     }
270*7f2fe78bSCy Schubert 
271*7f2fe78bSCy Schubert     if (cc != 4)
272*7f2fe78bSCy Schubert     {
273*7f2fe78bSCy Schubert         closesocket(s);
274*7f2fe78bSCy Schubert         return(LSH_RECVBYTES);
275*7f2fe78bSCy Schubert     }
276*7f2fe78bSCy Schubert 
277*7f2fe78bSCy Schubert     nettime = (long *)buffer;
278*7f2fe78bSCy Schubert     hosttime = (long) ntohl (*nettime) - TM_OFFSET;
279*7f2fe78bSCy Schubert     (&tv)->tv_sec = hosttime;
280*7f2fe78bSCy Schubert     if (settimeofday(&tv, &tz) < 0)
281*7f2fe78bSCy Schubert     {
282*7f2fe78bSCy Schubert         closesocket(s);
283*7f2fe78bSCy Schubert         return(LSH_SETTIMEOFDAY);
284*7f2fe78bSCy Schubert     }
285*7f2fe78bSCy Schubert 
286*7f2fe78bSCy Schubert     sprintf(tmpstr, "The time has been synchronized with the server:   %s\n\n", hostname);
287*7f2fe78bSCy Schubert     strcat(tmpstr, "To be able to use the Kerberos server, it was necessary to \nset the system time to:  ") ;
288*7f2fe78bSCy Schubert     strcat(tmpstr, ctime((time_t *)&hosttime));
289*7f2fe78bSCy Schubert     strcat(tmpstr, "\n");
290*7f2fe78bSCy Schubert     closesocket(s);
291*7f2fe78bSCy Schubert     return(0);
292*7f2fe78bSCy Schubert }
293