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