Beispiel #1
0
// 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
}
Beispiel #2
0
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)
}
Beispiel #3
0
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)
}
Beispiel #4
0
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
}
Beispiel #5
0
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)
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
0
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)
}
Beispiel #9
0
// 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
}
Beispiel #10
0
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)
}