// Put stores a message in the message store WITHOUT notifying the notify backend func (store Store) Put(msgStruct *structs.MessageStruct, signerStruct *structs.SignerStruct, message []byte) error { // Check if message exists if store.db.MessageKnown(&msgStruct.MessageID) { return ErrDuplicate } // Check if signer exists, load last from signer _, signerLoaded, _ := store.db.SelectSigner(&signerStruct.PublicKey) if signerLoaded != nil { // Old signer is better if signerLoaded.Bits > signerStruct.Bits { signerStruct.Bits = signerLoaded.Bits signerStruct.Nonce = signerLoaded.Nonce signerStruct.MaxMessagesPosted = signerLoaded.MaxMessagesPosted signerStruct.MaxMessagesRetained = signerLoaded.MaxMessagesRetained } // Update post data signerStruct.MessagesPosted = signerLoaded.MessagesPosted signerStruct.MessagesRetained = signerLoaded.MessagesRetained } // Verify signer if signerStruct.MessagesPosted >= signerStruct.MaxMessagesPosted { return ErrPostLimit } if signerStruct.MessagesRetained >= signerStruct.MaxMessagesRetained { // Retention is changed by expiring messages return ErrPostLimit } msgStruct.PostTime = uint64(CurrentTime()) msgStruct.ExpireTime = uint64(uint64(CurrentTime()) + signerStruct.ExpireTarget) if msgStruct.ExpireTime < msgStruct.ExpireRequest { msgStruct.ExpireTime = msgStruct.ExpireRequest } // Update signer err := store.db.InsertOrUpdateSigner(signerStruct) if err != nil { log.Errorf("messagestore, update signer: %s", err) } // Write message. Message is prefixed by encoded messageStruct storeID, err := store.db.InsertMessage(msgStruct) if err != nil { log.Errorf("messagestore, write message (DB): %s", err) return err } store.db.LearnMessage(&msgStruct.MessageID) err = store.db.InsertBlob(storeID, &msgStruct.MessageID, &signerStruct.PublicKey, msgStruct.OneTime, message) if err != nil { log.Errorf("messagestore, write message (Blob): %s", err) return err } if !msgStruct.OneTime && msgStruct.Sync { err := store.db.AddToGlobalIndex(storeID) if err != nil { log.Errorf("messagestore, globalindex append: %s", err) } } return nil }
// GetNotify receives notifications. func (ms MessageServer) GetNotify(w http.ResponseWriter, r *http.Request) { var proof [keyproof.ProofTokenSize]byte w.Header().Set("Content-Type", "text/plain; charset=us-ascii") getValues := r.URL.Query() if getValues != nil { if v, ok := getValues["auth"]; ok { if len(v[0]) > keyproof.ProofTokenMax { io.WriteString(w, "ERROR: Bad Param\n") return } auth := utils.B58decode(v[0]) if auth == nil || len(auth) > keyproof.ProofTokenSize { io.WriteString(w, "ERROR: Bad Param\n") return } copy(proof[:], auth) ok, timeStamp, senderPubKey := keyproof.VerifyProofToken(&proof, ms.TokenPubKey) if !ok { io.WriteString(w, "ERROR: Authentication failure\n") if senderPubKey == nil { log.Errorf("VerifyProofToken failed: (proof) %s\n", utils.B58encode(proof[:])) } else { log.Errorf("VerifyProofToken failed: (pubkey) %s\n", utils.B58encode(senderPubKey[:])) } return } // verify that we know the peer url := ms.PeerURL(senderPubKey) if url == "" { io.WriteString(w, "ERROR: Bad peer\n") log.Errorf("Notify, bad peer: %s\n", utils.B58encode(senderPubKey[:])) return } now := CurrentTime() // Test too old, too young if enforceTimeOuts && (now > timeStamp+DefaultAuthTokenAge+ms.MaxTimeSkew || now < timeStamp-DefaultAuthTokenAge-ms.MaxTimeSkew) { io.WriteString(w, "ERROR: Authentication expired\n") log.Errorf("VerifyProofToken replay by %s\n", url) return } ok, signedToken := keyproof.CounterSignToken(&proof, ms.TokenPubKey, ms.TokenPrivKey) if !ok { io.WriteString(w, "ERROR: Authentication failure\n") return } ms.DB.UpdatePeerAuthToken(senderPubKey, signedToken) log.Debugf("Notified by %s\n", url) io.WriteString(w, "SUCCESS: Notified\n") return } } io.WriteString(w, "ERROR: Missing Param\n") return }
// LoadPeers from file. func (ms MessageServer) LoadPeers() { var prePeerlist PeerListEncoded var myPeerURLs []string myPeers := make(PeerList) peersEncoded, err := ioutil.ReadFile(ms.PeerFile) if err != nil { example := make(PeerListEncoded, 1) example[0].PubKey = "Example ed25519 public key encoded in base58" example[0].URL = exampleURL dat, _ := json.MarshalIndent(example, "", " ") _ = dat err := ioutil.WriteFile(ms.PeerFile, dat, 0600) if err != nil { log.Errorf("Could not write peerfile: %s\n", err) return } log.Debugs("Example peerfile written\n") return } err = json.Unmarshal(peersEncoded, &prePeerlist) if err != nil { log.Errorf("Could not read peerfile: %s\n", err) return } if ms.AddToPeer && !ms.HubOnly { myPeerURLs = append(myPeerURLs, ms.URL) } for _, p := range prePeerlist { if p.URL != exampleURL { var tkey [ed25519.PublicKeySize]byte t := utils.B58decode(p.PubKey) copy(tkey[:], t) if *ms.TokenPubKey != tkey || debug { myPeers[tkey] = Peer{ URL: p.URL, PubKey: tkey, } if !p.IsHub { myPeerURLs = append(myPeerURLs, p.URL) } // Create Peer Index File ms.DB.TouchPeer(&tkey) } } } defer ms.setPeerURLs(myPeerURLs) systemPeersMutex.Lock() defer systemPeersMutex.Unlock() systemPeers = myPeers log.Debugs("Peers loaded\n") }
// GetPeerStat returns the last entry of peer statistics for pubkey func (store Store) GetPeerStat(pubkey *[ed25519.PublicKeySize]byte) *structs.PeerStruct { if store.peersindex.Index(pubkey[:]).Exists() { last := store.peersindex.Index(pubkey[:]).GetLast() if last == nil { log.Errorf("Peer last nil: %x\n", *pubkey) return nil } peerStat := structs.PeerStructDecode(last) if peerStat == nil { log.Errorf("Peer stat nil: %x\n", *pubkey) return nil } return peerStat } return nil }
// GetPeerStat returns the last entry of peer statistics for pubkey func (store Store) GetPeerStat(pubkey *[ed25519.PublicKeySize]byte) *structs.PeerStruct { st, err := store.db.SelectPeer(pubkey) if err != nil { log.Errorf("GetPeerStat: %s, %s\n", err, utils.B58encode(pubkey[:])) return nil } return st }
// LoadConfigFile loads configuration from a file func LoadConfigFile(file string) (conf ConfigVariables, err error) { data, err := utils.MaxReadFile(409600, file) if err != nil { log.Errorf("Cannot load config from file: %s\n", file) return conf, err } if err := json.Unmarshal(data, &conf); err != nil { return conf, err } return conf, nil }
// UpdatePeerAuthToken updates the peer record when a new auth token has been received func (store Store) UpdatePeerAuthToken(senderPubKey *[ed25519.PublicKeySize]byte, signedToken *[keyproof.ProofTokenSignedSize]byte) { if store.peersindex.Index(senderPubKey[:]).Exists() { store.peersindex.Index(senderPubKey[:]).Update(func(tx fileback.Tx) error { last := tx.GetLast() if last == nil { log.Errorf("Peer last nil: %x\n", *senderPubKey) return nil } peerStat := structs.PeerStructDecode(last) if peerStat == nil { log.Errorf("Peer stat nil: %x\n", *senderPubKey) return nil } peerStat.LastNotifyFrom = uint64(time.Now().Unix()) peerStat.AuthToken = *signedToken tx.Append(peerStat.Encode().Fill()) return nil }) } }
// Delete implements the delete call for messages. func (ms MessageServer) Delete(w http.ResponseWriter, r *http.Request) { var messageID *[message.MessageIDSize]byte var privateKey *message.Curve25519Key for i := 0; i < 4; i++ { ms.RandomSleep() // Let's not give instant gratification here } w.Header().Set("Content-Type", "text/plain; charset=us-ascii") getValues := r.URL.Query() if getValues != nil { if v, ok := getValues["messageid"]; ok { t := utils.B58decode(v[0]) if len(t) < message.MessageIDSize || len(t) > message.MessageIDSize { io.WriteString(w, "ERROR: Bad parameter\n") return } messageID = new([message.MessageIDSize]byte) copy(messageID[:], t) } if v, ok := getValues["privkey"]; ok { t := utils.B58decode(v[0]) if len(t) < message.Curve25519KeySize || len(t) > message.Curve25519KeySize { io.WriteString(w, "ERROR: Bad parameter\n") return } privateKey = new(message.Curve25519Key) copy(privateKey[:], t) } if privateKey != nil && messageID != nil { publicKey := message.GenPubKey(privateKey) err := ms.DB.PreExpire(messageID, publicKey) if err == nil { log.Errorf("Message censored: %x, asshole.\n", *messageID) io.WriteString(w, "SUCCESS: If you want to call it that\n") return } log.Errorf("Message censoring failed! %s\n", err) } } io.WriteString(w, "ERROR: Missing parameters\n") return }
// UpdatePeerFetchStat writes fetch-specific data func (store Store) UpdatePeerFetchStat(pubkey *[ed25519.PublicKeySize]byte, lastFetch, lastPos, lastErrors uint64) { if store.peersindex.Index(pubkey[:]).Exists() { store.peersindex.Index(pubkey[:]).Update(func(tx fileback.Tx) error { last := tx.GetLast() if last == nil { log.Errorf("Peer last nil: %x\n", *pubkey) return nil } peerStat := structs.PeerStructDecode(last) if peerStat == nil { log.Errorf("Peer stat nil: %x\n", *pubkey) return nil } peerStat.LastFetch = lastFetch peerStat.LastPosition = lastPos peerStat.ErrorCount = lastErrors tx.Append(peerStat.Encode().Fill()) return nil }) } }
// ExpireFromIndex reads the expire index and expires messages as they are recorded func (store Store) ExpireFromIndex() { // ExpireRun delMessages, err := store.db.SelectMessageExpire(CurrentTime()) if err != nil { log.Errorf("ExpireFromIndex, SelectMessageExpire: %s\n", err) return } for _, msg := range delMessages { err := store.db.DeleteBlob(&msg.MessageID) if err != nil { log.Errorf("ExpireFromIndex, DeleteBlob: %s %s\n", err, utils.B58encode(msg.MessageID[:])) continue } err = store.db.DeleteMessageByID(&msg.MessageID) if err != nil { log.Errorf("ExpireFromIndex, DeleteMessageByID: %s %s\n", err, utils.B58encode(msg.MessageID[:])) } } _, _, err = store.db.ExpireSigners(MaxAgeSigners) if err != nil { log.Errorf("ExpireFromIndex, ExpireSigners: %s\n", err) } err = store.db.ExpireMessageCounter(MaxAgeRecipients) if err != nil { log.Errorf("ExpireFromIndex, ExpireMessageCounter: %s\n", err) } err = store.db.ForgetMessages(CurrentTime() - MaxAgeRecipients) if err != nil { log.Errorf("ExpireFromIndex, ForgetMessages: %s\n", err) } }
// UpdatePeerNotification updates the peer stat after notification send func (store Store) UpdatePeerNotification(pubkey *[ed25519.PublicKeySize]byte, hasError bool) { if store.peersindex.Index(pubkey[:]).Exists() { store.peersindex.Index(pubkey[:]).Update(func(tx fileback.Tx) error { last := tx.GetLast() if last == nil { log.Errorf("Peer last nil: %x\n", *pubkey) return nil } peerStat := structs.PeerStructDecode(last) if peerStat == nil { log.Errorf("Peer stat nil: %x\n", *pubkey) return nil } peerStat.LastNotifySend = uint64(time.Now().Unix()) if hasError { peerStat.ErrorCount++ } tx.Append(peerStat.Encode().Fill()) return nil }) } }
// CmdGenKey generates a long-term public key func CmdGenKey() int { privkey, err := message.GenLongTermKey(OptionsVar.Hidden, OptionsVar.Sync) if err != nil { log.Errorf("Key generation error:%s\n", err) return 1 } pubkey := message.GenPubKey(privkey) log.Dataf("STATUS (PrivateKey):\t%s\n", utils.B58encode(privkey[:])) // log.Dataf("STATUS (PublicKey):\t%s\n", utils.B58encode(pubkey[:])) log.Printf("PRIVATE key: %s\n\n", utils.B58encode(privkey[:])) // log.Printf("Public key: %s\n", utils.B58encode(pubkey[:])) _ = pubkey return 0 }
// CmdSTM does an STM run to specific server and from specific stmdir func CmdSTM() int { if OptionsVar.Server == "" { log.Fatal("Server must be specified: --server\n") return 1 } if OptionsVar.Stmdir == "" { log.Fatal("Missing parameter: --stmdir\n") return 1 } if !isDir(OptionsVar.Stmdir) { log.Fatalf("stmdir does not exist or is no directory: %s\n", OptionsVar.Stmdir) return 1 } err := listSTM(OptionsVar.Stmdir) // Todo: Test if dir exists if err != nil { log.Errorf("STM Process errors: %s\n", err) return 1 } return 0 }
// CmdGenTempKey generates a temporary key for a given private key func CmdGenTempKey() int { var privkey message.Curve25519Key privkeystr := selectPrivKey(OptionsVar.Privkey, GlobalConfigVar.PrivateKey, "tty") if privkeystr == "" { log.Fatal("No private key given (-privkey)") return 1 } copy(privkey[:], utils.B58decode(privkeystr)) pubkey := message.GenPubKey(&privkey) privkeytemp, err := message.GenRandomKey() if err != nil { log.Errorf("Key generation error:%s\n", err) return 1 } pubkeytemp := message.GenPubKey(privkeytemp) log.Dataf("STATUS (PrivateKey):\t%s_%s\n", utils.B58encode(privkey[:]), utils.B58encode(privkeytemp[:])) log.Dataf("STATUS (PublicKey):\t%s_%s\n", utils.B58encode(pubkey[:]), utils.B58encode(pubkeytemp[:])) log.Printf("PRIVATE key: %s_%s\n\n", utils.B58encode(privkey[:]), utils.B58encode(privkeytemp[:])) log.Printf("Public key: %s_%s\n", utils.B58encode(pubkey[:]), utils.B58encode(pubkeytemp[:])) return 0 }
func runCommands() (retval int) { log.SetMinLevel(log.LevelPrint) if options.Appdata { log.SetMinLevel(log.LevelData) } if options.Verbose { log.SetMinLevel(log.LevelDebug) } if options.KEYVERB { log.SetMinLevel(log.LevelSecret) } usercfgfile := client.UserConfigFile() if options.Configfile != "" || usercfgfile != "" { configFile := usercfgfile if options.Configfile != "" { configFile = options.Configfile } globalconfigT, err := client.LoadConfigFile(configFile) if err == nil { globalconfig = globalconfigT } else { log.Errorf("Config file failed to load: %s\n", err) } } for k, v := range commands { if *v { if callFunc[k] != nil { client.OptionsVar = options client.GlobalConfigVar = globalconfig retval = callFunc[k]() } else { log.Fatal("Command not implemented") return 100 } log.Sync() break } } return }
func getPeers(force bool) error { log.Debugf("Peer update called. Last: %d\n", GlobalConfigVar.PeerUpdate) if GlobalConfigVar.PeerUpdate == 0 || GlobalConfigVar.PeerUpdate < (time.Now().Unix()-PeerUpdateDuration) { log.Debugs("Peer update forced. Prevent by running -peerlist.\n") force = true } if force { log.Debugs("Updating peers.\n") defer log.Debugs("Peer update done.\n") GlobalConfigVar.PeerUpdate = time.Now().Unix() server := OptionsVar.Server if server == "" && GlobalConfigVar.PasteServers != nil && len(GlobalConfigVar.PasteServers) > 0 { // no server defined, we select one servercount := len(GlobalConfigVar.PasteServers) rand.Seed(time.Now().UnixNano()) pos := rand.Int() % servercount server = GlobalConfigVar.PasteServers[pos] } if server == "" { server = GlobalConfigVar.BootStrapPeer } if server == "" { return ErrNoPeers } proto := repproto.New(OptionsVar.Socksserver, OptionsVar.Server, GlobalConfigVar.PasteServers...) serverInfo, err := proto.ID(server) if err != nil { return ErrNoPeers } if serverInfo.Peers != nil && len(serverInfo.Peers) > 0 { GlobalConfigVar.PasteServers = serverInfo.Peers GlobalConfigVar.MinHashCash = serverInfo.MinHashCashBits err := WriteConfigFile(GlobalConfigVar) if err != nil { log.Errorf("Error writing config-file: %s\n", err) } } } return nil }
// UpdatePeerAuthToken updates the peer record when a new auth token has been received func (store Store) UpdatePeerAuthToken(senderPubKey *[ed25519.PublicKeySize]byte, signedToken *[keyproof.ProofTokenSignedSize]byte) { err := store.db.UpdatePeerToken(senderPubKey, signedToken) if err != nil { log.Errorf("UpdatePeerAuthToken: %s, %s\n", err, utils.B58encode(senderPubKey[:])) } }
// Put stores a message in the message store WITHOUT notifying the notify backend func (store Store) Put(msgStruct *structs.MessageStruct, signerStruct *structs.SignerStruct, message []byte) error { // Check if message exists if store.MessageExists(msgStruct.MessageID) { return ErrDuplicate } // Check if signer exists, load last from signer signerLoaded := structs.SignerStructDecode(store.signers.Index(signerStruct.PublicKey[:]).GetLast()) if signerLoaded != nil { // Old signer is better if signerLoaded.Bits > signerStruct.Bits { signerStruct.Bits = signerLoaded.Bits signerStruct.Nonce = signerLoaded.Nonce signerStruct.MaxMessagesPosted = signerLoaded.MaxMessagesPosted signerStruct.MaxMessagesRetained = signerLoaded.MaxMessagesRetained } // Update post data signerStruct.MessagesPosted = signerLoaded.MessagesPosted signerStruct.MessagesRetained = signerLoaded.MessagesRetained } // Verify signer if signerStruct.MessagesPosted >= signerStruct.MaxMessagesPosted { return ErrPostLimit } if signerStruct.MessagesRetained >= signerStruct.MaxMessagesRetained { // Retention is changed by expiring messages return ErrPostLimit } msgStruct.PostTime = uint64(time.Now().Unix()) msgStruct.ExpireTime = uint64(uint64(time.Now().Unix()) + signerStruct.ExpireTarget) if msgStruct.ExpireTime < msgStruct.ExpireRequest { msgStruct.ExpireTime = msgStruct.ExpireRequest } // Update signer err := store.signers.Index(signerStruct.PublicKey[:]).CreateAppend(signerStruct.Encode()) // Ignore errors on signer update. They don't matter much if err != nil { log.Errorf("messagestore, update signer: %s", err) } // Write message. Message is prefixed by encoded messageStruct msgStructEncoded := msgStruct.Encode().Fill() err = store.messages.Index(msgStruct.MessageID[:]).Create(append(msgStructEncoded, message...)) if err != nil { log.Errorf("messagestore, write message: %s", err) return err } if !msgStruct.OneTime && msgStruct.Sync { // TX: Add to global index if store.keyindex.Index(globalindex).Exists() { err := store.keyindex.Index(globalindex).Update(func(tx fileback.Tx) error { // Ignore errors return updateKeyIndex(tx, msgStruct, msgStructEncoded) }) if err != nil { log.Errorf("messagestore, globalindex append: %s", err) } } else { err := store.keyindex.Index(globalindex).CreateAppend(msgStructEncoded) if err != nil { log.Errorf("messagestore, globalindex createAppend: %s", err) } } } // TX: Add to key index if store.keyindex.Index(msgStruct.ReceiverConstantPubKey[:]).Exists() { err := store.keyindex.Index(msgStruct.ReceiverConstantPubKey[:]).Update(func(tx fileback.Tx) error { // Ignore errors return updateKeyIndex(tx, msgStruct, msgStructEncoded) }) if err != nil { log.Errorf("messagestore, receiverPub append: %s", err) } } else { err := store.keyindex.Index(msgStruct.ReceiverConstantPubKey[:]).CreateAppend(msgStructEncoded) if err != nil { log.Errorf("messagestore, receiverPub createAppend: %s", err) } } // Add to expire expire := &structs.ExpireStruct{ ExpireTime: msgStruct.ExpireTime, MessageID: msgStruct.MessageID, SignerPubKey: msgStruct.SignerPub, } expireTime := (msgStruct.ExpireTime / uint64(ExpireRun)) + uint64(ExpireRun) err = store.expireindex.Index(utils.EncodeUInt64(expireTime)).CreateAppend(expire.Encode().Fill()) if err != nil { log.Errorf("messagestore, record expire: %s", err) } return nil }
// UpdatePeerNotification updates the peer stat after notification send func (store Store) UpdatePeerNotification(pubkey *[ed25519.PublicKeySize]byte, hasError bool) { err := store.db.UpdatePeerNotification(pubkey, hasError) if err != nil { log.Errorf("UpdatePeerNotification: %s, %x\n", err, *pubkey) } }
// CmdEncrypt encrypts data. func CmdEncrypt() int { var privkey, embedConstantPrivKey, embedTemporaryPrivKey, embedConstantPubKey, embedTemporaryPubKey *message.Curve25519Key var err error var inData, encMessage []byte var meta *message.MetaDataSend var signKeyPair *message.SignKeyPair var removeFile string if OptionsVar.Server == "" { getPeers(false) } // OptionsVar.anonymous . disable private key and signkey if OptionsVar.Anonymous { OptionsVar.Signkey = "" OptionsVar.Privkey = "" GlobalConfigVar.PrivateKey = "" } mindelay := uint32(OptionsVar.Mindelay) maxdelay := uint32(OptionsVar.Maxdelay) // Read input data maxInData := int64(GlobalConfigVar.BodyLength - (message.Curve25519KeySize * 2) - innerHeader) //maxInData := int64(MsgSizeLimit) if OptionsVar.Repost { maxInData -= utils.RepostHeaderSize - message.KeyHeaderSize - message.SignHeaderSize } log.Debugf("Size limit: %d\n", maxInData) inData, err = inputData(OptionsVar.Infile, maxInData) if err != nil { log.Fatalf("No input data: %s\n", err) return 1 } // Verify list contents if OptionsVar.MessageType == message.MsgTypeList { err := utils.VerifyListContent(inData) if err != nil { log.Errorf("Could not verify list input: %s\n", err) return 1 } } // Select private key to use privkeystr := selectPrivKey(OptionsVar.Privkey, GlobalConfigVar.PrivateKey, "") // Parse privkey if privkeystr != "" { privkey = new(message.Curve25519Key) copy(privkey[:], utils.B58decode(privkeystr)) } // Generate embedded keypairs if OptionsVar.Embedkey { if OptionsVar.Notrace || privkey == nil { embedConstantPrivKey, err = message.GenLongTermKey(OptionsVar.Hidden, OptionsVar.Sync) if err != nil { log.Errorf("Key generation error:%s\n", err) return 1 } } else { embedConstantPrivKey = privkey } embedConstantPubKey = message.GenPubKey(embedConstantPrivKey) embedTemporaryPrivKey, err = message.GenRandomKey() if err != nil { log.Errorf("Key generation error:%s\n", err) return 1 } embedTemporaryPubKey = message.GenPubKey(embedTemporaryPrivKey) } embedded := utils.EncodeEmbedded(embedConstantPubKey, embedTemporaryPubKey) recipientConstantPubKey, recipientTemporaryPubKey := utils.ParseKeyPair(OptionsVar.Recipientkey) // Find a signature keypair if we can signKeyDir := "" if GlobalConfigVar.KeyDir != "" { signKeyDir = GlobalConfigVar.KeyDir } if OptionsVar.Signdir != "" { signKeyDir = OptionsVar.Signdir } if OptionsVar.Signkey != "" { var d []byte d, err = utils.MaxReadFile(2048, OptionsVar.Signkey) if err == nil { signKeyPair = new(message.SignKeyPair) kp, err := signKeyPair.Unmarshal(d) if err != nil { log.Errorf("Sign keypair decode error: %s\n", err) signKeyPair = nil } else { signKeyPair = kp } } else { log.Errorf("Sign keypair read error: %s\n", err) } } if signKeyPair == nil && signKeyDir != "" { var d []byte d, removeFile, err = utils.ReadRandomFile(signKeyDir, 2048) if err == nil { signKeyPair = new(message.SignKeyPair) kp, err := signKeyPair.Unmarshal(d) if err != nil { log.Errorf("Sign keypair decode error: %s\n", err) signKeyPair = nil removeFile = "" } else { signKeyPair = kp } } else { log.Errorf("Sign keypair read error: %s\n", err) } } // Set up sender parameters sender := message.Sender{ Signer: signKeyPair, SenderPrivateKey: privkey, ReceiveConstantPublicKey: recipientConstantPubKey, ReceiveTemporaryPublicKey: recipientTemporaryPubKey, TotalLength: GlobalConfigVar.BodyLength, PadToLength: GlobalConfigVar.PadToLength, HashCashBits: GlobalConfigVar.MinHashCash, } // We want encryption output in realtime log.Sync() inData = append(embedded, inData...) if OptionsVar.Repost { // Generate a repost-message encMessage, meta, err = sender.EncryptRepost(byte(OptionsVar.MessageType), inData) if err == nil { rph := utils.EncodeRepostHeader(meta.PadKey, mindelay, maxdelay) encMessage = append(rph[:], encMessage...) log.Datas("STATUS (Process):\tPREPOST\n") log.Dataf("STATUS (RepostSettings):\t%d %d\n", mindelay, maxdelay) } } else { // Generate a normal message encMessage, meta, err = sender.Encrypt(byte(OptionsVar.MessageType), inData) if err == nil { log.Datas("STATUS (Process):\tPOST\n") } } if err != nil { log.Fatalf("Encryption failed: %s\n", err) return 1 } log.Sync() // Output. repost is only written to stdout or file if OptionsVar.Outfile == "-" || (OptionsVar.Repost && OptionsVar.Outfile == "") { err = utils.WriteStdout(encMessage) // Display data as necessary if err == nil { log.Dataf("STATUS (RecPubKey):\t%s\n", utils.B58encode(meta.ReceiverConstantPubKey[:])) if OptionsVar.Embedkey { log.Dataf("STATUS (EmbedPublicKey):\t%s_%s\n", utils.B58encode(embedConstantPubKey[:]), utils.B58encode(embedTemporaryPubKey[:])) log.Dataf("STATUS (EmbedPrivateKey):\t%s_%s\n", utils.B58encode(embedConstantPrivKey[:]), utils.B58encode(embedTemporaryPrivKey[:])) } if meta.MessageKey != nil { log.Dataf("STATUS (ListInput):\tNULL %s %s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) log.Dataf("STATUS (Message):\t%s_%s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) } else { log.Dataf("STATUS (ListInput):\tNULL %s NULL\n", utils.B58encode(meta.MessageID[:])) log.Dataf("STATUS (MessageID):\t%s\n", utils.B58encode(meta.MessageID[:])) } } } else if OptionsVar.Outfile != "" || OptionsVar.Repost { err = utils.WriteNewFile(OptionsVar.Outfile, encMessage) // Display data as necessary log.Dataf("STATUS (RecPubKey):\t%s\n", utils.B58encode(meta.ReceiverConstantPubKey[:])) if err == nil { if OptionsVar.Embedkey { log.Dataf("STATUS (EmbedPublicKey):\t%s_%s\n", utils.B58encode(embedConstantPubKey[:]), utils.B58encode(embedTemporaryPubKey[:])) log.Dataf("STATUS (EmbedPrivateKey):\t%s_%s\n", utils.B58encode(embedConstantPrivKey[:]), utils.B58encode(embedTemporaryPrivKey[:])) } if meta.MessageKey != nil { log.Dataf("STATUS (ListInput):\tNULL %s %s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) log.Dataf("STATUS (Message):\t%s_%s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) log.Printf("Pastebin Address:\t%s_%s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) } else { log.Dataf("STATUS (ListInput):\tNULL %s NULL\n", utils.B58encode(meta.MessageID[:])) log.Dataf("STATUS (MessageID):\t%s\n", utils.B58encode(meta.MessageID[:])) log.Printf("Pastebin Address:\t%s\n", utils.B58encode(meta.MessageID[:])) } } } else { // Post to server server := OptionsVar.Server proto := repproto.New(OptionsVar.Socksserver, OptionsVar.Server, GlobalConfigVar.PasteServers...) if server == "" { server, err = proto.Post(meta.MessageID[:], encMessage) } else { err = proto.PostSpecific(server, encMessage) } sep := "/" if server != "" && server[len(server)-1] == '/' { sep = "" } if err == nil { if meta.MessageKey != nil { log.Dataf("STATUS (URL):\t%s/%s_%s\n", server, utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) } if OptionsVar.Embedkey { log.Dataf("STATUS (EmbedPublicKey):\t%s_%s\n", utils.B58encode(embedConstantPubKey[:]), utils.B58encode(embedTemporaryPubKey[:])) log.Dataf("STATUS (EmbedPrivateKey):\t%s_%s\n", utils.B58encode(embedConstantPrivKey[:]), utils.B58encode(embedTemporaryPrivKey[:])) } if meta.MessageKey != nil { log.Dataf("STATUS (ListInput):\t%s %s %s\n", server, utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) log.Dataf("STATUS (Message):\t%s_%s\n", utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) log.Printf("Pastebin Address:\t%s%s%s_%s\n", server, sep, utils.B58encode(meta.MessageID[:]), utils.B58encode(meta.MessageKey[:])) } else { log.Dataf("STATUS (ListInput):\t%s %s NULL\n", server, utils.B58encode(meta.MessageID[:])) log.Dataf("STATUS (MessageID):\t%s\n", utils.B58encode(meta.MessageID[:])) log.Printf("Pastebin Address:\t%s%s%s\n", server, sep, utils.B58encode(meta.MessageID[:])) } } } if err != nil { log.Fatalf("Output failed: %s\n", err) log.Sync() return 1 } if removeFile != "" { // Operation has been successful, remove signer keyfile (if any) os.Remove(removeFile) } return 0 }
// TouchPeer creates a peer entry if it does not exist yet func (store Store) TouchPeer(pubkey *[ed25519.PublicKeySize]byte) { err := store.db.TouchPeer(pubkey) if err != nil { log.Errorf("TouchPeer: %s, %s\n", err, utils.B58encode(pubkey[:])) } }
// UpdatePeerFetchStat writes fetch-specific data func (store Store) UpdatePeerFetchStat(pubkey *[ed25519.PublicKeySize]byte, lastFetch, lastPos, lastErrors uint64) { err := store.db.UpdatePeerStats(pubkey, lastFetch, lastPos, lastErrors) if err != nil { log.Errorf("UpdatePeerStats: %s, %s\n", err, utils.B58encode(pubkey[:])) } }
// UpdatePeerNotification updates the peer stat after notification send func (store Store) UpdatePeerNotification(pubkey *[ed25519.PublicKeySize]byte, hasError bool) { err := store.db.UpdatePeerNotification(pubkey, hasError) if err != nil { log.Errorf("UpdatePeerNotification: %s, %s\n", err, utils.B58encode(pubkey[:])) } }
// TouchPeer creates a peer entry if it does not exist yet func (store Store) TouchPeer(pubkey *[ed25519.PublicKeySize]byte) { err := store.db.TouchPeer(pubkey) if err != nil { log.Errorf("TouchPeer: %s, %x\n", err, *pubkey) } }