如何在Linux中解码ldif文件中的base64文本?

如何在Linux中解码ldif文件中的base64文本?

我需要解码 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' 

相关内容