diff --git a/createboltcard.go b/createboltcard.go index d7e962f..59bd7b2 100644 --- a/createboltcard.go +++ b/createboltcard.go @@ -22,7 +22,7 @@ func random_hex() string { func createboltcard(w http.ResponseWriter, r *http.Request) { if db_get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { - msg := "Internal API function is not enabled" + msg := "createboltcard: internal API function is not enabled" log.Debug(msg) write_error_message(w, msg) return @@ -31,7 +31,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { tx_max_str := r.URL.Query().Get("tx_max") tx_max, err := strconv.Atoi(tx_max_str) if err != nil { - msg := "tx_max is not a valid integer" + msg := "createboltcard: tx_max is not a valid integer" log.Warn(msg) write_error_message(w, msg) return @@ -40,7 +40,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { day_max_str := r.URL.Query().Get("day_max") day_max, err := strconv.Atoi(day_max_str) if err != nil { - msg := "day_max is not a valid integer" + msg := "createboltcard: day_max is not a valid integer" log.Warn(msg) write_error_message(w, msg) return @@ -49,7 +49,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { enable_flag_str := r.URL.Query().Get("enable") enable_flag, err := strconv.ParseBool(enable_flag_str) if err != nil { - msg := "enable is not a valid boolean" + msg := "createboltcard: enable is not a valid boolean" log.Warn(msg) write_error_message(w, msg) return @@ -60,7 +60,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { uid_privacy_flag_str := r.URL.Query().Get("uid_privacy") uid_privacy_flag, err := strconv.ParseBool(uid_privacy_flag_str) if err != nil { - msg := "uid_privacy is not a valid boolean" + msg := "createboltcard: uid_privacy is not a valid boolean" log.Warn(msg) write_error_message(w, msg) return @@ -69,7 +69,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { allow_neg_bal_flag_str := r.URL.Query().Get("allow_neg_bal") allow_neg_bal_flag, err := strconv.ParseBool(allow_neg_bal_flag_str) if err != nil { - msg := "allow_neg_bal is not a valid boolean" + msg := "createboltcard: allow_neg_bal is not a valid boolean" log.Warn(msg) write_error_message(w, msg) return @@ -84,7 +84,7 @@ func createboltcard(w http.ResponseWriter, r *http.Request) { } if card_count > 0 { - msg := "the card name already exists in the database" + msg := "createboltcard: the card name already exists in the database" log.Warn(msg) write_error_message(w, msg) return diff --git a/database.go b/database.go index 7351fd1..65e5d1d 100644 --- a/database.go +++ b/database.go @@ -776,3 +776,51 @@ func db_insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string return nil } + +func db_wipe_card(card_name string) (*card_wipe_info, error) { + + card_wipe_info := card_wipe_info{} + + db, err := db_open() + if err != nil { + return &card_wipe_info, err + } + defer db.Close() + + // set card as wiped and disabled + + sqlStatement := `UPDATE cards SET` + + ` lnurlw_enable = 'N', lnurlp_enable = 'N', email_enable = 'N', wiped = 'Y'` + + ` WHERE card_name = $1;` + res, err := db.Exec(sqlStatement, card_name) + if err != nil { + return &card_wipe_info, err + } + count, err := res.RowsAffected() + if err != nil { + return &card_wipe_info, err + } + if count != 1 { + return &card_wipe_info, errors.New("not one card record updated") + } + + // get card keys + + sqlStatement = `SELECT card_id, uid, k0_auth_key, k2_cmac_key, k3, k4` + + ` FROM cards WHERE card_name = $1;` + row := db.QueryRow(sqlStatement, card_name) + err = row.Scan( + &card_wipe_info.id, + &card_wipe_info.uid, + &card_wipe_info.k0, + &card_wipe_info.k2, + &card_wipe_info.k3, + &card_wipe_info.k4) + if err != nil { + return &card_wipe_info, err + } + + card_wipe_info.k1 = db_get_setting("AES_DECRYPT_KEY") + + return &card_wipe_info, nil +} diff --git a/main.go b/main.go index ffb52b3..8077842 100644 --- a/main.go +++ b/main.go @@ -59,10 +59,9 @@ func main() { // this has no authentication and is not to be exposed publicly // it exists for use on a private virtual network within a docker container - // ping internal_router.Path("/ping").Methods("GET").HandlerFunc(internal_ping) internal_router.Path("/createboltcard").Methods("GET").HandlerFunc(createboltcard) - //internal_router.Path("/wipeboltcard").Methods("GET").HandlerFunc(wipeboltcard) + internal_router.Path("/wipeboltcard").Methods("GET").HandlerFunc(wipeboltcard) port := db_get_setting("HOST_PORT") if port == "" { diff --git a/wipeboltcard.go b/wipeboltcard.go new file mode 100644 index 0000000..59511e6 --- /dev/null +++ b/wipeboltcard.go @@ -0,0 +1,83 @@ +package main + +import ( + log "github.com/sirupsen/logrus" + "strconv" + "net/http" +) + +type card_wipe_info struct { + id int + k0 string + k1 string + k2 string + k3 string + k4 string + uid string +} + +func wipeboltcard(w http.ResponseWriter, r *http.Request) { + if db_get_setting("FUNCTION_INTERNAL_API") != "ENABLE" { + msg := "wipeboltcard: internal API function is not enabled" + log.Debug(msg) + write_error_message(w, msg) + return + } + + card_name := r.URL.Query().Get("card_name") + + // check if card_name has been given + + if card_name == "" { + msg := "wipeboltcard: the card name must be set" + log.Warn(msg) + write_error_message(w, msg) + return + } + + // check if card_name exists + + card_count, err := db_get_card_name_count(card_name) + + if card_count == 0 { + msg := "the card name does not exist in the database" + log.Warn(msg) + write_error_message(w, msg) + return + } + + // set the card as wiped and disabled, get the keys + + card_wipe_info_values, err := db_wipe_card(card_name) + if err != nil { + log.Warn(err.Error()) + return + } + + // log the request + + log.WithFields(log.Fields{ + "card_name": card_name}).Info("wipeboltcard API request") + + // generate a response + + jsonData := `{"status":"OK",` + + `"action": "wipe",` + + `"id": ` + strconv.Itoa(card_wipe_info_values.id) + `,` + + `"k0": "` + card_wipe_info_values.k0 + `",` + + `"k1": "` + card_wipe_info_values.k1 + `",` + + `"k2": "` + card_wipe_info_values.k2 + `",` + + `"k3": "` + card_wipe_info_values.k3 + `",` + + `"k4": "` + card_wipe_info_values.k4 + `",` + + `"uid": "` + card_wipe_info_values.uid + `",` + + `"version": 1"}` + + // log the response + + log.WithFields(log.Fields{ + "card_name": card_name, "response": jsonData}).Info("wipeboltcard API response") + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte(jsonData)) +}