我需要解码 ldif (openldap) 备份中嵌入的 Base64。
我发现这里一种连接以空格开头的行的方法。
然后,基于这关于“如何在 Linux 中解码 xml 文件中的 base64 文本?”的问题我想解码 Base64 字符串,但无法让它工作。
我的脚本是:
#Join lines starting with space
sed -n 'H; ${ x; s/\n//; s/\n //g; p}' "$FILE" > "$FILE_JOINED"
#Decode lines containing base64 (those with double colon)
sed -r 's/(:: )([[:graph:]]+)/\1 '"`grep -oP ':: [[:graph:]]+' "$FILE_JOINED" |cut -c 4- | base64 -d`"'/g' "$FILE_JOINED"
当我执行此操作时,出现以下错误:
sed: -e expression #1, char 297: unknown option to `s'
这里我添加了“$FILE_JOINED”内容的示例:
dn: olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=proxy,dc=ldap
olcAccess:: b25lIHZhbHVlCg==
olcAccess: {1}to filter=(&(objectClass=securityPrincipal)(!(pwdAccountLockedTime=*))) attrs=userPassword,shadowLastChange by dn="cn=Man1,ou=local,dc=proxy,dc=ldap" write by anonymous auth by self write by * none
olcAccess: {2} to * by * read
olcAddContentAcl: FALSE
olcLastMod: TRUE
olcMaxDerefDepth: 15
olcReadOnly: FALSE
olcRootDN: cn=Man1,ou=local,dc=proxy,dc=ldap
olcRootPW:: dmFsdWUgdHdvCg==
olcSyncUseSubentry: FALSE
olcSyncrepl:: dmFsdWUgdGhyZWUK
olcMirrorMode: TRUE
dn: olcOverlay={0}unique,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcUniqueConfig
(请注意,第二个命令留下双冒号 ( ::
),而不是只留下一个冒号。我这样做的目的是为了能够轻松地 grep 输出。稍后我会修复这个问题)
第二个命令中有一个 grep:它如何“选择”正确的行来解码所有文件内容?
这是单独命令的结果grep
:
# grep -oP ':: [[:graph:]]+' x |cut -c 4- | base64 -d
one value
value two
value three
有人可以告诉我如何解码 ldif 文件中包含的 Base64 值吗?
答案1
我找到了一种方法来做到这一点:
sed -r 's/(.*:)(: )([[:graph:]]+)/echo "\1 `echo -n '\\3' |base64 -d`"/ge' "$FILE_JOINED"
如果你想折叠长线,(基于这个答案)
sed -r 's/(.*:)(: )([[:graph:]]+)/echo "\1 `echo -n '\\3' |base64 -d`"/ge' "$FILE_JOINED" | \
awk -v WIDTH=76 '
{
space="";
while (length>WIDTH) {
print substr($0,1,WIDTH);
space=" ";
$0=space substr($0,WIDTH+1);
}
print;
}
'
如果有人需要,这里是整个脚本。
[请注意,脚本的 AWK 命令只留下未包含在前一行中的注释行(以“#”开头的行)]:
#!/bin/bash
FILE=$1
DIR=`dirname $FILE`
pushd $DIR
WIDTH=76
FILE=`basename $FILE`
FILE_JOINED="`basename $FILE .ldif`-una-linea.ldif"
FILE_DECODED="`basename $FILE .ldif`-decodificado.ldif"
echo
echo DIR: $DIR
echo FILE: $FILE
echo FILE_JOINED: $FILE_JOINED
echo FILE_DECODED: $FILE_DECODED
sed -n 'H; ${ x; s/\n//; s/\n //g; p}' "$FILE" > "$FILE_JOINED"
sed -r 's/(.*:)(: )([[:graph:]]+)/echo "\1 `echo -n '\\3' |base64 -d`"/ge' "$FILE_JOINED" | \
awk -v WIDTH=$WIDTH -v space=" " '
/^[^#]/ {
while (length>WIDTH) {
print substr($0,1,WIDTH);
$0=space substr($0,WIDTH+1);
}
print;
}
/^[#]|^$/ {
print;
}
' > $FILE_DECODED
rm $FILE_JOINED
更新20180830
shell 扩展出现错误。它没有保留“*”字符,而是用文件列表替换它们。
修复方法是在第一个 echo 命令中添加双引号。我已经修复了之前显示的命令和脚本。
这错误命令是:
sed -r 's/(.*:)(: )([[:graph:]]+)/echo \1 `echo -n '\\3' |base64 -d`/ge' "$FILE_JOINED"
更新20180830-b
AWK 命令也修改了注释,这是不应该的。
这以前的命令是:
awk -v WIDTH=$WIDTH '
BEGIN {
space=" ";
}
{
while (length>WIDTH) {
print substr($0,1,WIDTH);
$0=space substr($0,WIDTH+1);
}
print;
}
' > $FILE_DECODED
答案2
基于你很酷的 base64-stuff,我将解包和解码结合到管道命令中:
sed -n ':loop N; s/\n //; t loop; P; D' | sed -r 's/(.*:)(: )([[:graph:]]+)/echo "\1 `echo -n '\\3' |base64 -d`"/ge'