// Reads from io.Reader and generates a new object, put it to the meta-data layer func (this *DataMgr) GetData(topic string, key string, stream io.Writer) error { data := this.Get(topic, key) if data == nil { return fmt.Errorf("Unknown key") } var objHash *crypto.Digest err := transfer.DecodeBytes(data, &objHash) if err != nil { return err } okey := objHash.String() this.lock.Lock() obj := this.maybeGetObj(okey) if obj == nil || obj.State != DSLocal { return fmt.Errorf("File not local yet") } obj.Holds++ this.writeObj(obj) this.lock.Unlock() name := path.Join(this.dir, okey) file, err := os.Open(name) if err == nil { _, err = io.Copy(stream, file) } this.lock.Lock() obj = this.getObj(okey) obj.Holds-- this.writeObj(obj) this.lock.Unlock() return err }
func (this *MetaMgr) onData(who int, remote *crypto.Digest, rec *sync.Record) { this.Log.Printf("Processing Data") // Verify the basis basisRec := this.SyncMgr.Get(sync.RTBasis, rec.Topic, "$") owner := this.decodeBasis(basisRec, false) if owner == nil { this.Log.Printf("Getting record before basis, ignoring") return } // Otherwise, get the writer data var signer *crypto.PublicIdentity writerRec := this.SyncMgr.Get(sync.RTWriter, rec.Topic, rec.Author) if writerRec == nil { this.Log.Printf("Attempt to write by unauthorized writer, ignoring") return } err := transfer.DecodeBytes(writerRec.Value, &signer) if err != nil { this.Log.Printf("Error decoding writer record: %s", err) return } // Process the data record this.verifyUpdate(rec, signer) }
func verifyRecord(rec *sync.Record, writer *crypto.PublicIdentity) bool { hash := crypto.HashOf(rec.RecordType, rec.Topic, rec.Key, rec.Value, rec.Priority) var sig *crypto.Signature err := transfer.DecodeBytes(rec.Signature, &sig) if err != nil { panic(err) } return writer.Verify(hash, sig) }
func (this *MetaMgr) GetWriter(cid string, writer string) *crypto.PublicIdentity { writerRec := this.SyncMgr.Get(sync.RTWriter, cid, writer) if writerRec == nil { return nil } var writerKey *crypto.PublicIdentity err := transfer.DecodeBytes(writerRec.Value, &writerKey) if err != nil { return nil } return writerKey }
func (this *ApiMgr) getFriends(w http.ResponseWriter, req *http.Request) { myFp := this.Ident.Public().Fingerprint() rows := this.Db.MultiQuery("SELECT fingerprint, host, port FROM Friend") out := []FriendJson{} for rows.Next() { var json FriendJson var fpb []byte this.Db.Scan(rows, &fpb, &json.Host, &json.Port) var fp *crypto.Digest transfer.DecodeBytes(fpb, &fp) this.populateFriend(&json, myFp, fp) out = append(out, json) } this.sendJson(w, out) }
// Return a deserialized object, or nil if none func (this *DataMgr) maybeGetObj(key string) *DataObj { //this.Log.Printf("Getting Object: %s", key) row := this.Db.SingleQuery("SELECT data FROM Blob WHERE key=?", key) var data []byte if this.Db.MaybeScan(row, &data) { var obj *DataObj //this.Log.Printf("Found Object: %s, data = %v", key, data) err := transfer.DecodeBytes(data, &obj) if err != nil { panic(err) } obj.mgr = this return obj } return nil }
// Kicks off the link manager, presumes Callbacks has been set func (this *LinkMgr) Run() error { conn, err := net.Listen("tcp", this.server.Addr) if err != nil { return err } this.listener = tls.NewListener(conn, this.server.TLSConfig) rows := this.Db.MultiQuery("SELECT id, fingerprint, isgdid, host, port FROM Friend") for rows.Next() { var id int var isgdid int var fp []byte var host string var port uint16 this.Db.Scan(rows, &id, &fp, &isgdid, &host, &port) var fingerprint *crypto.Digest err := transfer.DecodeBytes(fp, &fingerprint) if err != nil { panic(err) } fi := &friendInfo{ id: id, fingerprint: fingerprint, isgdid: isgdid, host: host, port: port, } this.friendsFp[fingerprint.String()] = fi this.friendsId[id] = fi } this.cmut.RLock() for id, fi := range this.friendsId { for _, f := range this.listeners { f(id, fi.fingerprint, FriendStartup) } } this.cmut.RUnlock() this.wait.Add(1) go func() { this.server.Serve(this.listener) this.wait.Done() }() return nil }
func (this *DataMgr) onMeta(topic string, key string, data []byte, fp string, isUp bool) { var objHash *crypto.Digest err := transfer.DecodeBytes(data, &objHash) if err != nil { this.Log.Printf("Unable to decode meta-data value") return } objKey := objHash.String() this.lock.Lock() defer this.lock.Unlock() obj := this.getObj(objKey) if isUp { obj.metaUp(topic) } else { obj.metaDown(topic) } this.writeObj(obj) }
// Checks if basis record is valid, if so, returns owner ID, otherwise nil func (this *MetaMgr) decodeBasis(rec *sync.Record, check bool) *crypto.PublicIdentity { var cb *collectionBasis if rec == nil { return nil } err := transfer.DecodeBytes(rec.Value, &cb) if err != nil { this.Log.Printf("Unable to decode basis: %s", err) return nil } if check { cid := crypto.HashOf(cb.Owner.Fingerprint(), cb.Uniq).String() if cid != rec.Topic { this.Log.Printf("Basis hash mismatch: %s vs %s", cid, rec.Topic) return nil } } return cb.Owner }
func (this *MetaMgr) onWriter(who int, remote *crypto.Digest, rec *sync.Record) { this.Log.Printf("Processing Writer") // Verify the basis basisRec := this.SyncMgr.Get(sync.RTBasis, rec.Topic, "$") owner := this.decodeBasis(basisRec, false) if owner == nil { this.Log.Printf("Getting record before basis, ignoring") return } // Validate the incoming writer record is valid var checkit *crypto.PublicIdentity err := transfer.DecodeBytes(rec.Value, &checkit) if err != nil { this.Log.Printf("Writer record is misformed: %s", err) return } if checkit.Fingerprint().String() != rec.Key { this.Log.Printf("Writer record is misformed, key != hash") return } this.verifyUpdate(rec, owner) }