Exemple #1
0
func (this *SyncMgr) onNotify(remote int, fp *crypto.Digest, in io.Reader, out io.Writer) error {
	var mesgs []dataMesg
	err := transfer.Decode(in, &mesgs)
	if err != nil {
		return err
	}

	// Find client
	this.cmut.Lock()
	cl, ok := this.clients[fp.String()]
	this.cmut.Unlock()

	if !ok {
		this.Log.Printf("Receiving notify from non-friend, ignoring")
	}

	for _, mesg := range mesgs {
		this.Log.Printf("Received data, topic = %s, key = %s", mesg.Topic, mesg.Key)
		row := this.Db.SingleQuery(`SELECT heard_seqno FROM TopicFriend 
					WHERE topic = ? AND friend_id = ? AND desired = 1`,
			mesg.Topic, remote)
		var prev_seq int
		if !this.Db.MaybeScan(row, &prev_seq) {
			continue
		}
		sink, ok := this.sinks[mesg.RecordType]
		if !ok || prev_seq >= mesg.Seqno {
			continue
		}
		sink(cl.friendId, fp, &mesg.Record)
		this.Db.Exec("Update TopicFriend SET heard_seqno = ? WHERE topic = ? AND friend_id = ?",
			mesg.Seqno, mesg.Topic, remote)
	}
	return nil
}
Exemple #2
0
func (this *DataMgr) onDataGet(who int, ident *crypto.Digest, in io.Reader, out io.Writer) error {
	// TODO: Fix security hole where people can determine which blobs I have
	var key string
	err := transfer.Decode(in, &key)
	if err != nil {
		return err
	}

	this.lock.Lock()
	obj := this.maybeGetObj(key)
	if obj == nil || obj.State != DSLocal {
		this.lock.Unlock()
		fmt.Errorf("Unknown blob: %s", key)
	}
	obj.Holds++
	this.writeObj(obj)
	this.lock.Unlock()

	name := path.Join(this.dir, key)
	file, err := os.Open(name)
	if err == nil {
		_, err = io.Copy(out, file)
	}

	this.lock.Lock()
	obj = this.getObj(key)
	obj.Holds--
	this.writeObj(obj)
	this.lock.Unlock()

	return err
}
Exemple #3
0
// Implements the h0tb0x transfer protocol
func (this *PublicIdentity) Decode(stream io.Reader) error {
	var data []byte
	transfer.Decode(stream, &data)
	pub, err := x509.ParsePKIXPublicKey(data)
	if err != nil {
		return err
	}
	rsakey, ok := pub.(*rsa.PublicKey)
	if !ok {
		return fmt.Errorf("Public key in decode was not RSA")
	}
	this.key = rsakey
	return nil
}
Exemple #4
0
// Implements the h0tb0x transfer protocol
func (this *LockedIdentity) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
Exemple #5
0
// Implements the h0tb0x transfer protocol
func (this *EncryptedKey) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
Exemple #6
0
// Implements the h0tb0x transfer protocol
func (this *SKSignature) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
Exemple #7
0
func main() {
	user, err := user.Current()
	if err != nil {
		fatal("Current user is invalid", err)
	}

	defaultDir := path.Join(user.HomeDir, DefaultDir)

	dir := flag.String("d", defaultDir, "The directory your h0tb0x stuff lives in")
	flag.Parse()
	if *dir == "" {
		fatal("Directory option is required", nil)
	}

	cfgFilename := path.Join(*dir, ConfigFilename)
	dbFilename := path.Join(*dir, DbFilename)
	idFilename := path.Join(*dir, IdFilename)
	dataDir := path.Join(*dir, "data")

	var config *Config
	var thedb *db.Database
	var ident *crypto.SecretIdentity
	if fi, err := os.Stat(*dir); err == nil && fi.IsDir() {
		pass1, err := gopass.GetPass("Please enter your h0tb0x password: "******"", err)
		}
		configFile, err := os.Open(cfgFilename)
		if err != nil {
			fatal("", err)
		}
		dec := json.NewDecoder(configFile)
		err = dec.Decode(&config)
		if err != nil {
			fatal("", err)
		}
		configFile.Close()
		identFile, err := os.Open(idFilename)
		if err != nil {
			fatal("", err)
		}
		var lockedId *crypto.LockedIdentity
		err = transfer.Decode(identFile, &lockedId)
		if err != nil {
			fatal("", err)
		}
		ident, err = crypto.UnlockSecretIdentity(lockedId, pass1)
		if err != nil {
			fatal("", err)
		}
		thedb = db.NewDatabase(dbFilename)
	} else {
		fmt.Println("Making a *NEW* h0tb0x config")
		err = os.MkdirAll(*dir, 0700)
		if err != nil {
			fatal("", err)
		}
		pass1, err := gopass.GetPass("Please enter the new password for your h0tb0x: ")
		if err != nil {
			fatal("", err)
		}
		pass2, err := gopass.GetPass("Re-enter your password: "******"", err)
		}
		if pass1 != pass2 {
			fmt.Println("Passwords don't match, go away")
			return
		}
		config = &Config{
			ApiPort:  DefaultApiPort,
			LinkPort: DefaultLinkPort,
		}
		configFile, err := os.Create(cfgFilename)
		if err != nil {
			fatal("", err)
		}
		enc := json.NewEncoder(configFile)
		err = enc.Encode(&config)
		if err != nil {
			fatal("", err)
		}
		configFile.Close()
		thedb = db.NewDatabase(dbFilename)
		thedb.Install()
		ident = crypto.NewSecretIdentity(pass1)
		identFile, err := os.Create(idFilename)
		if err != nil {
			fatal("", err)
		}
		_, err = identFile.Write(transfer.AsBytes(ident.Lock()))
		if err != nil {
			fatal("", err)
		}
	}

	extHost, extPort := GetExternalAddr(config.LinkPort)

	base := &base.Base{
		Log:   log.New(os.Stderr, "h0tb0x", log.LstdFlags),
		Db:    thedb,
		Ident: ident,
		Port:  config.LinkPort,
	}

	link := link.NewLinkMgr(base)
	sync := sync.NewSyncMgr(link)
	meta := meta.NewMetaMgr(sync)
	data := data.NewDataMgr(dataDir, meta)
	api := api.NewApiMgr(extHost.String(), extPort, config.ApiPort, data)
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, os.Interrupt, os.Kill)
	api.Run()
	<-ch
	fmt.Fprintf(os.Stderr, "\n")
	api.Stop()
}