11import argparse
2- from dissect .target .helpers .sunrpc .client import Client , auth_null , auth_unix
3- from dissect .target .helpers .nfs .serializer import MountResultDeserializer
2+
43from dissect .target .helpers .nfs .client import Client as NfsClient
4+ from dissect .target .helpers .nfs .nfs import EntryPlus3
5+ from dissect .target .helpers .nfs .serializer import MountResultDeserializer
6+ from dissect .target .helpers .sunrpc .client import Client , auth_null , auth_unix
57from dissect .target .helpers .sunrpc .serializer import (
68 PortMappingSerializer ,
79 StringSerializer ,
1618NFS_PROGRAM = 100003
1719NFS_V3 = 3
1820
19- hostname = "localhost"
20- root = "/home/roel"
21-
2221
2322# NFS client demo, showing how to connect to an NFS server and list the contents of a directory
2423# Note: some nfs servers require connecting using a low port number (use --port)
@@ -29,6 +28,7 @@ def main():
2928 parser .add_argument ("--port" , type = int , default = 0 , help = "The local port to bind to (default: 0)" )
3029 parser .add_argument ("--uid" , type = int , default = 1000 , help = "The user id to use for authentication" )
3130 parser .add_argument ("--gid" , type = int , default = 1000 , help = "The group id to use for authentication" )
31+ parser .add_argument ("--index" , type = int , default = 0 , help = "The index of the file to read (starting at 1)" )
3232 args = parser .parse_args ()
3333
3434 # RdJ: Perhaps move portmapper to nfs client and cache the mapping
@@ -38,16 +38,25 @@ def main():
3838 params_nfs = PortMapping (program = NFS_PROGRAM , version = NFS_V3 , protocol = Protocol .TCP )
3939 nfs_port = port_mapper_client .call (100000 , 2 , 3 , params_nfs , PortMappingSerializer (), UInt32Serializer ())
4040
41- mount_client = Client .connect (hostname , mount_port , auth_null (), args .port )
41+ mount_client = Client .connect (args . hostname , mount_port , auth_null (), args .port )
4242 mount_result = mount_client .call (
4343 MOUNT_PROGRAM , MOUNT_V3 , MOUNT , args .root , StringSerializer (), MountResultDeserializer ()
4444 )
4545 mount_client .close ()
4646
4747 auth = auth_unix ("twigtop" , args .uid , args .gid , [])
48- nfs_client = NfsClient .connect (hostname , nfs_port , auth , args .port )
48+ nfs_client = NfsClient .connect (args . hostname , nfs_port , auth , args .port )
4949 readdir_result = nfs_client .readdirplus (mount_result .filehandle )
50- print (readdir_result )
50+ for index , entry in enumerate (readdir_result .entries , start = 1 ):
51+ if entry .attributes :
52+ print (f"{ index :<5} { entry .name :<30} { entry .attributes .size :<10} " )
53+
54+ file_entry : EntryPlus3 = readdir_result .entries [args .index - 1 ]
55+ if file_entry .attributes :
56+ file_contents = nfs_client .readfile_by_handle (file_entry .handle )
57+ with open (file_entry .name , "wb" ) as f :
58+ for chunk in file_contents :
59+ f .write (chunk )
5160
5261
5362if __name__ == "__main__" :
0 commit comments