// 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 } } }