Ejemplo n.º 1
0
// Creates a collection with a specific uniq element, used for friend collections
func (this *MetaMgr) CreateSpecialCollection(owner *crypto.SecretIdentity, uniq *crypto.Digest) (cid string) {
	pubkey := owner.Public()

	cb := &collectionBasis{
		Uniq:  uniq,
		Owner: pubkey,
	}
	cid = crypto.HashOf(cb.Owner.Fingerprint(), cb.Uniq).String()

	existing := this.SyncMgr.Get(sync.RTBasis, cid, "$")
	if existing != nil {
		return cid
	}

	basis := &sync.Record{
		RecordType: sync.RTBasis,
		Topic:      cid,
		Key:        "$",
		Author:     pubkey.Fingerprint().String(),
		Value:      transfer.AsBytes(cb),
	}
	signRecord(basis, owner)
	this.SyncMgr.Put(basis)

	owr := &sync.Record{
		RecordType: sync.RTWriter,
		Topic:      cid,
		Key:        pubkey.Fingerprint().String(),
		Value:      transfer.AsBytes(pubkey),
	}
	signRecord(owr, owner)
	this.SyncMgr.Put(owr)

	return
}
Ejemplo n.º 2
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)
}
Ejemplo n.º 3
0
func (this *ApiMgr) getSelf(w http.ResponseWriter, req *http.Request) {
	myFp := this.Ident.Public().Fingerprint()
	myCid := crypto.HashOf(myFp, myFp).String()
	json := SelfJson{
		Id:      myFp.String(),
		Host:    this.ExtHost,
		Port:    this.ExtPort,
		SelfCid: myCid,
	}
	this.sendJson(w, json)
}
Ejemplo n.º 4
0
func (this *SyncMgr) onFriendChange(id int, fp *crypto.Digest, what link.FriendStatus) {
	this.cmut.Lock()
	if what == link.FriendStartup || what == link.FriendAdded {
		this.Log.Printf("Adding friend: %s", fp.String())
		myFp := this.Ident.Public().Fingerprint()
		this.Db.Exec("INSERT OR IGNORE INTO TopicFriend (topic, friend_id, desired, requested) VALUES (?, ?, ?, ?)",
			crypto.HashOf(fp, myFp).String(), id, 1, 1)
		this.Db.Exec("INSERT OR IGNORE INTO TopicFriend (topic, friend_id, desired, requested) VALUES (?, ?, ?, ?)",
			crypto.HashOf(myFp, fp).String(), id, 1, 1)
		cl := newClientLooper(this, id)
		this.clients[fp.String()] = cl
		cl.run()
	} else {
		cl := this.clients[fp.String()]
		cl.stop()
		delete(this.clients, fp.String())
		this.Db.Exec("DELETE INTO TopicFriend WHERE friend_id = ?", id)
	}
	this.cmut.Unlock()
}
Ejemplo n.º 5
0
func (this *LinkMgr) UpdateIsGd(fi *friendInfo) {
	theHash := crypto.HashOf(fi.fingerprint, fi.isgdid)
	this.Log.Printf("Trying to update isGd for %s, id = %d", fi.fingerprint.String(), fi.isgdid)
	isgdurl := "http://is.gd/forward.php?format=json&shorturl=" + theHash.String()[0:24]
	this.Log.Printf("Doing get of: %s", isgdurl)
	resp, err := http.Get(isgdurl)
	this.Log.Printf("Get has returned")
	if err != nil {
		this.Log.Printf("Failed to do get of: %s", "http://is.gd/forward.php?format=json&shorturl="+theHash.String())
		return
	}
	if resp.StatusCode != http.StatusOK {
		this.Log.Printf("Status not OK")
		return
	}
	dec := json.NewDecoder(resp.Body)
	var gd isGdJson
	err = dec.Decode(&gd)
	if err != nil {
		this.Log.Printf("Unable to decode")
		return
	}
	url, err := url.Parse(gd.Url)
	if err != nil {
		this.Log.Printf("Unable to parse as URL: '%s'", gd.Url)
		return
	}
	var ip1, ip2, ip3, ip4 int
	var port int
	_, err = fmt.Sscanf(url.Host, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip3, &port)
	if err != nil {
		this.Log.Printf("Unable to parse as host: '%s': %v", url.Host, err)
		return
	}
	host := fmt.Sprintf("%d.%d.%d.%d", ip1, ip2, ip3, ip4)
	this.Log.Printf("Updating %s to %s:%d", fi.fingerprint.String(), host, port)
	fi.host = host
	fi.port = uint16(port)
	fi.isgdid++
	this.Db.Exec("UPDATE Friend SET host = ?, port = ?, isgdid = ? WHERE id = ?",
		host, port, fi.isgdid, fi.id)

}
Ejemplo n.º 6
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
}
Ejemplo n.º 7
0
// Update the subscription state for a topic on a particular friend.
func (this *SyncMgr) Subscribe(id *crypto.Digest, topic string, enable bool) bool {
	this.cmut.RLock()
	client, ok := this.clients[id.String()]
	this.cmut.RUnlock()
	if !ok {
		return false
	}

	client.lock.Lock()
	this.Db.Exec("INSERT OR IGNORE INTO TopicFriend (friend_id, topic) VALUES (?, ?)",
		client.friendId, topic)

	this.Db.Exec("UPDATE TopicFriend SET desired = ? WHERE friend_id = ? AND topic = ?",
		enable, client.friendId, topic)

	row := this.Db.SingleQuery("SELECT heard_seqno FROM TopicFriend WHERE friend_id = ? AND topic = ?",
		client.friendId, topic)
	var heard int
	this.Db.Scan(row, &heard)

	enbyte := byte(0)
	if enable {
		enbyte = 1
	}
	myFp := this.Ident.Public().Fingerprint()
	client.lock.Unlock()
	this.Put(&Record{
		RecordType: RTSubscribe,
		Topic:      crypto.HashOf(myFp, id).String(),
		Key:        topic,
		Value:      []byte{enbyte},
		Priority:   heard,
		Author:     "$",
	})

	return true
}
Ejemplo n.º 8
0
func (this *ApiMgr) populateFriend(json *FriendJson, myFp, fp *crypto.Digest) {
	json.Id = fp.String()
	json.SelfCid = crypto.HashOf(fp, fp).String()
	json.SendCid = crypto.HashOf(myFp, fp).String()
	json.RecvCid = crypto.HashOf(fp, myFp).String()
}
Ejemplo n.º 9
0
// Creates a new collection with a specific owner, no writers (except owner), and no data.
func (this *MetaMgr) CreateNewCollection(owner *crypto.SecretIdentity) (cid string) {
	uniq := make([]byte, 16)
	io.ReadFull(rand.Reader, uniq)
	return this.CreateSpecialCollection(owner, crypto.HashOf(uniq))
}
Ejemplo n.º 10
0
func signRecord(rec *sync.Record, writer *crypto.SecretIdentity) {
	hash := crypto.HashOf(rec.RecordType, rec.Topic, rec.Key, rec.Value, rec.Priority)
	sig := writer.Sign(hash)
	rec.Author = writer.Fingerprint().String()
	rec.Signature = transfer.AsBytes(sig)
}