SMB server written in Go
This document is laying out a plan for implementing an SMB server entirely in Go.
- Transpile existing implementation to Go
- Hand port existing implementation to Go
- Build Go implementation from scratch using existing Go libraries
- The most likely solution : some combination of the above
- https://en.wikipedia.org/wiki/Server_Message_Block
- https://en.wikipedia.org/wiki/NetBIOS
- https://www.samba.org/ftp/tridge/misc/french_cafe.txt
- https://www.samba.org/ftp/samba/specs/
- TODO: more here
- SMB can run on TCP without NETBIOS. I can't find a Go NETBIOS library, so it may be easier without it.
- TODO: more here
Impacket is interesting for a few of reasons.
- Its written in Python and the Grumpy transpiler is well known.
- Impacket was authored for pen-testing and has some other interesting protocols / code.
- The Python grammar is well documented.
Initial attempts at transpiling via Grumpy were slow going. The codebase uses eval(), various "futures", and other features known to not work with Grumpy. No support for the crucial struct standard library.
I've generated code with go/ast before. I was able to generate Go code from the Python grammar using ANTLR4.
The volume of things it generated was a little overwhelming, and I didn't really try to understand it.
I'm wondering if goyacc might be simpler.
The impacket codebase relies heavily on struct packing.
It uses a string syntax to identify serialization characteristic and default values.
In most cases, this struct syntax ports trivially, EG:
('InputCount','<L=0')
becomes InputCount uint32
.
However, in some cases these string contain logic to be evaluated at runtime, EG:
('OutputOffset','<L=(self.SIZE + 64 + len(self["AlignPad"]) + self["InputCount"])')
I wrote an ugly hack to see what progress could be made with regular expressions only. Its a lot of work, and its probably easier to understand and reimplement than do a naive port of the code.