add burn operation to the client, server, and protocol (#2)

* add burn operation to the client, server, and protocol

this provides a method for removing files from the server remotely without needing to restart the server
example use case for this is if your server is publicly accessible but you don't expose SSH publicly and you're transferring data between two cloud servers and don't want the data to be stored on the server any longer than it has to be

* updating documentation
This commit was merged in pull request #2.
This commit is contained in:
Jason Fowler
2025-04-25 14:21:43 +08:00
committed by GitHub
parent b2c6f313bc
commit a1e3c205f9
6 changed files with 224 additions and 71 deletions

View File

@@ -129,7 +129,7 @@ func (s *SecureConnection) Write(p []byte) (int, error) {
var nonce [24]byte
// Create a new nonce for each message sent
rand.Read(nonce[:])
_, _ = rand.Read(nonce[:])
encryptedMessage := box.SealAfterPrecomputation(nil, p, &nonce, s.SharedKey)
sm := SecureMessage{Msg: encryptedMessage, Nonce: nonce}
@@ -145,10 +145,10 @@ func Handshake(conn *net.TCPConn) *[32]byte {
publicKey, privateKey, _ := box.GenerateKey(rand.Reader)
conn.Write(publicKey[:])
_, _ = conn.Write(publicKey[:])
peerKeyArray := make([]byte, 32)
conn.Read(peerKeyArray)
_, _ = conn.Read(peerKeyArray)
copy(peerKey[:], peerKeyArray)
box.Precompute(&sharedKey, &peerKey, privateKey)
@@ -162,10 +162,11 @@ const (
OperationTypeSend OperationTypeEnum = iota
OperationTypeList
OperationTypeReceive
OperationTypeBurn
)
// PacketStartRequest is sent from the client to the server at the beginning
// to authenticate and annonce the requested particular operation
// to authenticate and announce the requested particular operation
type PacketStartRequest struct {
OperationType OperationTypeEnum
ClientName string
@@ -233,3 +234,20 @@ type PacketListData struct {
Timestamp time.Time
Kind string
}
type PacketBurnRequest struct {
Id uint32
}
type PacketBurnResponse struct {
Status PacketBurnResponseEnum
}
type PacketBurnResponseEnum byte
const (
// File has been deleted
BurnResponseOK PacketBurnResponseEnum = iota
// No such file by index
BurnResponseNotFound
)

View File

@@ -13,7 +13,8 @@ func TestBasic(t *testing.T) {
srcSecConn := SecureConnection{
Conn: srcConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -23,7 +24,8 @@ func TestBasic(t *testing.T) {
dstSecConn := SecureConnection{
Conn: dstConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -45,7 +47,7 @@ func TestBasic(t *testing.T) {
for _, b := range testData {
go func() {
srcSecConn.Write(b)
_, _ = srcSecConn.Write(b)
}()
time.Sleep(time.Second)
@@ -70,7 +72,8 @@ func TestPacketBasic(t *testing.T) {
srcSecConn := SecureConnection{
Conn: srcConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -80,7 +83,8 @@ func TestPacketBasic(t *testing.T) {
dstSecConn := SecureConnection{
Conn: dstConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -97,10 +101,12 @@ func TestPacketBasic(t *testing.T) {
ProtocolVersion: "1.1",
AuthToken: "abc123",
}
go func() { enc.Encode(packet) }()
go func() {
_ = enc.Encode(packet)
}()
recvPacket := PacketStartRequest{}
dec.Decode(&recvPacket)
_ = dec.Decode(&recvPacket)
if recvPacket.OperationType != OperationTypeReceive {
t.Error("bad OperationType")
@@ -117,7 +123,6 @@ func TestPacketBasic(t *testing.T) {
if recvPacket.ProtocolVersion != "1.1" {
t.Error("bad ProtocolVersion")
}
}
func BenchmarkPPS(b *testing.B) {
@@ -125,7 +130,8 @@ func BenchmarkPPS(b *testing.B) {
srcSecConn := SecureConnection{
Conn: srcConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -135,7 +141,8 @@ func BenchmarkPPS(b *testing.B) {
dstSecConn := SecureConnection{
Conn: dstConn,
SharedKey: &[32]byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
SharedKey: &[32]byte{
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
@@ -153,12 +160,11 @@ func BenchmarkPPS(b *testing.B) {
for i := 0; i < b.N; i++ {
go func() {
srcSecConn.Write(testdata)
_, _ = srcSecConn.Write(testdata)
}()
out := make([]byte, 16384)
n, err := dstSecConn.Read(out)
if err != nil {
b.Errorf("got error %v", err)
}
@@ -169,5 +175,4 @@ func BenchmarkPPS(b *testing.B) {
b.Errorf("%v not equal to %v", out[:n], testdata)
}
}
}