package hook import ( "crypto/aes" "crypto/cipher" "crypto/md5" "crypto/rand" "io" "tunnel/pkg/server/env" "tunnel/pkg/server/queue" ) type aesHook struct{} type aesPipe struct { key []byte } func (a *aesPipe) Send(rq, wq queue.Q) error { block, err := aes.NewCipher(a.key) if err != nil { return err } iv := make([]byte, aes.BlockSize) if _, err := rand.Read(iv); err != nil { return err } writer := &cipher.StreamWriter{ S: cipher.NewOFB(block, iv), W: wq.Writer(), } wq <- iv return queue.IoCopy(rq.Reader(), writer) } func (a *aesPipe) Recv(rq, wq queue.Q) error { block, err := aes.NewCipher(a.key) if err != nil { return err } r := rq.Reader() iv := make([]byte, aes.BlockSize) if _, err := io.ReadFull(r, iv); err != nil { if err == io.EOF { return nil } return err } reader := &cipher.StreamReader{ S: cipher.NewOFB(block, iv), R: r, } return queue.IoCopy(reader, wq.Writer()) } func (aesHook) New(env env.Env) (interface{}, error) { s := env.Value("secret") h := md5.Sum([]byte(s)) a := &aesPipe{key: make([]byte, 16)} copy(a.key, h[:]) return a, nil } func init() { register("aes", aesHook{}) }