Пример #1
0
// Add responds to /pks/add HKP requests.
func (w *Worker) Add(a *hkp.Add) {
	// Parse armored keytext
	var changes []*KeyChange
	var readErrors []*ReadKeyResult
	// Check and decode the armor
	armorBlock, err := armor.Decode(bytes.NewBufferString(a.Keytext))
	if err != nil {
		a.Response() <- &ErrorResponse{err}
		return
	}

	for readKey := range ReadKeys(armorBlock.Body) {
		if readKey.Error != nil {
			readErrors = append(readErrors, readKey)
		} else {
			log.Println("add.go: Found a key from request!! = ", readKey.Pubkey.KeyId())
			//SignPubKeyPKS(*readKey.Pubkey)
			//First Check weather we are the authority for it
			underAuth := IsUnderAuth(*readKey.Pubkey)
			if underAuth != nil {
				change1 := &KeyChange{}
				change1.Type = NotInOurAuthority
				change1.ChangeMessage = underAuth.Error()
				changes = append(changes, change1)
				log.Println(underAuth.Error())
			} else {

				//Checked weather its under our own authority

				if readKey.Pubkey.Sha256 == a.ShaOfTarget || len(a.ShaOfTarget) != 64 {
					//Extract Email
					usrID := readKey.Pubkey.primaryUid
					userEmail := usrID.UserId.Email
					//Email extracted
					req_PubKey := readKey.Pubkey
					reqChanges := w.FindChanges(readKey.Pubkey)
					isVerified := false
					var otlState int
					if reqChanges.Type == KeyAdded {
						//Key not found hence new key added
						log.Println("add.go:Request has New Key (ID): ", req_PubKey.Fingerprint())

						isVerified, otlState = w.Verify(userEmail, a.Keytext, *req_PubKey, int16(1))
						log.Println("add.go:Is Requested Key Verified??: ", isVerified)

					} else if reqChanges.Type == KeyModified {
						//key will be changed/updated with new contents
						log.Println("add.go:Request Modifies key (ID): ", req_PubKey.Fingerprint())

						isVerified, otlState = w.Verify(userEmail, a.Keytext, *req_PubKey, int16(1))
						log.Println("add.go:Is Requested Key Verified??: ", isVerified)
					} else if reqChanges.Type == KeyNotChanged {
						log.Println("add.go:request doesnt make change to key(id) : ", req_PubKey.Fingerprint())

						w.notifyChange(reqChanges)
						changes = append(changes, reqChanges)
						a.Response() <- &AddResponse{Changes: changes, Errors: readErrors}
						return
					}

					if isVerified {
						if reqChanges.Type != KeyNotChanged {
							//If key is verified then call upsert as
							//it will eventually insert data in to db
							log.Println("add.go:Key Verified...")
							//Key verified hence add signature of PKS
							//Check weather a key with same email exists or not.
							repKeys, err := w.LookupKeys(userEmail, 2)
							replacesKey := false
							if err == ErrKeyNotFound || len(repKeys) <= 0 { //No key found by Email
								replacesKey = false
							} else {
								replacesKey = true
							}

							//Replace End

							//Signing Start
							signed_Key, err := SignKeyAfterVerification(a.Keytext)
							if err != nil {
								log.Println("Error signing key ", err)
								a.Response() <- &ErrorResponse{err}
								return
							}
							armorBlock, err := armor.Decode(bytes.NewBufferString(signed_Key))
							if err != nil {
								log.Println("decoding signed key ", err)
								a.Response() <- &ErrorResponse{err}
								return
							}

							for readKey := range ReadKeys(armorBlock.Body) {
								if readKey.Error != nil {
									readErrors = append(readErrors, readKey)
								} else {

									if _, err = w.Begin(); err != nil {
										a.Response() <- &ErrorResponse{err}
										return
									}
									change := w.UpsertKey(readKey.Pubkey)
									if err = w.Commit(); err != nil {
										a.Response() <- &ErrorResponse{err}
										return
									}
									//Signing END
									if change.Error != nil {
										log.Printf("Error updating key [%s]: %v\n", readKey.Pubkey.Fingerprint(),
											change.Error)
									} else {
										if replacesKey {
											//Delete Old key
											if _, err = w.Begin(); err != nil {
												log.Println("replaceDelete", err)
												a.Response() <- &ErrorResponse{err}
												return
											}
											change, err1 := w.deleteKey(repKeys[0])
											if err = w.Commit(); err != nil {
												log.Println("replaceDelete", err)
												a.Response() <- &ErrorResponse{err}
												return
											}

											if err1 != nil {
												log.Println("replaceDelete", err1)
												a.Response() <- &ErrorResponse{err1}
												return
											}

											w.notifyChange(&change)
											changes = append(changes, &change)
										}
									}

									//Notify using changes
									w.notifyChange(change)
									changes = append(changes, change)
								}
							}

						} else {
							w.notifyChange(reqChanges)
							changes = append(changes, reqChanges)
						}
					} else {
						reqChanges.Type = EmailNotVerified
						reqChanges.Fingerprint = ""
						if otlState == OTLNewOtlMade {
							resKeys, err := w.LookupKeys(userEmail, 2)
							replacesKey := false
							if err == ErrKeyNotFound || len(resKeys) <= 0 { //No key found by Email
								replacesKey = false
							} else {
								replacesKey = true
							}

							message := fmt.Sprintf("A verification link has been sent to %s.The link will expire in %d day/s.\n Please check your email.", userEmail, ExpInDays)
							if replacesKey {
								message += "		* A key with same email already exists on the server.If you verify above request it will replace the key with id " +
									strings.ToUpper(resKeys[0].KeyId())
							}
							reqChanges.ChangeMessage = message
							log.Println("OTL NOT FOUND!!")

						} else if otlState == OTLExpired {
							reqChanges.ChangeMessage = fmt.Sprintf("The link you have clicked has expired. Please submit your key again.")
							log.Println("OTL Expired!!")

						} else if otlState == OTLNotVerified {
							reqChanges.ChangeMessage = fmt.Sprintf("A request for same key has already been made.Please Check your email %s", userEmail)
							log.Println("OTL Not Verified!!")
						} else if otlState == ErrorSendingMail {
							reqChanges.ChangeMessage = fmt.Sprintf("Unfortunately we were unable to send an e-mail to %s Please Add key after sometime with new request", userEmail)
						}

						changes = append(changes, reqChanges)
					}

					//EDIT END

				}
				a.Response() <- &AddResponse{Changes: changes, Errors: readErrors}
				return
			}
			a.Response() <- &AddResponse{Changes: changes, Errors: readErrors}
			return
		}
	}
}
Пример #2
0
func (w *Worker) PRCOTLVerify(otlv *hkp.OTLVerify) (result_code int) {
	//fmt.Println("prcotlv:raw otlv=", otlv)
	//fmt.Println("prcotlv otl=", otlv.OTLtext)
	/*

		1.Lookup otl_hash in verify DB >>if1
			2.if2>> Check weather it has been more than two days

				3. Show add screen with
						extra message (ur email id was detected in following request)
						show armor of the add request

						//ADD Button
							4.Set is_verified = true,veri_time=now
							again sends add request to PKS with armor data
						//CANCEL Button stops
							4.Set is_verified = false,veri_time=now

			5.else2>> Show message saying otl expiration
		6.else1>> Show message saying no such otl exists

	*/

	Temp_veri := []Veri_data{}

	veri := new(Veri_data)

	w.db.Select(&Temp_veri, `SELECT * FROM verify_email
		WHERE otl_hash=$1`, otlv.OTLtext)

	if len(Temp_veri) == 0 {
		result_code = OTLNotFound
		veri.Is_verified = false
		//fmt.Println("prc_otl_handler.go:No such OTL NOT FOUND in DB")
		//alr_verifAdd := new(hkp.Add)
		//aResp := new(AddResponse)
		keyCh := new(KeyChange)
		keyCh.ChangeMessage = "We are extremely Sorry but NO such Link Exists on this server"
		keyCh.Type = KeyNotChanged
		var changes []*KeyChange
		changes = append(changes, keyCh)
		otlv.Response() <- &AddResponse{Changes: changes}
	} else {
		*veri = Temp_veri[0]
		if veri.Expi_time.Before(time.Now()) {
			result_code = OTLExpired
			keyCh := new(KeyChange)
			keyCh.ChangeMessage = fmt.Sprintf("The link you have clicked has expired at %s", veri.Expi_time.Format(time.RFC850))
			keyCh.Type = KeyNotChanged
			var changes []*KeyChange
			changes = append(changes, keyCh)
			otlv.Response() <- &AddResponse{Changes: changes}
		} else if veri.Is_verified != true {
			//OTL has been found and it has not yet expired or verified
			result_code = OTLNotVerified
			//set isverified =true,verification time=now
			veri.Is_verified = true
			veri.Veri_time = time.Now()

			//Change isverified into DB

			if _, err := w.Begin(); err != nil {
				log.Println("OTL Verifier:Begining...", err)
				keyCh := new(KeyChange)
				keyCh.ChangeMessage = fmt.Sprintf("Problem at server.DB cant begin")
				keyCh.Type = KeyNotChanged
				var changes []*KeyChange
				changes = append(changes, keyCh)
				otlv.Response() <- &AddResponse{Changes: changes}
				return
			}
			w.tx.Execl(`UPDATE verify_email SET veri_time = $1,is_verified= $2
				WHERE otl_hash = $3`, veri.Veri_time, veri.Is_verified, veri.Otl_hash)
			if err := w.Commit(); err != nil {
				log.Println("OTL Verifier:Commiting...", err)
				keyCh := new(KeyChange)
				keyCh.ChangeMessage = fmt.Sprintf("Problem at server.DB cant commit")
				keyCh.Type = KeyNotChanged
				var changes []*KeyChange
				changes = append(changes, keyCh)
				otlv.Response() <- &AddResponse{Changes: changes}
				return
			}

			result_code = OTLVerified
			if veri.Operation == int16(1) {
				verifiedAdd := new(hkp.Add)
				verifiedAdd.Keytext = veri.Key_text
				verifiedAdd.Request = otlv.Request
				verifiedAdd.ShaOfTarget = veri.Hash_pubkey
				verifiedAdd.SetResponse(otlv.Response())
				w.Add(verifiedAdd)
			} else if veri.Operation == int16(2) {
				verifiedDelete := new(hkp.DeleteReq)
				verifiedDelete.EmailToDelete = veri.Pubkey_id
				verifiedDelete.KeyID = veri.Pubkey_id
				verifiedDelete.SetResponse(otlv.Response())
				verifiedDelete.Request = otlv.Request
				w.HandleDeleteReq(verifiedDelete)
			}
		} else if veri.Is_verified { //OTL is already verified
			//fmt.Println("prc_otl_handler.go: OTL is already verified")
			result_code = OTLAlereadyVerified
			//alr_verifAdd := new(hkp.Add)
			//			aResp := new(AddResponse)

			keyCh := new(KeyChange)
			keyCh.ChangeMessage = "The link you have clicked is already used once"
			keyCh.Type = KeyNotChanged
			var changes []*KeyChange
			changes = append(changes, keyCh)
			otlv.Response() <- &AddResponse{Changes: changes}
		}

	}

	/* TO Delete a key
	deleteString := otlv.OTLtext
	//tx := w.db.MustBegin()
	tx.Execl(`DELETE FROM openpgp_pubkey
				WHERE uuid = $1`, deleteString)
	//tx.Commit()
	//DELETE FROM table_name
	//WHERE some_column = some_value
	*/
	return

}