3
votes

Travis CI: Comment puis-je échapper à mon mot de passe pour que `travis encrypt` fonctionne?

Les documents de chiffrement travis mentionnez que je dois échapper à mon mot de passe avant de le chiffrer:

Remarque sur l'échappement de certains symboles

Lorsque vous utilisez travis encrypt pour crypter des données sensibles, il est important de noter qu'elles seront traitées comme une instruction bash. Cela signifie que le secret que vous cryptez ne devrait pas provoquer d'erreurs lorsque bash l'analyse. Si les données sont incomplètes, bash videra l'instruction d'erreur dans le journal, qui contient des parties de vos données sensibles.

Ainsi, vous devez échapper les caractères spéciaux tels que les accolades, les parenthèses, les barres obliques inverses et les symboles de barre verticale. Par exemple, lorsque vous souhaitez affecter la chaîne 6 & a (5! 1Ab \ à FOO , vous devez exécuter:

travis encrypt "FOO = 6 \\ & a \\ (5 \\! 1Ab \\\\"

La réponse à bash semble tourner autour de printf "% q" , mais c'est toujours aussi compliqué de comprendre comment câbler printf avec le travis cli.

Quelle est la base de référence pour que travis encrypt fasse ce qu'il est censé faire?

Je veux dire, je veux coller le nom de ma variable et sa valeur et être sûr qu'elle sera chiffrée correctement, sans avoir à me soucier de l'échappement de bash. Nous pouvons rester avec l'exemple ci-dessus, en supposant que je veuille attribuer la chaîne 6 & a (5! 1Ab \ à la variable FOO .

Et tant que nous y sommes, quelle serait la ligne unique correspondante pour travis env set ? Cela aiderait ceux qui se battent avec l'erreur données trop volumineuses .


3 commentaires

Je pense que tout ce dont vous avez besoin est printf -v esc_foo '% q' "$ foo" et maintenant esc_foo contient une chaîne correctement échappée


"Traité comme une instruction bash " me fait penser qu'il s'agit simplement d'appeler eval sur l'argument, ce qui signifie que je réfléchirais longuement et sérieusement à son utilisation du tout < / i>.


Aussi, pourquoi suggéreraient-ils ce cauchemar infesté de barres obliques inverses au lieu de travis encrypt "FOO = '6 & a (5! 1Ab \'" ?


3 Réponses :


2
votes

Quelle est la base de référence pour que travis encrypt fasse ce qu'il est censé faire?

Je veux dire, je veux coller le nom de ma variable et sa valeur et être sûr qu'elle sera chiffrée correctement, sans avoir à me soucier de l'échappement de bash.

Ceci est généralement impossible, car si la valeur doit être insérée dans la ligne de commande, une sorte de guillemet est indispensable, par conséquent au moins un caractère de guillemet (s'il est autorisé à apparaître dans la valeur) doit être traité spécialement et ne peut pas simplement être collé; c'est la raison pour laquelle inclure la valeur dans ' ' ne fonctionne pas si ' apparaît dans la valeur (et sûrement ' code> doit être autorisé dans un mot de passe). Ainsi, l'exigence de pouvoir coller la valeur ne peut être remplie que si l'exigence d'un est supprimée et que la valeur est fournie en entrée.
Ensuite, puisque la commande travis encrypt nécessite une citation supplémentaire de l'argument (peut-être parce que, comme le pense chepner, eval est appelé), nous pouvons fournir cette citation avec printf % q , e. g.

read -r; travis encrypt "$(printf %q "$REPLY")"
FOO=6&a(5!1Ab\

(la ligne en gras à coller).

Que diriez-vous de mettre VAR = VALUE dans l'instruction read pour tout rassembler? read -r , collez FOO = 6 & a (5! 1Ab \ et enfin travis encrypt "$ (printf% q" $ REPLY ")" .

Bien sûr, cela fonctionnerait également.

De plus, n'y a-t-il vraiment aucun moyen de rediriger le résultat de read -r vers travis encrypt ?

Si vous voulez dire littéralement diriger , alors non, il n'y a aucun moyen de diriger quelque chose vers une commande qui n'attend que des arguments. Mais si vous vous demandez simplement si nous pouvons concaténer les commandes, alors oui, nous pouvons aussi écrire e. g.

read -r
6&a(5!1Ab\
travis encrypt "$(printf %q "FOO=$REPLY")"

7 commentaires

Merci beaucoup! Que diriez-vous de mettre VAR = VALUE dans l'instruction read pour tout rassembler? read -r , collez FOO = 6 & a (5! 1Ab \ et enfin travis encrypt "$ (printf% q" $ REPLY ")" De plus, n'y a-t-il vraiment aucun moyen de canaliser le résultat de read -r vers travis encrypt ?


Que diriez-vous d'enchaîner les instructions avec && ? Ce serait: read -r && travis encrypt "$ (printf% q" $ REPLY ")" , puis collez FOO = 6 & a (5! 1Ab \ . Ce serait satisfaire à l'exigence d'une ligne unique pour moi. Quelque chose me manque-t-il?


@Pierre F - Je viens d'intégrer les questions de votre premier commentaire dans ma réponse. Votre idée d'utiliser && est encore meilleure que mon ; .


Merci pour la mise à jour @Armali. En ce qui concerne votre argument sur la gestion du caractère de guillemet en particulier: cette solution fonctionnerait-elle toujours, même lorsque la ligne contient le caractère ", ou devons-nous échapper à ce caractère une fois de plus pour être du bon côté?


@Pierre F - Cela fonctionne aussi avec ", car une citation contenue n'est pas interprétée lors de l'expansion de $ REPLY , et est ensuite échappée par printf% q < / code> comme les autres caractères spéciaux.


Parfait! Ensuite, je suppose que nous avons la solution. Problème résolu!


Il peut être judicieux d'exécuter unset REPLY après l'étape de chiffrement.



4
votes

Basé sur réponse d'Armali :

FOO=6&a(5!1Ab\

puis collez votre variable et sa valeur :

read -r && travis encrypt "$(printf %q "$REPLY")"


0 commentaires

2
votes

il est tellement plus facile de simplement base64 la chaîne et de la décoder dans votre build. enregistre tous les problèmes liés à la fuite dans travis.

Travis, et tout autre service CI / CD, permet de stocker secrètement des variables d'environnement secrètes pour être utilisées pour chaque build. Dans la configuration de la construction de vos projets, ajoutez une option de variable d'environnement. Pour faire écho au mot de passe dans cli à utiliser pour base64, vous devez toujours échapper à la chaîne car elle doit être évaluée par bash. créez un fichier temporaire avec votre mot de passe. Ensuite:

cat / tmp / secret | base64 -w 0

copiez la chaîne et collez-la dans le champ de valeur du paramètre travis ci env var

dans le fichier .travis.yaml pour récupérer le secret simplement:

echo $ SECRET | base64 -d

Il peut cependant y avoir des cas extrêmes, mais cela devrait résoudre la plupart des cas d'utilisation.


2 commentaires

C'est aussi une bonne idée, merci. Je suppose que la réponse serait encore plus utile pour les autres utilisateurs de débordement de pile avec les commandes correspondantes: Comment encoder et crypter en base64 en ligne de commande, et comment décrypter et décoder en base64 la variable d'environnement dans .travis .yml


Merci d'avoir mis à jour la réponse avec la commande base64 . Je ne sais pas comment cela pourrait être utilisé, par exemple pour crypter une variable destinée à être utilisée directement comme un mot de passe de déploiement. Avec la réponse d'Armali, vous pouvez directement travis encrypt --add deploy.password .