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, ¶ms, 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