add wipeboltcard

This commit is contained in:
Peter Rounce 2022-11-21 10:59:36 +00:00
parent 52533dd887
commit bfc6436098
6 changed files with 172 additions and 3 deletions

View file

@ -12,7 +12,7 @@ CREATE TABLE cards (
k2_cmac_key CHAR(32) NOT NULL, k2_cmac_key CHAR(32) NOT NULL,
k3 CHAR(32) NOT NULL, k3 CHAR(32) NOT NULL,
k4 CHAR(32) NOT NULL, k4 CHAR(32) NOT NULL,
uid CHAR(14) NOT NULL, uid VARCHAR(14) NOT NULL DEFAULT '',
last_counter_value INTEGER NOT NULL, last_counter_value INTEGER NOT NULL,
lnurlw_request_timeout_sec INT NOT NULL, lnurlw_request_timeout_sec INT NOT NULL,
lnurlw_enable CHAR(1) NOT NULL DEFAULT 'N', lnurlw_enable CHAR(1) NOT NULL DEFAULT 'N',
@ -26,6 +26,7 @@ CREATE TABLE cards (
one_time_code_expiry TIMESTAMPTZ DEFAULT NOW() + INTERVAL '1 DAY', one_time_code_expiry TIMESTAMPTZ DEFAULT NOW() + INTERVAL '1 DAY',
one_time_code_used CHAR(1) NOT NULL DEFAULT 'Y', one_time_code_used CHAR(1) NOT NULL DEFAULT 'Y',
allow_negative_balance CHAR(1) NOT NULL DEFAULT 'N', allow_negative_balance CHAR(1) NOT NULL DEFAULT 'N',
wiped CHAR(1) NOT NULL DEFAULT 'N',
PRIMARY KEY(card_id) PRIMARY KEY(card_id)
); );

View file

@ -76,7 +76,7 @@ func db_get_new_card(one_time_code string) (*card, error) {
sqlStatement := `SELECT k0_auth_key, k2_cmac_key, k3, k4, card_name` + sqlStatement := `SELECT k0_auth_key, k2_cmac_key, k3, k4, card_name` +
` FROM cards WHERE one_time_code=$1 AND` + ` FROM cards WHERE one_time_code=$1 AND` +
` one_time_code_expiry > NOW() AND one_time_code_used = 'N';` ` one_time_code_expiry > NOW() AND one_time_code_used = 'N' AND wiped = 'N';`
row := db.QueryRow(sqlStatement, one_time_code) row := db.QueryRow(sqlStatement, one_time_code)
err = row.Scan( err = row.Scan(
&c.k0_auth_key, &c.k0_auth_key,

View file

@ -58,7 +58,7 @@ func new_card_request(w http.ResponseWriter, req *http.Request) {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
log.Debug(err) log.Debug(err)
write_error_message(w, "one time code was used or does not exist") write_error_message(w, "one time code was used or card was wiped or card does not exist")
return return
} }

97
wipeboltcard/database.go Normal file
View file

@ -0,0 +1,97 @@
package main
import (
"database/sql"
"errors"
"fmt"
_ "github.com/lib/pq"
"os"
)
func db_open() (*sql.DB, error) {
// get connection string from environment variables
conn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
os.Getenv("DB_HOST"),
os.Getenv("DB_PORT"),
os.Getenv("DB_USER"),
os.Getenv("DB_PASSWORD"),
os.Getenv("DB_NAME"))
db, err := sql.Open("postgres", conn)
if err != nil {
return db, err
}
return db, nil
}
func db_get_card_name_count(card_name string) (card_count int, err error) {
card_count = 0
db, err := db_open()
if err != nil {
return 0, err
}
defer db.Close()
sqlStatement := `SELECT COUNT(card_id) FROM cards WHERE card_name = $1;`
row := db.QueryRow(sqlStatement, card_name)
err = row.Scan(&card_count)
if err != nil {
return 0, err
}
return card_count, 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 = os.Getenv("AES_DECRYPT_KEY")
return &card_wipe_info, nil
}

71
wipeboltcard/main.go Normal file
View file

@ -0,0 +1,71 @@
package main
import (
"flag"
"fmt"
"strconv"
log "github.com/sirupsen/logrus"
qrcode "github.com/skip2/go-qrcode"
)
type card_wipe_info struct {
id int
k0 string
k1 string
k2 string
k3 string
k4 string
uid string
}
func main() {
card_name_ptr := flag.String("name", "", "select the card to be wiped by name")
flag.Parse()
if *card_name_ptr == "" {
flag.PrintDefaults()
return
}
// check if card_name exists
card_count, err := db_get_card_name_count(*card_name_ptr)
if err != nil {
log.Warn(err.Error())
return
}
if card_count == 0 {
fmt.Println("the card name does not exist in the database")
return
}
// set the card as wiped and disabled, get the keys
card_wipe_info_values, err := db_wipe_card(*card_name_ptr)
if err != nil {
log.Warn(err.Error())
return
}
// show a QR code on the console
qr := `{` +
`"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` +
`}`;
fmt.Println()
q, err := qrcode.New(qr, qrcode.Medium)
fmt.Println(q.ToSmallString(false))
}

BIN
wipeboltcard/wipeboltcard Executable file

Binary file not shown.