blob: 2a128c86f30f43bcbd9a17a0ca6461d9df0cff8a [file] [log] [blame]
Alistair Delvabeaee832021-02-24 11:27:23 -08001/* Copyright 1999 Peter Schlaile.
2 * Copyright 1999-2002,2006,2007,2009 Alain Knaff.
3 * This file is part of mtools.
4 *
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Small install-test utility to check if a floppyd-server is running on the
19 * X-Server-Host.
20 *
21 * written by:
22 *
23 * Peter Schlaile
24 *
25 * udbz@rz.uni-karlsruhe.de
26 *
27 */
28
29#include "sysincludes.h"
30#include "stream.h"
31#include "mtools.h"
32#include "msdos.h"
33#include "scsi.h"
Alistair Delvabeaee832021-02-24 11:27:23 -080034#include "floppyd_io.h"
35
36#ifdef USE_FLOPPYD
37#include <sys/socket.h>
38#include <arpa/inet.h>
39#include <netdb.h>
40
41/* ######################################################################## */
42
43static const char* AuthErrors[] = {
44 "Auth success!",
45 "Auth failed: Packet oversized!",
46 "Auth failed: X-Cookie doesn't match!",
47 "Auth failed: Wrong transmission protocol version!",
48 "Auth failed: Device locked!"
49};
50
51#include "byte_dword.h"
52#include "read_dword.h"
53
54static int write_dword(int handle, Dword parm)
55{
56 Byte val[4];
57
58 dword2byte(parm, val);
59
60 if(write(handle, val, 4) < 4)
61 return -1;
62 return 0;
63}
64
65
66/* ######################################################################## */
67
Yi Kong39bbd962022-01-09 19:41:38 +080068static uint32_t authenticate_to_floppyd(char fullauth, int sock, char *display,
Alistair Delvabeaee832021-02-24 11:27:23 -080069 uint32_t protoversion)
70{
Yi Kong39bbd962022-01-09 19:41:38 +080071 uint32_t filelen=0;
Alistair Delvabeaee832021-02-24 11:27:23 -080072 Byte buf[16];
73 const char *command[] = { "xauth", "xauth", "extract", "-", 0, 0 };
74 char *xcookie = NULL;
75 Dword errcode;
76 uint32_t bytesRead;
77 uint32_t cap=0;
78
79 if (fullauth) {
80 command[4] = display;
81
Yi Kong39bbd962022-01-09 19:41:38 +080082 filelen=(uint32_t)strlen(display);
Alistair Delvabeaee832021-02-24 11:27:23 -080083 filelen += 100;
84
85 xcookie = (char *) safe_malloc(filelen+4);
Yi Kong39bbd962022-01-09 19:41:38 +080086 filelen = (uint32_t) safePopenOut(command, xcookie+4, filelen);
Alistair Delvabeaee832021-02-24 11:27:23 -080087 if(filelen < 1)
88 return AUTH_AUTHFAILED;
89 }
90 dword2byte(4,buf);
91 dword2byte(protoversion,buf+4);
92 if(write(sock, buf, 8) < 8)
93 return AUTH_IO_ERROR;
94
95 bytesRead = read_dword(sock);
96
97 if (bytesRead != 4 && bytesRead != 12) {
98 return AUTH_WRONGVERSION;
99 }
100
101
102 errcode = read_dword(sock);
103
104 if (errcode != AUTH_SUCCESS) {
105 return errcode;
106 }
107
Yi Kong39bbd962022-01-09 19:41:38 +0800108 protoversion = FLOPPYD_PROTOCOL_VERSION_OLD;
Alistair Delvabeaee832021-02-24 11:27:23 -0800109 if(bytesRead >= 12) {
110 protoversion = read_dword(sock);
111 cap = read_dword(sock);
112 }
Yi Kong39bbd962022-01-09 19:41:38 +0800113
Alistair Delvabeaee832021-02-24 11:27:23 -0800114 fprintf(stderr, "Protocol Version=%d\n", protoversion);
115 if(protoversion >= FLOPPYD_PROTOCOL_VERSION) {
Yi Kong39bbd962022-01-09 19:41:38 +0800116 fprintf(stderr, "Capabilities:%s%s\n",
Alistair Delvabeaee832021-02-24 11:27:23 -0800117 (cap & FLOPPYD_CAP_EXPLICIT_OPEN) ? " ExplicitOpen" : "",
118 (cap & FLOPPYD_CAP_LARGE_SEEK) ? " LargeFiles" : "");
119 }
120
121 if (fullauth) {
122 dword2byte(filelen, (Byte *) xcookie);
123 if(write(sock, xcookie, filelen+4) < (ssize_t)(filelen+4))
124 return AUTH_IO_ERROR;
125
126 if (read_dword(sock) != 4) {
127 return AUTH_PACKETOVERSIZE;
128 }
129
130 errcode = read_dword(sock);
131 }
132
133 return errcode;
134
135}
136
137
138/* ######################################################################## */
139
140static int get_host_and_port(const char* name, char** hostname, char **display,
141 uint16_t* port)
142{
143 char* newname = strdup(name);
144 char* p;
145 char* p2;
146
147 p = newname;
148 while (*p != '/' && *p) p++;
149 p2 = p;
150 if (*p) p++;
151 *p2 = 0;
Yi Kong39bbd962022-01-09 19:41:38 +0800152
Alistair Delvabeaee832021-02-24 11:27:23 -0800153 *port = atou16(p);
154 if (*port == 0) {
Yi Kong39bbd962022-01-09 19:41:38 +0800155 *port = FLOPPYD_DEFAULT_PORT;
Alistair Delvabeaee832021-02-24 11:27:23 -0800156 }
157
158 *display = strdup(newname);
159
160 p = newname;
161 while (*p != ':' && *p) p++;
162 p2 = p;
163 if (*p) p++;
164 *p2 = 0;
165
166 *port += atoi(p); /* add display number to the port */
167
168 if (!*newname || strcmp(newname, "unix") == 0) {
169 free(newname);
170 newname = strdup("localhost");
171 }
172
173 *hostname = newname;
174 return 1;
175}
176
177/*
178 * * Return the IP address of the specified host.
179 * */
180static in_addr_t getipaddress(char *ipaddr)
181{
Yi Kong39bbd962022-01-09 19:41:38 +0800182
Alistair Delvabeaee832021-02-24 11:27:23 -0800183 struct hostent *host;
184 in_addr_t ip;
Yi Kong39bbd962022-01-09 19:41:38 +0800185
Alistair Delvabeaee832021-02-24 11:27:23 -0800186 if (((ip = inet_addr(ipaddr)) == INADDR_NONE) &&
187 (strcmp(ipaddr, "255.255.255.255") != 0)) {
Yi Kong39bbd962022-01-09 19:41:38 +0800188
Alistair Delvabeaee832021-02-24 11:27:23 -0800189 if ((host = gethostbyname(ipaddr)) != NULL) {
190 memcpy(&ip, host->h_addr, sizeof(ip));
191 }
Yi Kong39bbd962022-01-09 19:41:38 +0800192
Alistair Delvabeaee832021-02-24 11:27:23 -0800193 endhostent();
194 }
Yi Kong39bbd962022-01-09 19:41:38 +0800195
Alistair Delvabeaee832021-02-24 11:27:23 -0800196#ifdef DEBUG
197 fprintf(stderr, "IP lookup %s -> 0x%08lx\n", ipaddr, ip);
198#endif
Yi Kong39bbd962022-01-09 19:41:38 +0800199
Alistair Delvabeaee832021-02-24 11:27:23 -0800200 return (ip);
201}
202
203/*
204 * * Connect to the floppyd server.
205 * */
206static int connect_to_server(in_addr_t ip, uint16_t port)
207{
Yi Kong39bbd962022-01-09 19:41:38 +0800208
Alistair Delvabeaee832021-02-24 11:27:23 -0800209 struct sockaddr_in addr;
210 int sock;
Yi Kong39bbd962022-01-09 19:41:38 +0800211
Alistair Delvabeaee832021-02-24 11:27:23 -0800212 /*
213 * Allocate a socket.
214 */
215 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
216 return (-1);
217 }
Yi Kong39bbd962022-01-09 19:41:38 +0800218
Alistair Delvabeaee832021-02-24 11:27:23 -0800219 /*
220 * Set the address to connect to.
221 */
Yi Kong39bbd962022-01-09 19:41:38 +0800222
Alistair Delvabeaee832021-02-24 11:27:23 -0800223 addr.sin_family = AF_INET;
224 addr.sin_port = htons(port);
225 addr.sin_addr.s_addr = ip;
Yi Kong39bbd962022-01-09 19:41:38 +0800226
Alistair Delvabeaee832021-02-24 11:27:23 -0800227 /*
228 * Connect our socket to the above address.
229 */
230 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
231 return (-1);
232 }
233
234 /*
235 * Set the keepalive socket option to on.
236 */
237 {
238 int on = 1;
Yi Kong39bbd962022-01-09 19:41:38 +0800239 setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
Alistair Delvabeaee832021-02-24 11:27:23 -0800240 (char *)&on, sizeof(on));
241
242 }
Yi Kong39bbd962022-01-09 19:41:38 +0800243
Alistair Delvabeaee832021-02-24 11:27:23 -0800244 return (sock);
245}
246
Yi Kong39bbd962022-01-09 19:41:38 +0800247int main (int argc, char** argv)
Alistair Delvabeaee832021-02-24 11:27:23 -0800248{
249 char* hostname;
250 char* display;
251 char* name;
252 uint16_t port;
253 int sock;
254 uint32_t reply;
255 int rval;
256 uint32_t protoversion;
257 char fullauth = 0;
258 Byte opcode = OP_CLOSE;
259
260 if (argc < 2) {
261 puts("Usage: floppyd_installtest [-f] Connect-String\n"
262 "-f\tDo full X-Cookie-Authentication");
263 return -1;
264 }
265
266 name = argv[1];
267 if (strcmp(name, "-f") == 0) {
268 fullauth = 1;
269 name = argv[2];
270 }
271
272 rval = get_host_and_port(name, &hostname, &display, &port);
Yi Kong39bbd962022-01-09 19:41:38 +0800273
Alistair Delvabeaee832021-02-24 11:27:23 -0800274 if (!rval) return -1;
275
276 sock = connect_to_server(getipaddress(hostname), port);
277
278 if (sock == -1) {
279 fprintf(stderr,
280 "Can't connect to floppyd server on %s, port %i!\n",
281 hostname, port);
282 return -1;
283 }
Yi Kong39bbd962022-01-09 19:41:38 +0800284
Alistair Delvabeaee832021-02-24 11:27:23 -0800285 protoversion = FLOPPYD_PROTOCOL_VERSION;
286 while(1) {
287 reply = authenticate_to_floppyd(fullauth, sock, display,
288 protoversion);
289 if(protoversion == FLOPPYD_PROTOCOL_VERSION_OLD)
290 break;
291 if(reply == AUTH_WRONGVERSION) {
292 /* fall back on old version */
293 protoversion = FLOPPYD_PROTOCOL_VERSION_OLD;
294 continue;
295 }
296 break;
297 }
298
299 if (reply != 0) {
Yi Kong39bbd962022-01-09 19:41:38 +0800300 fprintf(stderr,
Alistair Delvabeaee832021-02-24 11:27:23 -0800301 "Connection to floppyd failed:\n"
302 "%s\n", AuthErrors[reply]);
303 return -1;
304 }
Yi Kong39bbd962022-01-09 19:41:38 +0800305
Alistair Delvabeaee832021-02-24 11:27:23 -0800306 free(hostname);
307 free(display);
308
309 if(write_dword(sock, 1) < 0) {
310 fprintf(stderr,
311 "Short write to floppyd:\n"
312 "%s\n", strerror(errno));
313 }
314
315 if(write(sock, &opcode, 1) < 0) {
316 fprintf(stderr,
317 "Short write to floppyd:\n"
318 "%s\n", strerror(errno));
319 }
320
321 close(sock);
322
323 return 0;
324}
325#endif