Skip to content

Commit

Permalink
Fuse improvements by RJVB
Browse files Browse the repository at this point in the history
- use ssh-askpass for password requests when not connected
  to a terminal & allow options for fusermount
- export appropriate filesystem and subvolume names
  • Loading branch information
rdmark committed Jan 29, 2024
1 parent 580faae commit 382e645
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 11 deletions.
1 change: 1 addition & 0 deletions fuse/afp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct afp_server_mount_request {
unsigned int volume_options;
unsigned int map;
int changeuid;
char fuse_options[256];
};

struct afp_server_status_request {
Expand Down
42 changes: 36 additions & 6 deletions fuse/client.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -156,6 +157,7 @@ static void usage(void)
" \"DHCAST128\", \"Client Krb v2\", \"DHX2\" \n\n"
" -m, --map <mapname> : use this uid/gid mapping method, one of:\n"
" \"Common user directory\", \"Login ids\"\n"
" -O, --options <flags> : FUSE mount options, see man mount.fuse\n"
" status: get status of the AFP daemon\n\n"
" unmount <mountpoint> : unmount\n\n"
" suspend <servername> : terminates the connection to the server, but\n"
Expand All @@ -166,6 +168,30 @@ static void usage(void)
}


static char *get_password(const char *prompt)
{
if( isatty(fileno(stdin)) ){
return getpass(prompt);
}
else{
char *askpass = NULL;
static char pwd[AFP_MAX_PASSWORD_LEN+1];
FILE *fp;
asprintf( &askpass, "ssh-askpass %s", prompt );
if( (fp = popen( askpass, "r" )) ){
fread( pwd, 1, sizeof(pwd), fp );
pclose(fp);
// ssh-askpass always adds a newline: chop it.
pwd[strlen(pwd) - 1] = '\0';
}
else{
perror(askpass);
memset( pwd, (int) sizeof(pwd), (0) );
}
return pwd;
}
}

static int send_command(int sock, char * msg,int len)
{

Expand Down Expand Up @@ -281,6 +307,7 @@ static int do_mount(int argc, char ** argv)
{"port",1,0,'o'},
{"uam",1,0,'a'},
{"map",1,0,'m'},
{"options",1,0,'O'},
{0,0,0,0},
};

Expand All @@ -295,10 +322,11 @@ static int do_mount(int argc, char ** argv)
outgoing_buffer[0]=AFP_SERVER_COMMAND_MOUNT;
req->url.port=548;
req->map=AFP_MAPPING_UNKNOWN;
req->fuse_options[0] = '\0';

while(1) {
optnum++;
c = getopt_long(argc,argv,"a:u:m:o:p:v:V:",
c = getopt_long(argc,argv,"a:u:m:o:p:v:V:O:",
long_options,&option_index);
if (c==-1) break;
switch(c) {
Expand Down Expand Up @@ -326,16 +354,19 @@ static int do_mount(int argc, char ** argv)
case 'v':
req->url.requested_version=strtol(optarg,NULL,10);
break;
case 'O':
snprintf( req->fuse_options, sizeof(req->fuse_options), "%s", optarg );
break;
}
}

if (strcmp(req->url.password, "-") == 0) {
char *p = getpass("AFP Password: ");
char *p = get_password("AFP Password: ");
if (p)
snprintf(req->url.password,AFP_MAX_PASSWORD_LEN,"%s",p);
}
if (strcmp(req->url.volpassword, "-") == 0) {
char *p = getpass("Password for volume: ");
char *p = get_password("Password for volume: ");
if (p)
snprintf(req->url.volpassword,9,"%s",p);
}
Expand Down Expand Up @@ -365,7 +396,6 @@ static int do_mount(int argc, char ** argv)

snprintf(req->mountpoint,255,"%s",argv[optnum++]);


return 0;
}

Expand Down Expand Up @@ -462,13 +492,13 @@ static int handle_mount_afp(int argc, char * argv[])
return -1;
}
if (strcmp(req->url.password,"-")==0) {
char *p = getpass("AFP Password: ");
char *p = get_password("AFP Password: ");
if (p)
snprintf(req->url.password,AFP_MAX_PASSWORD_LEN,"%s",p);
}

if (volpass && (strcmp(volpass,"-")==0)) {
volpass = getpass("Password for volume: ");
volpass = get_password("Password for volume: ");
}
if (volpass)
snprintf(req->url.volpassword,9,"%s",volpass);
Expand Down
97 changes: 93 additions & 4 deletions fuse/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*
*/

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <errno.h>
Expand Down Expand Up @@ -35,11 +36,14 @@
#include "fuse_internal.h"

#ifdef __linux
#define FUSE_DEVICE "/dev/fuse"
# define FUSE_DEVICE "/dev/fuse"
#else
#define FUSE_DEVICE "/dev/fuse0"
# define FUSE_DEVICE "/dev/fuse0"
#endif

# define FUSE_USE_VERSION 29

#include <fuse/fuse.h>

static int fuse_log_method=LOG_METHOD_SYSLOG;

Expand Down Expand Up @@ -185,9 +189,46 @@ struct start_fuse_thread_arg {
int fuse_result;
int fuse_errno;
int changeuid;
char *fuse_options;
};

static void * start_fuse_thread(void * other)
/*
* Remove commas from fsname, as it confuses the fuse option parser.
* Copied from sshfs.c
*/
static void fsname_remove_commas(char *fsname)
{
if (strchr(fsname, ',') != NULL) {
char *s = fsname;
char *d = s;

for (; *s; s++) {
if (*s != ',')
*d++ = *s;
}
*d = *s;
}
}

// * Copied from sshfs.c
static char *fsname_escape_commas(char *fsnameold)
{
char *fsname = malloc(strlen(fsnameold) * 2 + 1);
char *d = fsname;
char *s;

for (s = fsnameold; *s; s++) {
if (*s == '\\' || *s == ',')
*d++ = '\\';
*d++ = *s;
}
*d = '\0';
free(fsnameold);

return fsname;
}

static void * start_fuse_thread(void * other)
{
int fuseargc=0;
const char *fuseargv[200];
Expand All @@ -197,6 +238,8 @@ static void * start_fuse_thread(void * other)
struct afp_volume * volume = arg->volume;
struct fuse_client * c = arg->client;
struct afp_server * server = volume->server;
char *fsname, *fsoption = NULL;
int libver = fuse_version();

/* Check to see if we have permissions to access the mountpoint */

Expand All @@ -222,6 +265,44 @@ static void * start_fuse_thread(void * other)
fuseargv[fuseargc]="allow_other";
fuseargc++;
}
// fuseargv[fuseargc] = "-osubtype=afpfs,fsname=foo@host";
// fuseargc++;
asprintf( &fsname, "%s@%s:%s", server->username, server->server_name, volume->volume_name );
if( libver >= 27 ){
if( libver >= 28 ){
fsname = fsname_escape_commas(fsname);
}
else{
fsname_remove_commas(fsname);
}
asprintf( &fuseargv[fuseargc], "-osubtype=afpfs,fsname=%s", fsname );
}
else{
fsname_remove_commas(fsname);
asprintf( &fuseargv[fuseargc], "-ofsname=afpfs#%s", fsname );
}
fsoption = fuseargv[fuseargc];
fuseargc++;

{ int i;
char *msg = NULL;
asprintf( &msg, "\tfuse version=%d args={'%s'",
fuse_version(), fuseargv[0] );
for( i = 1 ; i < fuseargc ; ++i ){
asprintf( &msg, "%s,'%s'", msg, fuseargv[i] );
}
log_for_client((void *) c, AFPFSD, LOG_WARNING,
"%s}\n", msg );
if( msg ){
free(msg);
}
}
if ( arg->fuse_options && strlen(arg->fuse_options) ) {
fuseargv[fuseargc]="-o";
fuseargc++;
fuseargv[fuseargc] = arg->fuse_options;
fuseargc++;
}


/* #ifdef USE_SINGLE_THREAD */
Expand All @@ -244,7 +325,14 @@ static void * start_fuse_thread(void * other)
"Unmounting volume %s from %s\n",
volume->volume_name_printable,
volume->mountpoint);

if( fsname ){
free(fsname);
fsname = NULL;
}
if( fsoption ){
free(fsoption);
fsoption = NULL;
}
return NULL;
}

Expand Down Expand Up @@ -485,6 +573,7 @@ static int process_mount(struct fuse_client * c)
arg.volume = volume;
arg.wait = 1;
arg.changeuid=req->changeuid;
arg.fuse_options = req->fuse_options;

gettimeofday(&tv,NULL);
ts.tv_sec=tv.tv_sec;
Expand Down
2 changes: 1 addition & 1 deletion fuse/fuse_internal.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef __FUSE_INTERNAL_H_
#define __FUSE_INTERNAL_H_

#define AFP_CLIENT_INCOMING_BUF 2048
#define AFP_CLIENT_INCOMING_BUF 2048+256


struct fuse_client {
Expand Down

0 comments on commit 382e645

Please sign in to comment.