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