Example #1
0
File: conn.go Project: sakeven/ssng
// Write writes data to connection.
func (c *Conn) Write(b []byte) (n int, err error) {
	// buf = [iv] + [encrypt data]
	// [iv] exists only at beginning of connection, else [iv] is empty.
	var buf = c.writeBuf
	var encryptData = buf

	dataLen := len(b)

	if c.iv == nil {
		utils.Debugf("Write iv")
		c.writeStart = true

		dataLen += c.info.ivLen
		if dataLen > len(buf) {
			buf = make([]byte, dataLen)
		}
		iv := c.initEncStream()
		copy(buf, iv)
		encryptData = buf[c.info.ivLen:]
	} else if !c.writeStart {
		c.initEncStream()
		utils.Debugf("init enc")
		c.writeStart = true
	}

	if dataLen > len(buf) {
		buf = make([]byte, dataLen)
		encryptData = buf
	}

	c.encrypt(encryptData, b)
	return c.Conn.Write(buf[:dataLen])
}
Example #2
0
File: mika.go Project: sakeven/ssng
func (c *Mika) Read(b []byte) (n int, err error) {
	// recover() avoid panic
	var buf = c.readBuf
	// dataLen := len(b)
	if c.serverSide {
		// ------------------------------
		// | dataLen | hmac | user data |
		// ------------------------------
		// |   2     | 10   | Variable  |
		// ------------------------------
		const datePos = 12
		if _, err := io.ReadFull(c.Conn, buf[:datePos]); err != nil {
			return 0, err
		}

		dataLen := int(binary.BigEndian.Uint16(buf[:2]))
		expectedhmac := make([]byte, 10)
		copy(expectedhmac, buf[2:datePos])

		utils.Debugf("dataLen %d expected len %d", dataLen, len(b))

		if dataLen > len(b) {
			utils.Errorf("Date len %d large than b %d", dataLen, len(b))
			return 0, fmt.Errorf("Too large data")
		}

		if _, err := io.ReadFull(c.Conn, b[:dataLen]); err != nil {
			utils.Errorf("Read error %s", err)
			return 0, err
		}

		c.header.ChunkID++
		utils.Debugf("ChunkID %d, receive %d datas, expectedhmac %#v ", c.header.ChunkID, dataLen, expectedhmac)

		_, hmac := otaReqChunkAuth(c.iv, c.header.ChunkID, b[:dataLen])
		if !bytes.Equal(hmac, expectedhmac) {
			utils.Errorf("Hmac %#v mismatch with %#v, remote addr %s", hmac, expectedhmac, c.RemoteAddr())
			return 0, fmt.Errorf("Hmac mismatch")
		}
		// if dataLen > b
		// we should buffer remains.
		return dataLen, nil
	}

	return c.Conn.Read(b)
}
Example #3
0
File: conn.go Project: sakeven/ssng
// Read reads data from connection.
func (c *Conn) Read(b []byte) (n int, err error) {
	if c.iv == nil {
		utils.Debugf("Read iv")
		iv := make([]byte, c.info.ivLen)
		if _, err := io.ReadFull(c.Conn, iv); err != nil {
			return 0, err
		}

		c.initDecStream(iv)
		c.readStart = true
	} else if !c.readStart {
		c.initDecStream(c.iv)
		c.readStart = true
	}

	var buf = c.readBuf
	n, err = c.Conn.Read(buf[:len(b)])
	if err != nil {
		return
	}

	c.decrypt(b, buf[:n])
	return
}
Example #4
0
File: mika.go Project: sakeven/ssng
// Write writes data to connection.
func (c *Mika) Write(b []byte) (n int, err error) {
	buf := b
	dataLen := len(b)
	if !c.serverSide {
		// ------------------------------
		// | dataLen | hmac | user data |
		// ------------------------------
		// |   2     | 10   | Variable  |
		// ------------------------------
		c.header.ChunkID++
		// hmac := HmacSha1(append(c.iv, c.key...), b)
		// len(hmac)+dataLen = 12
		dataLen += 12

		// utils.Debugf("Send %d hmac %#v", dataLen-12, hmac)
		// utils.Debugf("Data write %#v", b)
		var hmac []byte
		buf, hmac = otaReqChunkAuth(c.iv, c.header.ChunkID, b)
		utils.Debugf("Send %d data, chunkID %d, hmac %#v", dataLen-12, c.header.ChunkID, hmac)
		// utils.Debugf("Data after write %#v", buf[12:dataLen])
	}

	return c.Conn.Write(buf[:dataLen])
}
Example #5
0
File: conn.go Project: sakeven/ssng
// Close closes connection and releases buf.
// TODO check close state to avoid close twice.
func (c *Conn) Close() error {
	leakyBuf.Put(c.writeBuf)
	leakyBuf.Put(c.readBuf)
	utils.Debugf("Connection %s closed", c.RemoteAddr())
	return c.Conn.Close()
}