1#include <string.h>
2#include <netdb.h>
3#include <sys/stat.h>
4#include <errno.h>
5#include <stdio.h>
6#include <ctype.h>
7#include <Application.h>
8#include <unistd.h>
9#include <signal.h>
10#include <stdlib.h>
11#include <Roster.h>
12#ifdef __BEOS__
13#include <bone/sys/socket.h>
14#else
15#include "socket.h"
16#endif
17
18#include "betalk.h"
19#include "rpc.h"
20#include "md5.h"
21#include "BlowFish.h"
22#include "LoginPanel.h"
23
24#ifndef BONE_VERSION
25#include "ksocket_internal.h"
26#endif
27
28struct mount_nfs_params
29{
30	unsigned int serverIP;
31	char *server;
32	char *_export;
33	uid_t uid;
34	gid_t gid;
35	char *hostname;
36	char *folder;
37	char user[MAX_USERNAME_LENGTH + 1];
38	char password[BT_AUTH_TOKEN_LENGTH * 2 + 1];
39};
40
41int main (int argc, char *argv[]);
42bool getAuthentication(unsigned int serverIP, char *shareName);
43bool authenticateSelf(char *server, char *share, char *user, char *password, bool useTracker);
44void getString(char *string, int length, bool displayChars);
45void usage();
46
47
48int main(int argc, char *argv[])
49{
50	mount_nfs_params params;
51	blf_ctx ctx;
52	hostent *ent;
53	struct stat st;
54	char hostname[256], server[256], share[256], folder[B_PATH_NAME_LENGTH], password[MAX_NAME_LENGTH + 1], *colon;
55	port_id port;
56	int length, hostArg = 1, pathArg = 2;
57	bool useTracker = false;
58
59	BApplication theApp("application/x-vnd.teldar-mounthost");
60
61	if (argc < 3 || argc > 5)
62	{
63		usage();
64		return 1;
65
66	}
67
68	if (*argv[1] == '-')
69	{
70		hostArg++;
71		pathArg++;
72		if (strcmp(argv[1], "-t") == 0)
73			useTracker = true;
74		else
75			printf("Option %s not understood and ignored\n", argv[1]);
76	}
77
78	if (strcasecmp(argv[pathArg], "at") == 0)
79		pathArg++;
80
81	if (stat(argv[pathArg], &st) != 0)
82	{
83		printf("The specified mount path does not exist.\n");
84		return 1;
85	}
86
87	strcpy(server, argv[hostArg]);
88	colon = strchr(server, ':');
89	if (colon == NULL)
90	{
91		usage();
92		return 1;
93	}
94
95	*colon = 0;
96	strcpy(share, colon + 1);
97	strcpy(folder, argv[pathArg]);
98
99	ent = gethostbyname(server);
100	if (ent == NULL)
101	{
102		printf("Server %s is unknown or its network address could not be\nresolved from that host name.\n", server);
103		return 1;
104	}
105
106	unsigned int serverIP = ntohl(*((unsigned int *) ent->h_addr));
107
108#ifndef BONE_VERSION
109	if (!be_roster->IsRunning(KSOCKETD_SIGNATURE))
110		if (be_roster->Launch(KSOCKETD_SIGNATURE) < B_NO_ERROR)
111		{
112			printf("The kernel socket daemon ksocketd could not be started.\n");
113			return 1;
114		}
115
116	for (int32 i = 0; i < 10; i++)
117	{
118		port = find_port(KSOCKET_DAEMON_NAME);
119
120		if (port < B_NO_ERROR)
121			snooze(1000000LL);
122		else
123			break;
124	}
125
126	if (port < B_NO_ERROR)
127	{
128		printf ("The kernel socket daemon ksocketd is not responding.\n");
129		return 1;
130	}
131#endif
132
133	int result = B_OK;
134
135	params.user[0] = params.password[0] = 0;
136
137	if (getAuthentication(serverIP, share))
138		if (!authenticateSelf(server, share, params.user, password, useTracker))
139			return 1;
140		else
141		{
142			// Copy the user name and password supplied in the authentication dialog.
143			sprintf(params.password, "%-*s%-*s", B_FILE_NAME_LENGTH, share, MAX_USERNAME_LENGTH, params.user);		//crypt(password, "p1"));
144			params.password[BT_AUTH_TOKEN_LENGTH] = 0;
145
146			blf_key(&ctx, (unsigned char *) password, strlen(password));
147			blf_enc(&ctx, (unsigned long *) params.password, BT_AUTH_TOKEN_LENGTH / 4);
148		}
149
150	params.serverIP = serverIP;
151	params.server = server;
152	params._export = share;
153	params.folder = folder;
154	params.uid = 0;
155	params.gid = 0;
156
157	gethostname(hostname, 256);
158	params.hostname = hostname;
159
160	result = mount("beserved_client", folder, NULL, 0, &params, sizeof(params));
161
162	if (result < B_NO_ERROR)
163	{
164		printf ("Could not mount remote file share (%s).\n", strerror(errno));
165		return 1;
166	}
167
168	return 0;
169}
170
171bool getAuthentication(unsigned int serverIP, char *shareName)
172{
173	bt_inPacket *inPacket;
174	bt_outPacket *outPacket;
175	int security;
176
177	security = EHOSTUNREACH;
178
179	outPacket = btRPCPutHeader(BT_CMD_PREMOUNT, 1, strlen(shareName));
180	btRPCPutArg(outPacket, B_STRING_TYPE, shareName, strlen(shareName));
181	inPacket = btRPCSimpleCall(serverIP, BT_TCPIP_PORT, outPacket);
182	if (inPacket)
183	{
184		security = btRPCGetInt32(inPacket);
185		free(inPacket->buffer);
186		free(inPacket);
187	}
188
189	return (security == BT_AUTH_BESURE);
190}
191
192bool authenticateSelf(char *server, char *share, char *user, char *password, bool useTracker)
193{
194	char pwBuffer[50];
195
196	if (useTracker)
197	{
198		BRect frame(0, 0, LOGIN_PANEL_WIDTH, LOGIN_PANEL_HEIGHT);
199		LoginPanel *login = new LoginPanel(frame, server, share, false);
200		login->Center();
201		status_t loginExit;
202		wait_for_thread(login->Thread(), &loginExit);
203		if (login->IsCancelled())
204			return false;
205
206		strcpy(user, login->user);
207		strcpy(password, login->md5passwd);
208	}
209	else
210	{
211		printf("Username: ");
212		getString(user, MAX_NAME_LENGTH, true);
213		printf("Password: ");
214		getString(pwBuffer, MAX_NAME_LENGTH, false);
215		md5EncodeString(pwBuffer, password);
216	}
217
218	return true;
219}
220
221void getString(char *string, int length, bool displayChars)
222{
223	char ch;
224	int pos = 0;
225
226	while ((ch = getchar()) != '\n')
227		if (pos < length - 1)
228			string[pos++] = ch;
229
230	string[pos] = 0;
231}
232
233void usage()
234{
235	printf("Usage: mounthost [-bt] server:share [at] path\n");
236	printf("Options:\n");
237	printf("\t-t\tUse the BeOS Tracker to request the user name and password\n");
238}
239