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 }
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 }
// 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 }
// Implements the h0tb0x transfer protocol func (this *LockedIdentity) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
// Implements the h0tb0x transfer protocol func (this *EncryptedKey) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
// Implements the h0tb0x transfer protocol func (this *SKSignature) Decode(stream io.Reader) error { return transfer.Decode(stream, &this.impl) }
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() }