private void Mount(rpcCracker cracker, rpcPacker reply) { uint length = cracker.get_uint32(); string dirPath = ""; for (uint i = 0; i < length; ++i) dirPath += cracker.get_char(); Console.WriteLine("Mount {0}:{1}", length, dirPath); if (Directory.Exists(dirPath) == false) { reply.setUint32(2); // Errno for no such file or directory reply.setUint32(0); // Where fh would go } else { fhandle fh = FileTable.Add(new FileEntry(dirPath)); reply.setUint32(0); // Success fh.Pack(reply); } }
private void GetPort(rpcCracker cracker, rpcPacker packer) { const uint IPPROTO_UDP = 17; uint prog = cracker.get_uint32(); uint vers = cracker.get_uint32(); uint prot = cracker.get_uint32(); uint port = cracker.get_uint32(); Console.WriteLine("prog:{0}, vers:{1}, prot:{2}, port:{3}", prog, vers, prot, port); uint registeredPort = 0; if (prot == IPPROTO_UDP) { if (prog == (uint)Progs.mountd && vers == (uint)Vers.mountd) { registeredPort = (uint)Ports.mountd; } else if (prog == (uint)Progs.nfsd && vers == (uint)Vers.nfsd) { registeredPort = (uint)Ports.nfsd; } } packer.setUint32(registeredPort); }
public void Run() { while (true) { remoteHost = new IPEndPoint(IPAddress.Any, 0); Byte[] data = conn.Receive(ref remoteHost); Console.WriteLine("{0}: Received a connection from:{1}", prog, remoteHost.ToString()); rpcCracker cracker = new rpcCracker(data); //cracker.Dump("Received"); rpcPacker reply = CrackRPC(cracker); Console.WriteLine("{0}: Sending a reply to:{1}", prog, remoteHost.ToString()); //reply.Dump("Sending"); int sent = conn.Send(reply.Data, (int)reply.Length, remoteHost); if (sent != (int)reply.Length) { Console.WriteLine("*** Didn't send all. Length:{0}, sent:{1}", reply.Length, sent); } } }
public void Pack(rpcPacker packer) { //Console.WriteLine("entry pack name:{0}", name); packer.setUint32(fileid); packer.setString(name); packer.setUint32(cookie); }
private rpcPacker ProgMismatchReply(uint xid) { rpcPacker reply = NewAcceptReply(xid, 2); reply.setUint32(prog); // rpc_msg.reply_body.accepted_reply.mismatch_info.low reply.setUint32(prog); // rpc_msg.reply_body.accepted_reply.mismatch_info.high return(reply); }
protected override void Proc(uint proc, rpcCracker cracker, rpcPacker packer) { switch (proc) { case 3: // GetPort GetPort(cracker, packer); break; default: throw new BadProc(); } }
private rpcPacker RPCMismatchReply(uint xid) { rpcPacker reply = new rpcPacker(); reply.setUint32(xid); reply.setUint32(1); // rpc_msg.REPLY reply.setUint32(1); // rpc_msg.reply_body.MSG_DENIED reply.setUint32(0); // rpc_msg.reply_body.rejected_reply.RPC_MISMATCH reply.setUint32(2); // rpc_msg.reply_body.rejected_reply.mismatch_info.low reply.setUint32(2); // rpc_msg.reply_body.rejected_reply.mismatch_info.low return(reply); }
public void Pack(rpcPacker packer) { packer.setUint32(index); // Pad packer.setUint32(0); packer.setUint32(0); packer.setUint32(0); packer.setUint32(0); packer.setUint32(0); packer.setUint32(0); packer.setUint32(0); }
private rpcPacker NewAcceptReply(uint xid, uint acceptStatus) { rpcPacker reply = new rpcPacker(); reply.setUint32(xid); reply.setUint32(1); // rpc_msg.REPLY reply.setUint32(0); // rpc_msg.reply_body.MSG_ACCEPTED reply.setUint32(0); // rpc_msg.reply_body.accepted_reply.opaque_auth.NULL reply.setUint32(0); // rpc_msg.reply_body.accepted_reply.opaque_auth.<datsize> // rpc_msg.reply_body.accepted_reply.<case> reply.setUint32(acceptStatus); return(reply); }
private rpcPacker CrackRPC(rpcCracker cracker) { uint xid = cracker.get_uint32(); uint msg_type = cracker.get_uint32(); uint rpcvers = cracker.get_uint32(); uint prog = cracker.get_uint32(); uint vers = cracker.get_uint32(); uint proc = cracker.get_uint32(); #if DEBUG Console.WriteLine("{0}> {1}: xid:{2}, type:{3}, rpcvers:{4}, prog:{5}, vers:{6}, proc:{7}", ++count, this.prog, xid, msg_type, rpcvers, prog, vers, proc); #endif if (msg_type != 0) { return(GarbageArgsReply(xid)); } if (rpcvers != 2) { return(RPCMismatchReply(xid)); } if (this.prog != prog && Prog(prog) != true) { return(ProgMismatchReply(xid)); } CrackCredentials(cracker); CrackVerifier(cracker); try { rpcPacker reply = SuccessReply(xid); if (proc != 0) { Proc(proc, cracker, reply); } return(reply); } catch (Exception e) { System.Console.WriteLine("Whoops: {0}", e); return(ProcUnavilReply(xid)); } }
protected override void Proc(uint proc, rpcCracker cracker, rpcPacker reply) { switch (proc) { case (uint)Procs.Null: throw new BadProc(); case (uint)Procs.Mount: Mount(cracker, reply); break; case (uint)Procs.Dump: throw new BadProc(); case (uint)Procs.UMount: UMount(cracker, reply); break; case (uint)Procs.UMountAll: throw new BadProc(); case (uint)Procs.Export: throw new BadProc(); default: throw new BadProc(); } }
private void CreateFileOrDirectory(rpcCracker cracker, rpcPacker packer, bool createFile) { createargs args = new createargs(cracker); String createPath = FileTable.LookupFileEntry(args.Where.DirHandle).Name + @"\" + args.Where.FileName; Console.WriteLine("Create: {0}", createPath); fhandle fh; if ((fh = FileTable.LookupFileHandle(createPath)) == null) fh = FileTable.Add(new FileEntry(createPath)); if (createFile == true) new FileInfo(createPath).Create().Close(); else new DirectoryInfo(createPath).Create(); fattr attr = new fattr(fh); if (attr.IsFile() != createFile) throw new System.Exception(); diropres.PackSuccess(packer, fh, attr); }
private void Create(rpcCracker cracker, rpcPacker packer) { CreateFileOrDirectory(cracker, packer, true); }
public static void PackError(rpcPacker packer, NFSStatus error) { packer.setUint32((uint)error); }
public static void PackSuccess(rpcPacker packer, fattr attr) { packer.setUint32((uint)NFSStatus.NFS_OK); attr.Pack(packer); }
private void ReadDir(rpcCracker cracker, rpcPacker packer) { fhandle fh = new fhandle(cracker); uint cookie = cracker.get_uint32(); uint count = cracker.get_uint32(); FileEntry dir = FileTable.LookupFileEntry(fh); //Console.WriteLine("ReadDir:{0}, cookie:{1}, count:{2}, resultsNULL:{3}", dir.Name, cookie, count, results == null); if (cookie == 0 || results == null) { if (dir == null) throw new NFSStatusException(NFSStatus.NFSERR_EXIST); try { results = new readdirres(dir.Name, count); } catch(DirectoryNotFoundException) { FileTable.Remove(fh); throw; } } if (results.Pack(packer, cookie, count) == true) results = null; }
private void MkDir(rpcCracker cracker, rpcPacker packer) { CreateFileOrDirectory(cracker, packer, false); }
private void RmDir(rpcCracker cracker, rpcPacker packer) { diropargs args = new diropargs(cracker); String removePath = FileTable.LookupFileEntry(args.DirHandle).Name + @"\" + args.FileName; Console.WriteLine(@"RmDir: {0}", removePath); fhandle fh = FileTable.LookupFileHandle(removePath); try { new DirectoryInfo(removePath).Delete(false); } catch (IOException) { if (new DirectoryInfo(removePath).GetFileSystemInfos().Length > 0) throw new NFSStatusException(NFSStatus.NFSERR_NOTEMPTY); else throw new NFSStatusException(NFSStatus.NFSERR_PERM); } if (fh != null) FileTable.Remove(fh); packer.setUint32((uint)NFSStatus.NFS_OK); }
private void Remove(rpcCracker cracker, rpcPacker packer) { diropargs args = new diropargs(cracker); String removePath = FileTable.LookupFileEntry(args.DirHandle).Name + @"\" + args.FileName; FileInfo info = new FileInfo(removePath); if (info.Exists == false) { removePath += ".sl"; info = new FileInfo(removePath); } Console.WriteLine(@"Remove: {0}", removePath); fhandle fh = FileTable.LookupFileHandle(removePath); info.Delete(); // If UnauthorizedAccessException is thrown & caught should // probably stat file to determine if the cause is because // the path is a dir rather than a directory. if (fh != null) FileTable.Remove(fh); packer.setUint32((uint)NFSStatus.NFS_OK); }
public bool Pack(rpcPacker packer, uint cookie, uint count) { packer.setUint32((uint)NFSStatus.NFS_OK); uint size = 8; // First pointer + EOF if (cookie >= entries.Length) { // nothing } else { do { entry next = entries[cookie]; if (size + next.Size > count) break; else size += next.Size; // true as in yes, more follows. This is *entry. packer.setUint32(1); next.Pack(packer); } while (++cookie < entries.Length); } // false as in no more follow. This is *entry. // Unlike EOF which is set only when all entries have been sent // *entry is reset to false following the last entry in each // batch. packer.setUint32(0); //Console.WriteLine("ReadDir: Pack done. cookie:{0}, size:{1}", cookie, size); // EOF if (cookie >= entries.Length) { packer.setUint32((uint)1); // yes return true; } else { packer.setUint32((uint)0); // no return false; } }
private void UMount(rpcCracker cracker, rpcPacker reply) { uint length = cracker.get_uint32(); string dirPath = ""; for (uint i = 0; i < length; ++i) dirPath += cracker.get_char(); Console.WriteLine("UMount {0}:{1}", length, dirPath); #if FOO uint fh = fileHandles.Find( if (fileHandles.Remove(dirPath) == false) Console.WriteLine("{0} not mounted", dirPath); #endif }
private void GetAttr(rpcCracker cracker, rpcPacker packer) { attrstat.PackSuccess(packer, new fattr(new fhandle(cracker))); }
private void StatFS(rpcCracker cracker, rpcPacker packer) { const uint BLOCK_SIZE = 4096; fhandle fh = new fhandle(cracker); FileEntry file = FileTable.LookupFileEntry(fh); Console.WriteLine("StatFS: {0}", file.Name); System.UInt64 freeBytesAvailable = 0; System.UInt64 totalNumberOfBytes = 0; System.UInt64 totalNumberOfFreeBytes = 0; if (UnmanagedWin32API.GetDiskFreeSpaceEx(file.Name, ref freeBytesAvailable, ref totalNumberOfBytes, ref totalNumberOfFreeBytes) == false) throw new NFSStatusException(NFSStatus.NFSERR_EXIST); freeBytesAvailable /= BLOCK_SIZE; totalNumberOfBytes /= BLOCK_SIZE; totalNumberOfFreeBytes /= BLOCK_SIZE; packer.setUint32((uint)NFSStatus.NFS_OK); packer.setUint32(BLOCK_SIZE); // tsize: optimum transfer size packer.setUint32(BLOCK_SIZE); // Block size of FS packer.setUint32((uint)totalNumberOfBytes); // Total # of blocks (of the above size) packer.setUint32((uint)totalNumberOfFreeBytes); // Free blocks packer.setUint32((uint)freeBytesAvailable); // Free blocks available to non-priv. users }
private void Lookup(rpcCracker cracker, rpcPacker packer) { diropargs args = new diropargs(cracker); String lookupPath = FileTable.LookupFileEntry(args.DirHandle).Name + @"\" + args.FileName; String symLinkLookupPath = lookupPath + ".sl"; #if DEBUG //Console.WriteLine(@"Lookup: {0}", lookupPath); #endif fhandle fh = null; #if DEBUG try { #endif if ((fh = FileTable.LookupFileHandle(lookupPath)) == null) { //Console.WriteLine(@"Lookup (symlink): {0}", symLinkLookupPath); fh = FileTable.LookupFileHandle(symLinkLookupPath); } // Entry (for file or symlink) not in FileTable if (fh == null) { // Try non-SL first fh = FileTable.Add(new FileEntry(lookupPath)); try { diropres.PackSuccess(packer, fh, new fattr(fh)); } catch { FileTable.Remove(fh); fh = FileTable.Add(new FileEntry(symLinkLookupPath)); } } // Case where fh is in FileTable and used when neither was but // regular file/dir has not been found so add entry for SL #if DEBUG } catch { Console.WriteLine(@"Lookup EXCEPTION: {0}", lookupPath); throw; } #endif diropres.PackSuccess(packer, fh, new fattr(fh)); }
private void SymLink(rpcCracker cracker, rpcPacker packer) { diropargs args = new diropargs(cracker); string path = cracker.get_String(); sattr attr = new sattr(cracker); String createPath = FileTable.LookupFileEntry(args.DirHandle).Name + @"\" + args.FileName + ".sl"; Console.WriteLine("Symlink: {0}->{1}", createPath, path); fhandle fh; if ((fh = FileTable.LookupFileHandle(createPath)) == null) fh = FileTable.Add(new FileEntry(createPath)); try { FileStream symlink = new FileStream(createPath, FileMode.CreateNew, FileAccess.Write); try { UTF8Encoding pathUTF8 = new UTF8Encoding(); byte[] buf = pathUTF8.GetBytes(path); symlink.Write(buf, 0, buf.Length); packer.setUint32((uint)NFSStatus.NFS_OK); } finally { symlink.Close(); } } catch(IOException) { if (new FileInfo(createPath).Exists == true) throw new NFSStatusException(NFSStatus.NFSERR_EXIST); else throw; } }
private void Read(rpcCracker cracker, rpcPacker packer) { fhandle fh = new fhandle(cracker); uint offset = cracker.get_uint32(); uint count = cracker.get_uint32(); uint totalCount = cracker.get_uint32(); FileStream fs; try { fs = new FileStream(FileTable.LookupFileEntry(fh).Name, FileMode.Open, FileAccess.Read); } catch (System.IO.FileNotFoundException) { FileTable.Remove(fh); throw; } try { fs.Position = offset; Byte[] buf = new Byte[count]; int bytesRead = fs.Read(buf, 0, (int)count); fattr attr = new fattr(fh); if (attr.IsFile() == false) throw new NFSStatusException(NFSStatus.NFSERR_ISDIR); packer.setUint32((uint)NFSStatus.NFS_OK); attr.Pack(packer); packer.setData(buf, bytesRead); } finally { fs.Close(); } }
public void Pack(rpcPacker packer) { packer.setUint32((uint)type); packer.setUint32(mode); packer.setUint32(nlink); packer.setUint32(uid); packer.setUint32(gid); packer.setUint32(size); packer.setUint32(blocksize); packer.setUint32(rdev); packer.setUint32(blocks); packer.setUint32(fsid); packer.setUint32(fileid); atime.Pack(packer); mtime.Pack(packer); mtime.Pack(packer); }
private void ReadLink(rpcCracker cracker, rpcPacker packer) { fhandle fh = new fhandle(cracker); FileStream fs; try { fs = new FileStream(FileTable.LookupFileEntry(fh).Name, FileMode.Open, FileAccess.Read); } catch (System.IO.FileNotFoundException) { FileTable.Remove(fh); throw; } try { Byte[] buf = new Byte[MAXPATHLEN]; int bytesRead = fs.Read(buf, 0, MAXPATHLEN); packer.setUint32((uint)NFSStatus.NFS_OK); packer.setData(buf, buf.Length); } finally { fs.Close(); } }
protected abstract void Proc(uint proc, rpcCracker cracker, rpcPacker reply);
private void Rename(rpcCracker cracker, rpcPacker packer) { diropargs from = new diropargs(cracker); diropargs to = new diropargs(cracker); string fromPath = FileTable.LookupFileEntry(from.DirHandle).Name + @"\" + from.FileName; string toPath = FileTable.LookupFileEntry(to.DirHandle).Name + @"\" + to.FileName; Console.WriteLine("Rename {0} to {1}", fromPath, toPath); if (File.Exists(toPath) == true) File.Delete(toPath); File.Move(fromPath, toPath); // Only bother updating the FileTable if the operation was successful FileTable.Rename(fromPath, toPath); packer.setUint32((uint)NFSStatus.NFS_OK); }
private rpcPacker NewAcceptReply(uint xid, uint acceptStatus) { rpcPacker reply = new rpcPacker(); reply.setUint32(xid); reply.setUint32(1); // rpc_msg.REPLY reply.setUint32(0); // rpc_msg.reply_body.MSG_ACCEPTED reply.setUint32(0); // rpc_msg.reply_body.accepted_reply.opaque_auth.NULL reply.setUint32(0); // rpc_msg.reply_body.accepted_reply.opaque_auth.<datsize> // rpc_msg.reply_body.accepted_reply.<case> reply.setUint32(acceptStatus); return reply; }
private void SetAttr(rpcCracker cracker, rpcPacker packer) { fhandle fh = new fhandle(cracker); sattr attributes = new sattr(cracker); FileEntry file = FileTable.LookupFileEntry(fh); if (file == null) { Console.WriteLine("Invalid file handle:{0}", fh.Index); throw new NFSStatusException(NFSStatus.NFSERR_STALE); } // TODO: Actually do something with the attributes. if (attributes.Size == 0) { try { FileStream fs = new FileStream(file.Name, FileMode.Truncate, FileAccess.Write); fs.Close(); } catch (System.IO.FileNotFoundException) { FileTable.Remove(fh); throw; } } if ((int)attributes.Mode != -1) { FileInfo info = new FileInfo(FileTable.LookupFileEntry(fh).Name); if ((attributes.Mode & (uint)fattr.modes.WOWN) == (uint)fattr.modes.WOWN) info.Attributes = info.Attributes & ~FileAttributes.ReadOnly; else info.Attributes = info.Attributes | FileAttributes.ReadOnly; } attrstat.PackSuccess(packer, new fattr(fh)); }
private rpcPacker RPCMismatchReply(uint xid) { rpcPacker reply = new rpcPacker(); reply.setUint32(xid); reply.setUint32(1); // rpc_msg.REPLY reply.setUint32(1); // rpc_msg.reply_body.MSG_DENIED reply.setUint32(0); // rpc_msg.reply_body.rejected_reply.RPC_MISMATCH reply.setUint32(2); // rpc_msg.reply_body.rejected_reply.mismatch_info.low reply.setUint32(2); // rpc_msg.reply_body.rejected_reply.mismatch_info.low return reply; }
protected override void Proc(uint proc, rpcCracker cracker, rpcPacker packer) { try { switch(proc) { case 1: GetAttr(cracker, packer); break; case 2: SetAttr(cracker, packer); break; case 3: // Root(). No-op. break; case 4: Lookup(cracker, packer); break; case 5: ReadLink(cracker, packer); break; case 6: Read(cracker, packer); break; case 8: Write(cracker, packer); break; case 9: Create(cracker, packer); break; case 10: Remove(cracker, packer); break; case 11: Rename(cracker, packer); break; case 13: SymLink(cracker, packer); break; case 14: MkDir(cracker, packer); break; case 15: RmDir(cracker, packer); break; case 16: ReadDir(cracker, packer); break; case 17: StatFS(cracker, packer); break; default: throw new BadProc(); } } catch(BadProc) { throw; } catch(NFSStatusException e) { packer.setUint32((uint)e.Status); } catch (System.IO.FileNotFoundException) { packer.setUint32((uint)NFSStatus.NFSERR_NOENT); } catch(UnauthorizedAccessException) { packer.setUint32((uint)NFSStatus.NFSERR_PERM); } catch(PathTooLongException) { packer.setUint32((uint)NFSStatus.NFSERR_NAMETOOLONG); } catch(DirectoryNotFoundException) { packer.setUint32((uint)NFSStatus.NFSERR_NOTDIR); } catch(Exception e) { Console.WriteLine("nfsd error:{0}", e); packer.setUint32((uint)NFSStatus.NFSERR_IO); } }
private void Write(rpcCracker cracker, rpcPacker packer) { fhandle fh = new fhandle(cracker); uint beginOffset = cracker.get_uint32(); uint offset = cracker.get_uint32(); uint totalcount = cracker.get_uint32(); Byte[] data = cracker.getData(); FileStream fs; try { fs = new FileStream(FileTable.LookupFileEntry(fh).Name, FileMode.Open, FileAccess.Write); } catch (System.IO.FileNotFoundException) { FileTable.Remove(fh); throw; } try { fs.Position = offset; fs.Write(data, 0, data.Length); attrstat.PackSuccess(packer, new fattr(fh)); } finally { fs.Close(); } }
public void Pack(rpcPacker packer) { packer.setUint32(seconds); packer.setUint32(useconds); }