Kesalahan git - gpg gagal menandatangani data


149

Saya baru saja mulai menggunakan git dan saya menginstal git dan gpg melalui homebrew. Untuk beberapa alasan, saya mendapatkan kesalahan ini ketika saya melakukannya git commit saya melihat banyak pertanyaan stackoverflow lainnya mengenai topik ini dan tidak ada satupun yang bekerja untuk saya. Bagaimana saya dapat memperbaiki kesalahan ini sehingga saya dapat mengunggah dengan sukses.

error: gpg failed to sign the data
fatal: failed to write commit object

3
Untuk pengguna Mac. Saya punya masalah ini. Saran pada halaman ini membantu saya menyadari bahwa saya mungkin memiliki dua versi gpg diinstal dan saya lakukan. Satu dari buatan dan satu dari GPG Suite. Saya ingin menggunakan GPG Suite karena memungkinkan untuk menyalin kata sandi di gantungan kunci sistem. Mencopot pemasangan versi penyeduhan menyelesaikan masalah saya. Bersamaan dengan jawaban @ sontonbarker tentang membunuh gpg-agent. Jadi saya menganggap konfigurasi masing-masing saling mengganggu.
Michael Welch



Saya baru saja mengalami masalah dengan penandatanganan gpg, masalahnya adalah bahwa repo git saya tidak memiliki set gpg.signingkey lokal, tetapi yang gllobal adalah. Jadi cukup setel git config --local user.signingkeyke kunci yang benar dan itu akan otomatis lagi. dan mungkin menghapus yang global dengangit config --global --unset user.signingkey
MarcusJ

Jawaban:


210

Untuk pemecahan masalah, dua hal yang harus dicoba pertama kali:

  • jalankan git config --global gpg.program gpg2, untuk memastikan git menggunakan gpg2dan tidakgpg
  • jalankan echo "test" | gpg2 --clearsign, untuk memastikan gpg2dirinya berfungsi

Jika semuanya tampak baik-baik saja, satu hal lagi yang perlu dicoba:

  • jalankan brew install pinentryuntuk memastikan Anda memiliki alat yang bagus diinstal untuk entri frasa sandi

Jika setelah itu instal dan Anda coba lagi git commitdan masih mendapatkan " failed to sign the data" kesalahan:

  • lari gpgconf --kill gpg-agentuntuk membunuh agen berjalan yang mungkin digantung

Jika itu mengatakan gpgconftidak diinstal atau tidak memiliki --killopsi, Anda dapat mencoba ini:

  1. cp ~/.gnupg ~/.gnupg-GOODuntuk menyimpan salinan Anda ~/.gnupguntuk dikembalikan lagi nanti jika diperlukan
  2. brew install gnupg21 untuk menginstal GnuPG 2.1

Alasan untuk menyimpan salinan ~/.gnupgdir Anda adalah bahwa GnuPG 2.1 berpotensi membuat / mengubah beberapa data kunci dengan cara yang tidak kompatibel dengan GnuPG 2.0 dan sebelumnya, jadi jika Anda ingin kembali lagi nanti, Anda dapat melakukannya mv ~/.gnupg ~/.gnupg21 && mv ~/.gnupg-GOOD ~/.gnupg.


Jika tidak, ada beberapa langkah dasar yang harus dijalankan untuk memeriksa Anda memiliki lingkungan GnuPG yang berfungsi:

  • jalankan gpg2 -K --keyid-format SHORT, untuk memeriksa apakah Anda memiliki setidaknya satu pasangan kunci

Jika output yang menunjukkan Anda tidak memiliki kunci rahasia untuk digunakan GnuPG, maka Anda perlu membuatnya:

  • jalankan gpg2 --gen-key, agar GnuPG memandu Anda melalui langkah-langkah untuk membuat pasangan kunci

Jika Anda mendapatkan pesan kesalahan yang mengatakan "ioctl tidak sesuai untuk perangkat" , lakukan ini:

  • jalankan export GPG_TTY=$(tty)dan / atau tambahkan itu ke ~/.bashrcatau˜/.bash_profile

Saya mendapatkan kesalahan ini ketika saya menjalankan perintah kedua: gpg: tidak ada kunci rahasia default: Tidak ada kunci rahasia gpg: [stdin]: clearsign gagal: Tidak ada kunci rahasia
Entitize

@Entitize Tampaknya ini menunjukkan gpg tidak berpikir Anda memiliki kunci untuk digunakan untuk masuk. Lihat langkah-langkah tambahan yang saya tambahkan ke jawabannya; jika Anda belum pernah berlari gpg2 --gen-keysebelumnya, itulah yang perlu Anda lakukan terlebih dahulu.
sontonbarker

2
ketika saya menjalankan echo "test" | gpg2 --clearsign, ia memberi saya: gpg-agent [-]: perintah get_passphrase gagal: ioctl yang tidak sesuai untuk perangkat gpg: masalah dengan agen: ioctl yang tidak sesuai untuk perangkat gpg: tidak ada kunci rahasia default: Operasi dibatalkan gpg: [stdin]: clearsign gagal: Operasi dibatalkan. Saya sudah mencoba banyak kemungkinan lain, tetapi tidak ada yang berhasil. Apakah ada cara untuk menggunakan GIT tanpa GPG!
Daftarkan

9
Anda mungkin mencoba export GPG_TTY=$(tty). Sejauh jika ada cara untuk menggunakan git tanpa gpg, Anda harus dapat melakukannya secara default atau hanya dengan menjalankan git config --global commit.gpgsign falsesecara global setel gpg penandatanganan komitmen Anda.
sontonbarker

10
Di sini, di Mac OS X, saya mulai men-debug dengan echo "test" | gpg2 --clearsign, menemukan kesalahan dan itu membawa saya ke utas ini , yang memecahkan masalah saya: Saya baru saja memasukkan sebuah export GPG_TTY=$(tty)ke dalam ˜/.bash_profilefile saya dan kemudian memuat ulang dengansource ˜/.bash_profile
herrera

71

Git perlu tahu kunci apa yang ditandatanganinya.

Setelah Anda menyiapkan GPG, agen gpg, dan file gpg.conf Anda (lihat panduan ini ), Anda perlu menjalankan

git config --global user.signingkey EB11C755

Jelas, ganti kunci publik di akhir dengan milik Anda. Jika Anda ingin setiap komit ditandatangani secara default, gunakan

git config --global commit.gpgsign true

7
Saya hanya mengalami hal ini jika ada orang yang cukup bodoh untuk melakukan apa yang saya lakukan: Pastikan Anda mengejanya "signingkey" dan bukan "signinkey".
ZNK

1
secara harfiah komentar dari @ZNK ini melakukannya untuk saya. Saya telah mengejanya "signkey" bukannya "signingkey"
jzatt

1
Jawaban yang diterima harus mengutip ini sebagai langkah pemecahan masalah pertama, karena kadang-kadang Anda sudah memiliki semua kunci Anda, itu hanya git lupa kunci mana yang digunakan.
f055

41

Entah bagaimana git Anda dikonfigurasi untuk menandatangani setiap komitmen GPG. Masuk dengan GPG tidak diharuskan untuk melakukan atau mendorong menggunakan git. Kemungkinan memberikan kesalahan karena mekanisme penandatanganan gpg Anda belum dikonfigurasi.

Jika Anda baru menggunakan git, cobalah membuatnya bekerja terlebih dahulu tanpa masuk GPG terlebih dahulu, lalu tambahkan masuk nanti jika Anda benar-benar membutuhkannya.

Anda dapat memverifikasi bagaimana git Anda dikonfigurasi sehubungan dengan gpg dengan melakukan:

git config -l | grep gpg

Yang dapat menghasilkan nol atau lebih garis, termasuk:

commit.gpgsign=true

Jika "commit.gpgsign" benar, maka Anda mengaktifkan penandatanganan gpg. Nonaktifkan dengan:

git config --global --unset commit.gpgsign

Kemudian coba jalankan komit Anda lagi. Sekarang seharusnya berjalan tanpa penandatanganan gpg. Setelah git dasar berfungsi, Anda harus mencoba menambahkan gpg yang masuk kembali ke dalam campuran.


12
Luar biasa! git config --global --unset commit.gpgsignbekerja untuk saya :)
hpaknia

Wow!! itu bekerja untuk saya: git config --global --unset commit.gpgsign
Hardy Mathew

32

Lihat @sontonbarker, dan solusi @Xavier Ho, saya memecahkan masalah saya melalui langkah-langkah berikut.

Asumsikan gpg2 diinstal oleh minuman,

git config --global gpg.program gpg2
brew install pinentry
gpgconf --kill gpg-agent
gpg2 -K --keyid-format SHORT
// no key found then generate new one
gpg2 --gen-key

gpg2 -K --keyid-format SHORT 

           

... /. gnupg / pubring.gpg

sec rsa2048 / 0A61C6FC 2017-06-29 [SC] [kedaluwarsa: 2019-06-29]

git config --global user.signingkey 0A61C6FC

Diingatkan oleh rekan saya, perlu ditambahkan

export GPG_TTY=$(tty)

ke ~ / .zshrc jika menggunakan zsh, atau tambahkan ke ~ / .bash_profile


Untuk macOS,

gpg2 dikombinasikan dengan gpg dalam minuman dan karenanya perintah gpg diarahkan ke gpg2

brew install gpg2

info pembuatan gpg

gnupg: stable 2.2.6 (botol)

git config --global gpg.program gpg
gpg -K --keyid-format SHORT 

dan ada pinentry-mac untuk entri frasa sandi

brew install pinentry-mac
vim ~/.gnupg/gpg-agent.conf

Tambahkan baris

pinentry-program / usr / local / bin / pinentry-mac

Diingatkan oleh rekan saya, perlu ditambahkan

export GPG_TTY=$(tty)

ke ~ / .zshrc jika menggunakan zsh, atau tambahkan ke ~ / .bash_profile


1
macOS 10.15 (Catalina) dikirimkan bersama GnuPG versi 2.2.17 sehingga tidak perlu menginstalnya secara terpisah kecuali Anda berencana untuk mengelola pembaruan sendiri.
Josh Habdas

18

Saya menggunakannya. Ini memiliki dukungan untuk zsha dan berfungsi di Windows Subsystem untuk Linux:

export GPG_TTY=$(tty)

2
Saya menggunakan zsh di MacOS Catalina dan ini adalah satu-satunya perubahan yang saya butuhkan untuk membuatnya bekerja. Terima kasih.
JP Lew

Saya menerima kesalahan dalam OP setelah menyalin kunci saya ke lingkungan WSL saya, ternyata saya perlu melakukan ini untuk memberikan prompt untuk frasa sandi pada kunci. Terima kasih.
Narwic

10

Periksa kunci Anda untuk kedaluwarsa. Setelah Anda memperbaiki tanggal kedaluwarsa (tidak perlu membuat kunci baru kecuali jika Anda mau), gitakan berfungsi seperti biasa.

Salah satu cara untuk memperbaiki kunci yang kadaluarsa:

(Catatan: $mewakili prompt baris perintah, ketikkan perintah setelah prompt; tekan Enter setelah setiap perintah)

$ gpg2 --list-keysuntuk menemukan tombol yang sesuai id (karakter setelah \pada pubbaris)

$ gpg2 --edit-key <key id> - ini membuka shell gpg, dengan prompt berubah menjadi gpg>

gpg> expire - ikuti instruksi untuk menetapkan tanggal kedaluwarsa baru untuk kunci utama

Selanjutnya, jika ada subkunci yang kedaluwarsa ( subtayang di telepon), atur ulang tanggal kedaluwarsa mereka juga:

gpg> key 1- pilih subkey pertama gpg> expire- ikuti instruksi untuk mengatur tanggal kedaluwarsa baru untuk subkey

Ulangi untuk setiap subkunci berikutnya, sesuai kebutuhan.


Saya mengalami masalah ini setiap kali saya mencoba menjalankan kunci gpg yang tidak memiliki tanggal kedaluwarsa. Untuk beberapa alasan git tidak suka itu. Menggunakan metode ini untuk menambahkan tanggal kedaluwarsa (tidak peduli seberapa jauh di masa depan) tampaknya menyelesaikan masalah.
some_guy632

Jangan lupa mengetik savedi gpg prompt setelah selesai!
daviewales

5

Ini bekerja untuk saya di ubuntu 18.04

Periksa kunci gpg Anda

gpg -K --keyid-format LONG

jika Anda mendapatkan respons kosong, buat kunci GPG

gpg --generate-key

jalankan kembali perintah pertama, Anda harus mendapatkan output sebagai:

sec   rsa3072/95A854E0593B3214 2019-05-06 [SC] [expires: 2021-05-05]
      AF2F7514568DC26B0EB97B9595A854E0593B74D8
uid                 [ultimate] yourname<your_email>
ssb   rsa3072/EFD326E6C611117C 2019-05-06 [E] [expires: 2021-05-05]

mengatur kunci git bernyanyi

git config --global user.singingkey 95A854E0593B3214

maka kamu baik untuk pergi! (--global adalah opsional)

Atau jika Anda tidak keberatan masuk dengan kunci ssh Anda

git config commit.gpgsign false

perhatikan bahwa ini tidak direkomendasikan karena masalah keamanan menurut pertanyaan ini di sini dan di sini


"Atau jika Anda tidak keberatan menandatangani dengan kunci ssh Anda," apa yang harus dilakukan ssh dengan menandatangani?
riffraff

SSH tidak ada hubungannya dengan penandatanganan komitmen. Mereka merujuk pada mematikan penandatanganan komitmen GPG, dan bergantung pada penggunaan kunci SSH untuk mengotentikasi ketika Anda benar-benar mendorong komit Anda ke server git. Anda dapat mendorong (dan ini sangat umum) untuk mendorong komitmen yang tidak ditandatangani menggunakan otentikasi SSH.
phouse512

4

Saya harus memperbaiki gpg.program ke jalur absolut ke gpg:

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

Saya menggunakan Windows dengan cygwin.


3
Ini solusi untuk saya. Saya telah menginstal gnupg menggunakan cokelat.
Alex S

Terima kasih, bekerja untuk saya juga. Saya telah melakukanchoco install gpg4win
Gokul NC

4

Larutan:

Issue: Disabled loopback pinentry mode

Untuk mengatasi masalah ini, Anda harus mengaktifkan mode pinback loopback di ~ / .gnupg / gpg.conf :

cat <<'EOF' >> ~/.gnupg/gpg.conf

use-agent 
pinentry-mode loopback

EOF

Dan juga di ~ / .gnupg / gpg-agent.conf (buat file jika belum ada):

cat <<'EOF' >> ~/.gnupg/gpg-agent.conf

allow-loopback-pinentry

EOF

Kemudian restart agen dengan echo RELOADAGENT | gpg-connect-agentdan Anda harus pergi dengan baik!

Sumber


1
Wow, setelah menghabiskan berjam-jam mencoba setiap solusi yang mungkin, ini memperbaiki masalah saya, terima kasih!
Matt

Sama-sama. Berkat sumbernya sebenarnya. Saya terjebak dengan ini juga.
Rahul Thakur

3

Kesalahan ini juga dapat terjadi ketika kunci GPG Anda telah kedaluwarsa. Membuat kunci baru dan menambahkannya ke Git harus menyelesaikan ini.


3

Saya mengalami masalah ini setelah memutakhirkan ke gnupg 2.x. Akan terlihat bahwa gpg2 mereferensikan kunci secara berbeda: Saya masih punya signingkey = ABC98F11(gpg v1 setting) di ~/.gitconfig. Pengidentifikasi utama untuk gpg2 lebih panjang. Carilah merekagpg --list-secret-keys


1

Saya telah membuat gitkunci dengan 3 kunci terpisah untuk certify/ sign/ encrypt& kunci ditampilkan sebagai kedaluwarsa di masa mendatang (setelah bekerja dengan baik selama beberapa hari):

pub   rsa4096/4CD1E9DA 2017-04-26 [C] [expired: 2017-04-28]
      Key fingerprint = 4670 59C1 7592 08B8 7FA5  313B 2A42 B6A6 4CD1 E9DA
uid         [ expired] Stuart Cardall (GIT Development Keys) <xxxxxx>
sub   rsa4096/5195E715 2017-04-26 [E] [expired: 2019-04-26]
sub   rsa4096/DB74C297 2017-04-26 [S] [expired: 2019-04-26]
sub   rsa2048/A3913A3C 2017-04-28 [] [expired: never     ]

membuat kunci baru tanpa menambahkan subkunci terpisah untuk menyelesaikan masalah.


1

Mungkin konfigurasi Git Anda disetel gpgsign = true . Coba setel ke false jika Anda tidak ingin menetapkan komitmen Anda. Buka folder repositori Anda dan ubah file

nano .git / config

Dari ini...

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@bitbucket.org:yourrepo/project.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[user]
    signingkey = <GPG-KEY>
[commit]
    gpgsign = true

Untuk ini...

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = git@bitbucket.org:yourrepo/project.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[user]
    signingkey = <GPG-KEY>
[commit]
    gpgsign = false

1

Bagi saya kesalahan ini mulai terjadi git tag -spada Debian GNU / Linux ketika saya beralih dari pinentry-gnome3ke pinentry-curses(menggunakan update-alternatives --config pinentry) untuk akses jarak jauh yang lebih mudah. Ini hanya terjadi dengan git tag -s, bukan dengan gpg(misgpg --clearsign ) itu sendiri.

Satu-satunya perubahan yang diperlukan untuk membuatnya berfungsi kembali dalam hal ini adalah menambahkan export GPG_TTY=$(tty)ke file startup shell saya.

Namun saya tidak mendapatkan pesan kesalahan "Ioctl untuk perangkat" yang tidak pantas yang disebutkan sebagai indikator untuk perbaikan ini di jawaban lain untuk pertanyaan ini.

Catatan: Karena penyebab untuk mendapatkan kesalahan ini sangat berbeda dari yang menyarankan export GPG_TTY=$(tty)sebelumnya (biasanya sebagai petunjuk tambahan) dalam jawaban lain untuk pertanyaan ini, saya memutuskan pertanyaan ini membutuhkan jawaban lain yang menyebutkan bahwa export GPG_TTY=$(tty)mungkin merupakan perbaikan utama dan satu-satunya hal yang diperlukan dalam beberapa kasus.


Terima kasih! update-alternatives --config pinentrymelakukannya untukku. Saya SSH akan masuk ke desktop saya dan pinentrydisetel ke /usr/bin/pinentry-gnome3(yang seharusnya memiliki fallback TTY ketika SSH masuk atau ketika beralih ke konsol virtual). Tapi ternyata itu tidak berhasil. Pengaturan default untuk /usr/bin/pinentry-ttymelakukan trik untuk saya. Saya mungkin harus mengaturnya kembali ketika saya kembali ke desktop saya, tetapi, untuk saat ini, saya baik-baik saja. export GPG_TTY=$(tty)tidak cukup. Saya melakukannya tetapi harus beralih pinentrysebelum saya bisa menandatangani komit saya.
Karl Wilbur

1

Apa yang dipecahkan untuk saya adalah memastikan nama kunci cocok dengan nama pengguna git saya. Saya menganggap email harus cocok juga. Ini mungkin ada hubungannya dengan saya menggunakan GPG KeyChain di Mac saya. Tidak yakin.

Saya pikir saya memberi nama kunci ketika saya mengisi ini, tapi saya kira itu meminta nama saya (git nama pengguna).

Bentuk Keychain GPG


Sayang sekali jawaban ini sangat jauh di belakang sehingga banyak yang tidak akan ke sini mencari masalah mereka.
MaciekS

1

Saya memiliki kesalahan ini pada makro - untuk mencoba dan memecahkan masalah saya mencoba daftar kunci untuk melihat apakah mereka telah kadaluwarsa menggunakan gpg2 --list-keys- saya memverifikasi bahwa kunci belum kedaluwarsa dan bahwa kunci yang tepat telah diatur dalam konfigurasi saya menggunakangit config --global user.signingkey .

Setelah saya menjalankan perintah-perintah itu, saya tiba-tiba dapat melakukan commit yang ditandatangani lagi tanpa masalah. Saya tidak mengubah file atau kunci konfigurasi saya - Saya bahkan tidak membuat instance Terminal baru. Sepertinya gpg2 entah bagaimana berada dalam keadaan aneh di mac saya.


0

Saya memecahkan masalah menginstal brew install gpg2kemudian melakukangit config --global gpg.program gpg2


0

Kesalahan yang sama juga dapat disebabkan ketika Anda telah kedaluwarsa pada konfigurasi git Anda.

Silakan periksa konten cat .git/configdan cari signingkeynilainya dan periksa apakah sudah kadaluarsa. Jika ya perbarui dengan yang baru.


0

Jika Anda menggunakan smart card / yubikey untuk menyimpan kunci GPG Anda dan Anda mengatur signkeykonfigurasi git dengan kunci yang disimpan dalam kartu (dan semua jawaban di atas tampaknya tidak menyelesaikan masalah Anda), PIN kartu yang diblokir mungkin adalah akar penyebab masalah ini.

Untuk memeriksa PIN yang diblokir:

gpg --card-status

Jika penghitung mirip dengan

Reader ...........: Yubico YubiKey
PIN retry counter : 3 0 3

Kemudian PIN Anda diblokir (setelah 3 percobaan gagal).

Untuk membuka blokir PIN:

gpg --card-edit
gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. … detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 2
PIN unblocked and new PIN set.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

0

Bagi saya yang sederhana brew unintstall gnupg && brew cask reinstall gpg-suitemenyelesaikan masalah.

Mencopot pemasangan (dalam kasus saya) secara manual gpg homebrew-istalled dan menginstal ulang seluruh GPG Suite.


0

Dalam kasus saya, saya memiliki konfigurasi gpg campuran dan konfigurasi smimesign yang diberikan dalam dokumentasi penandatanganan komitmen di sini: https://help.github.com/en/github/authenticating-to-github/telling-git-about-your-signing- kunci

Setelah mengerjakannya selama berjam-jam, saya menemukan cara terbaik untuk memperbaikinya adalah membatalkan semua yang terkait dengan gpg, dan mengkonfigurasi ulang gpg.

Seperti disebutkan dalam jawaban @Jason Thrasher, temukan semua konfigurasi git yang terkait dengan gpg menggunakan:

git config -l | grep gpg

Kemudian hapus semua yang dapat dilakukan secara lokal dan lokal menggunakan:

git config --global --unset <config_name>
git config --local --unset <config_name>

Kemudian konfigurasi ulang mengikuti dokumentasi resmi yang diberikan di atas. Semoga ini membantu.


Juga, saya menggunakan gpg2
Shubham Gupta

0

Jika Anda memasang pinentry dan pengaturan gpg sebelumnya, dan berhenti bekerja entah dari mana:

Periksa apakah gpg Anda berfungsi:

echo "test" | gpg --clearsign

Jika dikatakan gpg: signing failed: No pinentry, mulai ulang klien daemon gpg, yang macet dari waktu ke waktu:

gpgconf --kill gpg-agent

Sekarang seharusnya sudah berfungsi:

echo "test" | gpg --clearsign

0

Dalam kasus saya, kesalahan ini terjadi ketika berjalan git commitdi tmuxjendela kecil yang tidak dapat masuk ke prompt frasa sandi.

$ echo "test" | gpg --clearsign
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
gpg: signing failed: Screen or window too small
gpg: [stdin]: clear-sign failed: Screen or window too small

-6

Ini akan membantu Anda untuk menyingkirkannya

git config commit.gpgsign false


1
Saya tidak mengerti suara turun, itu memecahkan masalah yang diusulkan seperti pesona bagi saya.
Jms

2
Perintah ini harus dihindari. Itu hanya akan menghapus persyaratan untuk menandatangani git commit, bukan menyelesaikan masalah otentikasi orang yang membuat komit.
Kyle
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.