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