Example #1
0
// FetchPost fetches a post from a peer and adds it.
func (ms MessageServer) FetchPost(url, auth string, msgID [message.MessageIDSize]byte, expireRequest uint64) error {
	// Fetch the post
	proto := repproto.New(ms.SocksProxy, "")
	data, err := proto.GetSpecificAuth(url, auth, msgID[:])
	// data, err := proto.GetSpecific(url, msgID[:])
	if err != nil {
		return err
	}
	// Verify and use it
	signheader, err := message.Base64Message(data).GetSignHeader()
	if err != nil {
		log.Debugf("Bad fetch:GetSignHeader: %s\n", err)
		return err
	}
	details, err := message.VerifySignature(*signheader, ms.MinHashCashBits)
	if err != nil {
		log.Debugf("Bad fetch:VerifySignature: %s\n", err)
		return err
	}
	constantRecipientPub, MessageID, err := deferVerify(data)
	if err != nil {
		log.Debugf("Bad fetch:deferVerify: %s\n", err)
		return err
	}
	if *MessageID != details.MsgID {
		log.Debugs("Bad fetch:MessageID\n")
		return ErrBadMessageID
	}
	msgStruct := &structs.MessageStruct{
		MessageID:              *MessageID,
		ReceiverConstantPubKey: *constantRecipientPub,
		SignerPub:              details.PublicKey,
		OneTime:                false,
		Sync:                   false,
		Hidden:                 false,
		ExpireRequest:          expireRequest,
	}
	if message.KeyIsSync(constantRecipientPub) {
		msgStruct.Sync = true
	}
	if message.KeyIsHidden(constantRecipientPub) {
		msgStruct.Hidden = true
	}

	sigStruct := &structs.SignerStruct{
		PublicKey: details.PublicKey,
		Nonce:     details.HashCashNonce,
		Bits:      details.HashCashBits,
	}
	sigStruct.MaxMessagesPosted, sigStruct.MaxMessagesRetained, sigStruct.ExpireTarget = ms.calcLimits(details.HashCashBits)
	return ms.DB.Put(msgStruct, sigStruct, data)
}
Example #2
0
// ListSpecific lists the messages for pubKey from a specific server
func (proto *Proto) ListSpecific(server string, pubKey, privKey []byte, start, count int) (messages []*structs.MessageStruct, more bool, err error) {
	var authStr string
	var myPubKey message.Curve25519Key
	copy(myPubKey[:], pubKey)
	if message.KeyIsHidden(&myPubKey) {
		if privKey == nil {
			return nil, false, ErrPrivKey
		}
		auth, err := proto.Auth(server, privKey)
		if err != nil {
			return nil, false, err
		}
		authStr = "&auth=" + auth
	}
	url := constructURL(server, "/keyindex?key=", utils.B58encode(pubKey[:]), "&start=", strconv.Itoa(start), "count=", strconv.Itoa(count), authStr)
	body, err := socks.Proxy(proto.SocksServer).LimitGet(url, 512000)
	if err != nil {
		return nil, false, err
	}
	return parseListResponse(body)
}
Example #3
0
// ProcessPost verifies and adds a post to the database.
func (ms MessageServer) ProcessPost(postdata io.ReadCloser, oneTime bool, expireRequest uint64) string {
	data, err := utils.MaxRead(ms.MaxPostSize, postdata)
	if err != nil {
		return "ERROR: Message too big\n"
	}
	if len(data) < ms.MinPostSize {
		return "ERROR: Message too small\n"
	}
	signheader, err := message.Base64Message(data).GetSignHeader()
	if err != nil {
		log.Debugf("Post:GetSignHeader: %s\n", err)
		return "ERROR: Sign Header\n"
	}
	details, err := message.VerifySignature(*signheader, ms.MinHashCashBits)
	if err != nil {
		log.Debugf("Post:VerifySignature: %s\n", err)
		return "ERROR: HashCash\n"
	}
	constantRecipientPub, MessageID, err := deferVerify(data)
	if err != nil {
		log.Debugf("Post:deferVerify: %s\n", err)
		return "ERROR: Verify\n"
	}
	if *MessageID != details.MsgID {
		log.Debugs("Post:MessageID\n")
		return "ERROR: MessageID\n"
	}
	msgStruct := &structs.MessageStruct{
		MessageID:              *MessageID,
		ReceiverConstantPubKey: *constantRecipientPub,
		SignerPub:              details.PublicKey,
		OneTime:                oneTime,
		Sync:                   false,
		Hidden:                 false,
		ExpireRequest:          expireRequest,
	}
	if !oneTime {
		if message.KeyIsSync(constantRecipientPub) {
			msgStruct.Sync = true
		}
	} else {
		msgStruct.Sync = false
	}
	if message.KeyIsHidden(constantRecipientPub) {
		msgStruct.Hidden = true
	}

	sigStruct := &structs.SignerStruct{
		PublicKey: details.PublicKey,
		Nonce:     details.HashCashNonce,
		Bits:      details.HashCashBits,
	}
	sigStruct.MaxMessagesPosted, sigStruct.MaxMessagesRetained, sigStruct.ExpireTarget = ms.calcLimits(details.HashCashBits)
	_, _ = msgStruct, sigStruct
	ms.RandomSleep()
	// err = ms.DB.Put(msgStruct, sigStruct, data)
	err = ms.DB.PutNotify(msgStruct, sigStruct, data, ms.notifyChan)
	ms.RandomSleep()
	if err != nil {
		log.Debugf("Post:MessageDB: %s\n", err)
		return fmt.Sprintf("ERROR: %s\n", err)
	}
	log.Debugf("Post:Added: %x\n", MessageID[:12])
	if ms.Stat {
		stat.Input <- stat.Post
	}
	return "SUCCESS: Connection close\n"
}
Example #4
0
// GetKeyIndex returns the index for a key.
func (ms MessageServer) GetKeyIndex(w http.ResponseWriter, r *http.Request) {
	var pubKey *message.Curve25519Key
	var auth []byte
	start := int64(0)
	count := int64(10)
	w.Header().Set("Content-Type", "text/plain; charset=us-ascii")
	getValues := r.URL.Query()
	if getValues != nil {
		if v, ok := getValues["start"]; ok {
			t, err := strconv.Atoi(v[0])
			if err == nil {
				start = int64(t)
			}
		}
		if v, ok := getValues["count"]; ok {
			t, err := strconv.Atoi(v[0])
			if err == nil {
				count = int64(t)
				if count > ms.MaxIndexKey {
					count = ms.MaxIndexKey
				}
			}
		}
		if v, ok := getValues["key"]; ok {
			if len(v[0]) > message.Curve25519KeySize*10 {
				io.WriteString(w, "ERROR: Bad param\n")
				return
			}
			t := utils.B58decode(v[0])
			if len(t) != message.Curve25519KeySize {
				io.WriteString(w, "ERROR: Bad param\n")
				return
			}
			pubKey = new(message.Curve25519Key)
			copy(pubKey[:], t)
			if v, ok := getValues["auth"]; ok {
				if len(v[0]) > keyauth.AnswerSize*10 {
					io.WriteString(w, "ERROR: Bad param\n")
					return
				}
				auth = utils.B58decode(v[0])
				if len(auth) != keyauth.AnswerSize {
					io.WriteString(w, "ERROR: Bad param\n")
					return
				}
			}
		} else {
			io.WriteString(w, "ERROR: Missing param\n")
			return
		}
	} else {
		io.WriteString(w, "ERROR: Missing param\n")
		return
	}
	if pubKey == nil {
		io.WriteString(w, "ERROR: Missing param\n")
		return
	}
	if message.KeyIsHidden(pubKey) {
		if auth == nil {
			log.Debugs("List:Auth missing\n")
			io.WriteString(w, "ERROR: Authentication required\n")
			return
		}
		answer := [keyauth.AnswerSize]byte{}
		copy(answer[:], auth)
		now := uint64(time.Now().Unix() + ms.TimeSkew)
		if !keyauth.VerifyTime(&answer, now, ms.TimeGrace) {
			log.Debugs("List:Auth timeout\n")
			io.WriteString(w, "ERROR: Authentication failed: Timeout\n")
			return
		}
		privK := [32]byte(*ms.authPrivKey)
		testK := [32]byte(*pubKey)
		if !keyauth.Verify(&answer, &privK, &testK) {
			log.Debugs("List:Auth no verify\n")
			io.WriteString(w, "ERROR: Authentication failed: No Match\n")
			return
		}
	}
	messages, found, err := ms.DB.GetIndex(pubKey, start, count)
	if err != nil && err != fileback.ErrNoMore {
		log.Debugf("List:GetIndex: %s\n", err)
		log.Debugf("List:GetIndex: Key %x\n", pubKey)
		io.WriteString(w, "ERROR: List failed\n")
		return
	}
	io.WriteString(w, "SUCCESS: Data follows\n")
	for _, msg := range messages {
		io.WriteString(w, "IDX: "+strings.Trim(string(msg), " \t\n\r")+"\n")
	}
	if int64(found) < count {
		io.WriteString(w, "CMD: Exceeded\n")
	} else {
		io.WriteString(w, "CMD: Continue\n")
	}
}