Пример #1
0
// 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
}
Пример #2
0
// 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
}
Пример #3
0
// 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")
}
Пример #4
0
// 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
}
Пример #5
0
// 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
}
Пример #6
0
// 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
}
Пример #7
0
// 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
		})
	}
}
Пример #8
0
// 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
}
Пример #9
0
// 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
		})
	}
}
Пример #10
0
// 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)
	}
}
Пример #11
0
// 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
		})
	}
}
Пример #12
0
// 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
}
Пример #13
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
}
Пример #14
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
}
Пример #15
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
}
Пример #16
0
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
}
Пример #17
0
// 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[:]))
	}
}
Пример #18
0
// 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
}
Пример #19
0
// 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)
	}
}
Пример #20
0
// 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
}
Пример #21
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[:]))
	}
}
Пример #22
0
// 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[:]))
	}
}
Пример #23
0
// 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[:]))
	}
}
Пример #24
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, %x\n", err, *pubkey)
	}
}