LINUX.ORG.RU

Экранирование sed (random input)

 , ,


0

1

Всем привет, есть скрипт, который генерирует кучу 16-значных паролей, затем что-то делает с ними, например заменяет старые пароли на новые в конфигах:

NEWPASS=`cat /dev/urandom | tr -dc [:graph:] | head -c${1:-16}`

Подробности дальнейшей обработки этого я опущу, важно следующее: этот NEWPASS нужно запихнуть в конфиг, в котором уже есть старый пароль, старый пароль генерировался аналогично. Замена старого пароля на новый происходит так:

sed -ie 's/'$OLDPASS'/'$NEWPASS'/' /some/password/file

И всё было ничего, до момента, когда:

OLDPASS=>XGG3m36H;~;8ftL
NEWPASS=m]0gv#>0&:oSu(au

т.е. XGG3m36H;~;8ftL лежит в конфиге, а когда sed пытается его заменить на m]0gv#>0&:oSu(au , то в итоге получается:

m]0gv#>0>XGG3m36H;~;8ftL:oSu(au

Подскажите, как можно экранировать такое? Вставить костыли в виде парсинга свежесгенеренного пароля не предлагать, как и использование perl, php, c++ , упрощение пароля до букв+цифр

★★★★★
Ответ на: комментарий от shell-script

Но я в нём ни бум-бум, а пихать «однострочник на perl» в сервак под честное слово анонимуса с лора не хочется.

Pyzia ★★★★★
() автор топика

какой формат файла?

удалять старую строку по логину/id/..., а не по старому паролю, и генерить новую строку с новым паролем

anonymous
()
NEWPASS="$(pwgen -sy 16 1 | tee /some/password/file)"
r3lgar ★★★★★
()
Последнее исправление: r3lgar (всего исправлений: 1)

У тебя что-то не так в подходе. Покажи кусок файла с паролями.

Kroz ★★★★★
()
OLDPASS="$(  sed 's/\([]$.*\\[^/]\)/\\\1/g' <<< "$OLDPASS" )"

Но мне всё равно не нравится твой подход. Возможно я чего-то не знаю.

Kroz ★★★★★
()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Pyzia

Ну, например, если переделать твой скрипт как-нибудь так, можно обойтись без непонятных однострочников:

#!/bin/bash

FILE=$1

export OLDPASS='>XGG3m36H;~;8ftL'
export NEWPASS='m]0gv#>0&:oSu(au'
perl -pi -ne 's/$ENV{OLDPASS}/$ENV{NEWPASS}/g' $FILE

shell-script ★★★★★
()
$ printf -v var '%q' 'm]0gv#>0&:oSu(au'
$ echo "$var"
m\]0gv#\>0\&:oSu\(au
vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от DonkeyHot

остальной скрипт от неприятностей.

Вы сами то пробовали запускать? base64 не имеет в выводе точку и минус в tr надо либо в начале либо в конце аргумента и у dd надо установить размер блока, который по умолчанию 512 и stderr надо подавить...

NEWPASS=`dd if=/dev/urandom bs=1 count=18 status=none | base64 | tr /+ _-`
vodz ★★★★★
()
Ответ на: комментарий от DonkeyHot

Вам идеи недостаточно, рабочую копипасту подавать?

Мне? Мне не надо, я сделал для себя паролегенератор на C. Но вы же дали совет с однострочником, который можно проверить за секунду и сделали в нём 4 ошибки.

vodz ★★★★★
()
Ответ на: комментарий от vodz

проверить за секунду и сделали в нём 4 ошибки

Это же не в job-форуме, тут можно.

DonkeyHot ★★★★★
()
pthSomePassFile='/some/password/file'
passFileCont=$(<"$pthSomePassFile")
echo "${passFileCont//$OLDPASS/$NEWPASS}" > "$pthSomePassFile"

Enjoy!

DRVTiny ★★★★★
()
Ответ на: комментарий от vodz

Щас с говнокода.ру паст накидаю, чтоб таких аутистов код-гольфистов порвало.

anonymous
()
Ответ на: комментарий от Pyzia

Соврал, сработало 1 раз, затем заткнулось, когда $OLDPASS стал y>+-2WFdMke$uxQB

Кароче, не работает, если в пароле есть символ $.

Pyzia ★★★★★
() автор топика
Последнее исправление: Pyzia (всего исправлений: 1)
Ответ на: комментарий от Pyzia

Кароче, не работает, если в пароле есть символ $.

Я же вам уже дал рабочий метод записи в переменную с экранированием. А ваш вызов sed-а, как обычно тут бывает - смешон. Зачем экранировать обычные символы s/ ? В чём трудность написать аргумент с переменными в двойные кавычки?

$ printf -v NEWPASS '%q' '+-2WFdMke$uxQB'
$ echo "$NEWPASS"
+-2WFdMke\$uxQB
$ sed -ie "s/$OLDPASS/$NEWPASS/" "$passwdfile"

vodz ★★★★★
()
Ответ на: комментарий от vodz

Сначала вроде работало, но потом...

Мой скрипт (его кусок):

CONFIGFILE="/etc/some-file"
NEWPASS=$(cat /dev/urandom | tr -dc [:graph:] | head -c${1:-16}) 
OLDPASS=$(cat $CONFIGFILE | grep DB_NAME | grep -o '".*"' | sed 's/"//g')
printf -v NEWPASS '%q' $NEWPASS
sed -ie "s/$OLDPASS/$NEWPASS/" /etc/some-file
Вывод bash -x чучуть порезал лишнее:
+ NEWPASS='M!~6?1>%FU`\/NGT'
+ OLDPASS='rsOG,9:b&M&j\K_'
+ printf -v NEWPASS %q 'M!~6?1>%FU`\/NGT'
+ sed -ie 's/rsOG,9:b&M&j\K_/M\!~6\?1\>%FU\`\\/NGT/' /etc/some-file
sed: -e expression #1, char 37: unknown option to `s'

Что-то лыжи не едут( Но спасибо за вашу помощь!

Pyzia ★★★★★
() автор топика
Ответ на: комментарий от Pyzia

Что-то лыжи не едут

Потому что символ / - не специальный и не экранируется. Вам надо выбрать символ для ограничения regex s/old/new/ вместо '/' -другой, который не генерирует tr -dc [:graph:]. Да и OLDPASS надо преобразовыванную.

$ OLDPASS='rsOG,9:b&M&j\K_'
$ NEWPASS='M!~6?1>%FU`\/NGT'
$ printf -v NEWPASS %q "$NEWPASS"
$ echo "$NEWPASS"
M\!~6\?1\>%FU\`\\/NGT
$ printf -v OLDPASS %q "$OLDPASS"
$ SP=$'\001'
$ sed -ie "s${SP}${OLDPASS}${SP}${NEWPASS}${SP}" "$passwdfile"

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)

Всем большое спасибо, решил ограничить сложность пароля:

cat /dev/urandom | tr -dc [:alnum:]'!@^*,' | head -c${1:-16}

Pyzia ★★★★★
() автор топика
Ответ на: комментарий от vodz

Я прогнал цикл на 1000 итераций и с ними проблем не возникло, делал через ваш способ (printf)

Pyzia ★★★★★
() автор топика
Ответ на: комментарий от vodz

Соврал! Ошибка в скрипте, я прогонял вариант без спецсимволов. Кажется, будет пароль на 32 символа, чтоб покрыть нехватку спецсимволов.

Pyzia ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.