func mustDecodeGSSWrapper(data []byte) (asn1.ObjectIdentifier, []byte) { must(len(data) >= 2) // GSS wrappers are optional, if they are not supplied we assume the data is KRB5 if data[0] != 0x60 { return gssKrb5Oid, data } isz := int(data[1]) data = data[2:] // Note for the long forms, the data len must be >= 0x80 anyways must(isz <= len(data)) switch { case isz == 0x84: isz = int(data[0])<<24 + int(data[1])<<16 + int(data[2])<<8 + int(data[3]) data = data[4:] case isz == 0x83: isz = int(data[0])<<16 + int(data[1])<<8 + int(data[2]) data = data[3:] case isz == 0x82: isz = int(data[0])<<8 + int(data[1]) data = data[2:] case isz == 0x81: isz = int(data[0]) data = data[1:] case isz <= 0x7F: // short length form default: panic(ErrProtocol) } must(0 <= isz && isz <= len(data)) data = data[:isz] oid := asn1.ObjectIdentifier{} data, err := asn1.Unmarshal(data, &oid) if err != nil { panic(err) } return oid, data }
func getresult(rw io.ReadWriter, param string, res *result) error { // We need to be careful about only reading the response and no more // so this can work with start tls var b []byte var err error var de, he int if b, err = readExactly(rw, b, 2); err != nil { return err } if he, err = headerEnd(b); err != nil { return err } if b, err = readExactly(rw, b, he); err != nil { return err } if de, err = dataEnd(b); err != nil { return err } if b, err = readExactly(rw, b, de); err != nil { return err } msg := message{} if _, err := asn1.Unmarshal(b, &msg); err != nil { return err } if msg.Id != 0 { return ErrProtocol } if _, err := asn1.UnmarshalWithParams(msg.Data.FullBytes, res, param); err != nil { return err } return nil }
// TODO: figure out better routing of read errors func (db *DB) rxThread(rw io.ReadWriter, conn net.Conn) { defer func() { conn.Close() db.lk.Lock() if db.conn == conn { db.conn = nil db.rw = nil } db.lk.Unlock() }() var b []byte for { var err error var he, de int if b, err = readAtLeast(rw, b, 2); err != nil { return } if he, err = headerEnd(b); err != nil { return } if b, err = readAtLeast(rw, b, he); err != nil { return } if de, err = dataEnd(b[:he]); err != nil { return } if b, err = readAtLeast(rw, b, de); err != nil { return } msg := message{} if _, err := asn1.Unmarshal(b, &msg); err != nil { return } if msg.Data.Class != classApplication { return } db.lk.Lock() reply := db.replies[msg.Id] db.lk.Unlock() if reply != nil { switch reply.onReply(msg.Data.Tag, msg.Data.FullBytes) { case finished: db.lk.Lock() delete(db.replies, msg.Id) db.lk.Unlock() case abandon: db.lk.Lock() delete(db.replies, msg.Id) id := db.nextId db.nextId++ db.lk.Unlock() data := mustMarshal(abandonRequest(msg.Id), abandonRequestParam) msg := message{ Id: id, Data: asn1.RawValue{ FullBytes: data, }, } if _, err := rw.Write(mustMarshal(msg, "")); err != nil { return } } } // Note don't overwrite the early part of the buffer as the // handler may still be referencing it. EG []byte members in a // SearchTree result. b = b[de:] } }