本文主要介紹如何在OpenHarmony系統(tǒng)下通過(guò)ndk工具移植OpenSSH-9.6p1。
安裝NDK工具
未編譯過(guò)ohos-sdk的話,先執(zhí)行下面的命令編譯sdk:
./build.sh --product-name ohos-sdk --ccache
編譯好ohos-sdk之后,可以直接從編譯路徑下拷貝到指定路徑,當(dāng)然也可以直接將out目錄下的ohos sdk的native路徑作為NDK的路徑。如果下載的public-sdk,也可以從壓縮包中解壓native的壓縮包(例如:native-linux-x64-4.0.10.13-Release.zip
)到指令路徑。這里以我們自行編譯的full-sdk下的native拷貝為例(不同的版本生成路徑可能會(huì)有差異):
mkdir -p /opt/sdk/ohos/native/
cp -r ${OHOS_SRC}/out/sdk/packages/ohos-sdk/linux/10/native/ /opt/sdk/ohos/native/4.0.10.13
之后使用ndk編譯時(shí),該路徑負(fù)責(zé)提供交叉編譯工具和sysroot等依賴。
交叉編譯zlib
zlib其實(shí)可以默認(rèn)使用ndk中自帶的庫(kù),這里也給出zlib的交叉編譯方式。
下載源碼和解壓:
wget https://www.zlib.net/zlib-1.3.tar.gz
tar -xf zlib-1.3.tar.gz
cd zlib-1.3
編寫(xiě)編譯腳本build.sh:
#!/bin/bash
set -e
if [ "$1" == "clean" ] || [ "$1" == "distclean" ];then
make $1
exit 0
fi
export OHOS_SDK_HONE=/opt/sdk/ohos
export OHOS_NATIVE_HOME=/opt/sdk/ohos/native/4.0.10.13
export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
export AR="$OHOS_NATIVE_HOME/llvm/bin/llvm-ar"
export AS="$OHOS_NATIVE_HOME/llvm/bin/llvm-as"
export LD="$OHOS_NATIVE_HOME/llvm/bin/ld.lld"
export RANLIB="$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib"
export STRIP="$OHOS_NATIVE_HOME/llvm/bin/llvm-strip"
export CC="$OHOS_NATIVE_HOME/llvm/bin/clang"
export NM="$OHOS_NATIVE_HOME/llvm/bin/llvm-nm"
export OBJDUMP="$OHOS_NATIVE_HOME/llvm/bin/llvm-objdump"
export CFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb"
export CPPFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot"
export LDFLAGS="--target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind"
./configure --prefix=${PWD}/_install --static
make && make install
執(zhí)行編譯命令:
bash build.sh distclean
bash build.sh
交叉編譯openssl
這里移植移植最新的v3.2.0版本的OpenSSL,測(cè)試過(guò)openssl-3.0.12也可以正常編譯。
下載源碼和解壓:
wget https://www.openssl.org/source/openssl-3.2.0.tar.gz
tar -xf openssl-3.2.0.tar.gz
cd openssl-3.2.0
編寫(xiě)編譯腳本build.sh:
#!/bin/bash
set -e
if [ "$1" == "clean" ] || [ "$1" == "distclean" ];then
make $1
exit 0
fi
export OHOS_SDK_HONE=/opt/sdk/ohos
export OHOS_NATIVE_HOME=/opt/sdk/ohos/native/4.0.10.13
export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
export AR="$OHOS_NATIVE_HOME/llvm/bin/llvm-ar"
export AS="$OHOS_NATIVE_HOME/llvm/bin/llvm-as"
export LD="$OHOS_NATIVE_HOME/llvm/bin/ld.lld"
export RANLIB="$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib"
export STRIP="$OHOS_NATIVE_HOME/llvm/bin/llvm-strip"
export CC="$OHOS_NATIVE_HOME/llvm/bin/clang"
export NM="$OHOS_NATIVE_HOME/llvm/bin/llvm-nm"
export OBJDUMP="$OHOS_NATIVE_HOME/llvm/bin/llvm-objdump"
export CFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb"
export CPPFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot"
export LDFLAGS="--target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind -L${PWD}/_install/lib"
#./Configure linux-armv4 --prefix=${PWD}/_install zlib no-asm no-shared no-unit-test no-tests
./Configure linux-armv4 --prefix=${PWD}/_install zlib no-asm shared no-unit-test no-tests
# remove library atomic
sed -i 's/-latomic//g' ./Makefile
# use static library crypto and ssl
sed -i 's/-lcrypto/libcrypto.a/g' ./Makefile
sed -i 's/-lssl/libssl.a/g' ./Makefile
make -j$(($(nproc)*2)) && make install
由于ohos ndk中不帶libatomic,編譯時(shí)會(huì)報(bào)錯(cuò),這里直接從自動(dòng)生成的Makefile中刪除atomic的依賴即可。另外我們希望openssh編譯時(shí)以靜態(tài)庫(kù)的方式來(lái)連接crypto和ssl庫(kù),所以這里可以考慮把這兩個(gè)庫(kù)直接改成靜態(tài)庫(kù)的方式連接,也可以不改,不改的話默認(rèn)鏈動(dòng)態(tài)庫(kù)。
執(zhí)行編譯命令:
bash build.sh distclean
bash build.sh
交叉編譯openssh
zlib和openssl編譯成功之后,就可以開(kāi)始編譯openssh了。
下載源碼和解壓:
wget https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.6p1.tar.gz
tar -xf openssh-9.6p1.tar.gz
cd openssh-9.6p1
編寫(xiě)編譯腳本build.sh:
#!/bin/bash
set -e
if [ "$1" == "clean" ] || [ "$1" == "distclean" ];then
make $1
exit 0
fi
export OHOS_SDK_HONE=/opt/sdk/ohos
export OHOS_NATIVE_HOME=/opt/sdk/ohos/native/4.0.10.13
export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
export AR="$OHOS_NATIVE_HOME/llvm/bin/llvm-ar"
export AS="$OHOS_NATIVE_HOME/llvm/bin/llvm-as"
export LD="$OHOS_NATIVE_HOME/llvm/bin/ld.lld"
export RANLIB="$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib"
export STRIP="$OHOS_NATIVE_HOME/llvm/bin/llvm-strip"
export CC="$OHOS_NATIVE_HOME/llvm/bin/clang"
export NM="$OHOS_NATIVE_HOME/llvm/bin/llvm-nm"
export OBJDUMP="$OHOS_NATIVE_HOME/llvm/bin/llvm-objdump"
export CFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb"
export CPPFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot"
export LDFLAGS="--target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind"
./configure --prefix=${PWD}/_install \
--target=arm-linux-ohos \
--host=arm-linux \
--sysconfdir=/etc/ssh \
--with-libs --with-zlib=${PWD}/../zlib-1.3/_install \
--with-ssl-dir=${PWD}/../openssl-3.2.0/_install \
--disable-etc-default-login \
${EXTOPTS}
make -j$(($(nproc)*2)) && make install
執(zhí)行編譯命令:
bash build.sh distclean
bash build.sh
報(bào)錯(cuò)1:
configure報(bào)錯(cuò)找不到libcrypto庫(kù),發(fā)現(xiàn)默認(rèn)會(huì)鏈動(dòng)態(tài)庫(kù),動(dòng)態(tài)庫(kù)不生成時(shí)靜態(tài)庫(kù)會(huì)優(yōu)先從sysroot中查找,此時(shí)會(huì)提示缺少很多符號(hào),解決方案是在LDFLAGS中追加libcrypto.a的靜態(tài)庫(kù)方式連接,以及指定zlib庫(kù)(libcrypto依賴zlib):
${PWD}/../openssl-3.0.12/_install/lib/libcrypto.a -lz
報(bào)錯(cuò)2:
/opt/sdk/ohos/native/4.0.10.13/llvm/bin/clang --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wextra -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/include -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../zlib-1.3/_install/include --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c rijndael.c -o rijndael.o
/opt/sdk/ohos/native/4.0.10.13/llvm/bin/clang --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wextra -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong -fPIC -I. -I.. -I. -I./.. -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/include -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../zlib-1.3/_install/include --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE -DHAVE_CONFIG_H -c getgrouplist.c
xcrypt.c:134:21: warning: call to undeclared function 'getspnam'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
struct spwd *spw = getspnam(pw->pw_name);
^
xcrypt.c:134:15: error: incompatible integer to pointer conversion initializing 'struct spwd *' with an expression of type 'int' [-Wint-conversion]
struct spwd *spw = getspnam(pw->pw_name);
^ ~~~~~~~~~~~~~~~~~~~~~
2 warnings and 1 error generated.
make[1]: *** [Makefile:106: xcrypt.o] Error 1
make[1]: *** Waiting for unfinished jobs....
這是因?yàn)閚dk目錄下的musl庫(kù)和頭文件shadow.h沒(méi)有支持這個(gè)函數(shù),查看源碼路徑third_party/musl以及out目錄下生成的libc.so,發(fā)現(xiàn)getspnam是支持的,只是sdk編譯時(shí)沒(méi)有帶而已。所以直接拷貝替換即可:
cp /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/shadow.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/shadow.h.bak
cp ${OHOS_SRC}/out/${PRODUCT}/obj/third_party/musl/usr/include/arm-linux-ohos/shadow.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/shadow.h
cp /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/lib/arm-linux-ohos/libc.so /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/lib/arm-linux-ohos/libc.so.bak
cp ${OHOS_SRC}/out/${PRODUCT}/obj/third_party/musl/usr/lib/arm-linux-ohos/libc.so /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/lib/arm-linux-ohos/libc.so
報(bào)錯(cuò)3:
/opt/sdk/ohos/native/4.0.10.13/llvm/bin/clang --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wextra -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/include -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../zlib-1.3/_install/include --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c ssh-ecdsa.c -o ssh-ecdsa.o
xcrypt.c:88:4: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(passwd, strlen(passwd));
^
xcrypt.c:117:12: warning: call to undeclared function 'crypt'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
crypted = crypt(password, salt);
^
xcrypt.c:117:10: error: incompatible integer to pointer conversion assigning to 'char *' from 'int' [-Wint-conversion]
crypted = crypt(password, salt);
^ ~~~~~~~~~~~~~~~~~~~~~
2 warnings and 1 error generated.
make[1]: *** [Makefile:106: xcrypt.o] Error 1
make[1]: *** Waiting for unfinished jobs....
sshbuf.c:189:3: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(buf->d, buf->alloc);
^
sshbuf.c:215:2: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(buf->d, buf->alloc);
^
/opt/sdk/ohos/native/4.0.10.13/llvm/bin/clang --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wextra -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-parameter -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/include -I/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../zlib-1.3/_install/include --target=arm-linux-ohos --sysroot=/opt/sdk/ohos/native/4.0.10.13/sysroot -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c ssh-ecdsa-sk.c -o ssh-ecdsa-sk.o
arc4random.c:123:2: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
^
xmalloc.c:67:12: warning: call to undeclared function 'reallocarray'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
new_ptr = reallocarray(ptr, nmemb, size);
^
xmalloc.c:67:10: error: incompatible integer to pointer conversion assigning to 'void *' from 'int' [-Wint-conversion]
new_ptr = reallocarray(ptr, nmemb, size);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
readpass.c:103:3: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(buf, sizeof(buf));
^
readpass.c:109:2: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(buf, sizeof(buf));
^
readpass.c:194:2: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(buf, sizeof(buf));
^
bcrypt_pbkdf.c:108:2: warning: call to undeclared function 'explicit_bzero'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
explicit_bzero(ciphertext, sizeof(ciphertext));
^
make: *** [Makefile:195: xmalloc.o] Error 1
make: *** Waiting for unfinished jobs....
explicit_bzero 隱式申明的函數(shù),由musl實(shí)現(xiàn),需要替換libc.so庫(kù)和頭文件string.h:
cp /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/string.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/string.h.bak
cp ${OHOS_SRC}/out/${PRODUCT}/obj/third_party/musl/usr/include/arm-linux-ohos/string.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/string.h
crypt需要替換libc.so庫(kù)和頭文件crypt.h:
cp /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/crypt.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/crypt.h.bak
cp ${OHOS_SRC}/out/${PRODUCT}/obj/third_party/musl/usr/include/arm-linux-ohos/crypt.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/crypt.h
reallocarray需要替換libc.so庫(kù)和頭文件stdlib.h:
cp /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/stdlib.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/stdlib.h.bak
cp ${OHOS_SRC}/out/${PRODUCT}/obj/third_party/musl/usr/include/arm-linux-ohos/stdlib.h /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/stdlib.h
報(bào)錯(cuò)4:
提示頭文件linux/socket.h和sys/socket.h中的結(jié)構(gòu)體sockaddr_storage重復(fù)定義:
In file included from port-net.c:46:
In file included from /opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/linux/if.h:23:
/opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/linux/socket.h:23:8: error: redefinition of 'sockaddr_storage'
struct sockaddr_storage {
^
/opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/sys/socket.h:377:8: note: previous definition is here
struct sockaddr_storage {
查看這兩個(gè)頭文件:
/opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/sys/socket.h
#ifndef __MUSL__
struct sockaddr_storage {
sa_family_t ss_family;
char __ss_padding[128-sizeof(long)-sizeof(sa_family_t)];
unsigned long __ss_align;
};
#endif
/opt/sdk/ohos/native/4.0.10.13/sysroot/usr/include/linux/socket.h
#ifndef _UAPI_LINUX_SOCKET_H
#define _UAPI_LINUX_SOCKET_H
#define _K_SS_MAXSIZE 128
typedef unsigned short __kernel_sa_family_t;
struct sockaddr_storage {
union {
struct {
__kernel_sa_family_t ss_family;
char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
};
void * __align;
};
};
#endif
可見(jiàn)沒(méi)有定義__MUSL__
宏時(shí),sys/socket.h
中的struct sockaddr_storage
定義和linux/socket.h
沖突了。定義__MUSL__
宏即可。
報(bào)錯(cuò)5:
/opt/sdk/ohos/native/4.0.10.13/llvm/bin/clang -o ssh ssh.o readconf.o clientloop.o sshtty.o sshconnect.o sshconnect2.o mux.o ssh-sk-client.o -L. -Lopenbsd-compat/ -L/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/lib -L/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../zlib-1.3/_install/lib --target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/../openssl-3.0.12/_install/lib/libcrypto.a -lz -Wl,-z,retpolineplt -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -fstack-protector-strong -pie -lssh -lopenbsd-compat -lcrypto -lz
2 warnings generated.
ld.lld: error: undefined symbol: __res_state
>>> referenced by getrrsetbyname.c:195 (/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/openbsd-compat/getrrsetbyname.c:195)
>>> getrrsetbyname.o:(getrrsetbyname) in archive openbsd-compat/libopenbsd-compat.a
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:234: ssh-keyscan] Error 1
make: *** Waiting for unfinished jobs....
ld.lld: error: undefined symbol: __res_state
>>> referenced by getrrsetbyname.c:195 (/work/platform/other/test/ohos/thirdparty/openssh-9.6p1/openbsd-compat/getrrsetbyname.c:195)
>>> getrrsetbyname.o:(getrrsetbyname) in archive openbsd-compat/libopenbsd-compat.a
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:207: ssh] Error 1
musl c庫(kù)中沒(méi)有定義__res_state,所以我們這里實(shí)際上不應(yīng)該使用它。
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 1d54995..4b19428 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -17,6 +17,9 @@ INSTALL=@INSTALL@
LDFLAGS=-L. @LDFLAGS@
LDFLAGS_NOPIE=-L. -Lopenbsd-compat/ @LDFLAGS_NOPIE@
+#remove for ohos
+ # getrrsetbyname.o \
+
OPENBSD=arc4random.o \
arc4random_uniform.o \
base64.o \
@@ -33,7 +36,6 @@ OPENBSD=arc4random.o \
getcwd.o \
getgrouplist.o \
getopt_long.o \
- getrrsetbyname.o \
glob.o \
inet_aton.o \
inet_ntoa.o \
@@ -66,6 +68,9 @@ OPENBSD=arc4random.o \
timingsafe_bcmp.o \
vis.o
+#remove for ohos
+# getrrsetbyname-ldns.o \
+
COMPAT= bsd-asprintf.o \
bsd-closefrom.o \
bsd-cygwin_util.o \
@@ -88,7 +93,6 @@ COMPAT= bsd-asprintf.o \
bsd-timegm.o \
bsd-waitpid.o \
fake-rfc2553.o \
- getrrsetbyname-ldns.o \
kludge-fd_set.o \
openssl-compat.o \
libressl-api-compat.o \
diff --git a/dns.c b/dns.c
index 9392414..0125780 100644
--- a/dns.c
+++ b/dns.c
@@ -220,12 +220,17 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
return -1;
}
+#if !defined(__OHOS__)
result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
DNS_RDATATYPE_SSHFP, 0, &fingerprints);
if (result) {
verbose("DNS lookup error: %s", dns_result_totext(result));
return -1;
}
+#else
+ /* unsupported in OpenHarmony */
+ result = -1;
+#endif
if (fingerprints->rri_flags & RRSET_VALIDATED) {
*flags |= DNS_VERIFY_SECURE;
@@ -259,7 +264,9 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
&hostkey_digest, &hostkey_digest_len, hostkey)) {
error("Error calculating key fingerprint.");
free(dnskey_digest);
+#if !defined(__OHOS__)
freerrset(fingerprints);
+#endif
return -1;
}
@@ -281,7 +288,9 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
free(hostkey_digest); /* from sshkey_fingerprint_raw() */
}
+#if !defined(__OHOS__)
freerrset(fingerprints);
+#endif
/* If any fingerprint failed to validate, return failure. */
if (*flags & DNS_VERIFY_FAILED)
報(bào)錯(cuò)6:
安裝報(bào)錯(cuò),無(wú)法創(chuàng)建/var/empty:
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/bin
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/sbin
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/share/man/man1
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/share/man/man5
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/share/man/man8
/usr/bin/mkdir -p /work/platform/other/test/ohos/thirdparty/openssh-9.6p1/_install/libexec
/usr/bin/mkdir -p -m 0755 /var/empty
/usr/bin/mkdir: cannot create directory ‘/var/empty’: Permission denied
本地編譯才需要?jiǎng)?chuàng)建,仔細(xì)查看Makefile邏輯,發(fā)現(xiàn)make install可以通過(guò)追加DESTDIR來(lái)決定目標(biāo)路徑:
make install DESTDIR=${PWD}/_install
最終編譯openssh的腳本build.sh:
#!/bin/bash
set -e
if [ "$1" == "clean" ] || [ "$1" == "distclean" ];then
make $1
exit 0
fi
export OHOS_SDK_HONE=/opt/sdk/ohos
export OHOS_NATIVE_HOME=/opt/sdk/ohos/native/4.0.10.13
export PATH=$OHOS_NATIVE_HOME/llvm/bin:$PATH
export AR="$OHOS_NATIVE_HOME/llvm/bin/llvm-ar"
export AS="$OHOS_NATIVE_HOME/llvm/bin/llvm-as"
export LD="$OHOS_NATIVE_HOME/llvm/bin/ld.lld"
export RANLIB="$OHOS_NATIVE_HOME/llvm/bin/llvm-ranlib"
export STRIP="$OHOS_NATIVE_HOME/llvm/bin/llvm-strip"
export CC="$OHOS_NATIVE_HOME/llvm/bin/clang"
export NM="$OHOS_NATIVE_HOME/llvm/bin/llvm-nm"
export OBJDUMP="$OHOS_NATIVE_HOME/llvm/bin/llvm-objdump"
export CFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot -g -fvisibility=hidden -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -fno-addrsig -Wformat -Werror=format-security -fno-limit-debug-info -fPIC -march=armv7-a -mthumb -D__MUSL__ -D__OHOS__"
export CPPFLAGS="--target=arm-linux-ohos --sysroot=$OHOS_NATIVE_HOME/sysroot -D__MUSL__ -D__OHOS__"
export LDFLAGS="--target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind -lz"
export LDFLAGS="--target=arm-linux-ohos --rtlib=compiler-rt -fuse-ld=lld -lunwind"
ZLIB_VER="1.3"
SSL_VER="3.2.0"
LIBCRYPO_STATIC="${PWD}/../openssl-${SSL_VER}/_install/lib/libcrypto.a"
export LIBS="${LIBCRYPO_STATIC} -lz"
./configure --prefix=/system \
--target=arm-linux-ohos \
--host=arm-linux \
--bindir=/system/bin \
--sbindir=/system/sbin \
--libexecdir=/system/libexe \
--sysconfdir=/system/etc/ssh \
--localstatedir=/data/ssh/var \
--libdir=/system/lib \
--with-libs --with-zlib=${PWD}/../zlib-${ZLIB_VER}/_install \
--with-ssl-dir=${PWD}/../openssl-${SSL_VER}/_install \
--disable-etc-default-login \
${EXTOPTS}
#make -j$(($(nproc)*2)) CHANNELLIBS=${LIBCRYPO_STATIC} SSHDLIBS=${LIBCRYPO_STATIC} piddir="/data/ssh/var/run"
make -j$(($(nproc)*2)) CHANNELLIBS="" SSHDLIBS="" piddir="/data/ssh/var/run"
make install-nokeys DESTDIR=${PWD}/_install STRIP_OPT="-s --strip-program=${STRIP}"
功能調(diào)試和代碼修改
編譯通過(guò)之后,接下來(lái)就是魔改openssh的源碼來(lái)調(diào)試sshd/ssh的遠(yuǎn)程登錄、scp和sftp的安全拷貝功能了。遇到最主要的問(wèn)題:因?yàn)閛penharmony下的passwd文件沒(méi)有定義用戶的home目錄,導(dǎo)致無(wú)法在登錄之后切換到home路徑;passwd中定義的shell為/bin/false導(dǎo)致用戶無(wú)法登錄;沒(méi)有shadow文件,導(dǎo)致不能密碼登錄(當(dāng)然密鑰登錄的方式還是相對(duì)安全性更可靠一點(diǎn))。代碼修改的細(xì)節(jié)且按下不表,待續(xù)…
添加到系統(tǒng)編譯流程
這里不講如何將上述的Makefile項(xiàng)目轉(zhuǎn)換成BUILD.gn添加到OHOS源碼目錄下的third_party/目錄中進(jìn)行編譯,不難,但是要花點(diǎn)時(shí)間轉(zhuǎn)換。所以,我們這里直接將編譯好的可執(zhí)行程序等以prebuilt文件的形式直接拷貝到編譯。
以放到device/board目錄為例,我們已經(jīng)在該目錄有現(xiàn)成的BUILD.gn文件了,且這個(gè)BUILD.gn中編譯目錄已經(jīng)被依賴:
device/board/${VENDOR}/${PRODUCT}/files/BUILD.gn
declare_args() {
use_openssh = true
use_dropbear = false
}
group("prebuilt_files") {
deps = [
":busybox",
":sysparam.sh",
]
if (use_openssh) {
deps += [ "openssh:openssh" ]
}
if (use_dropbear) {
deps += [ "http://third_party/dropbear:dropbear_group" ]
}
}
增加gn參數(shù)use_openssh和use_dropbear用于決定集成openssh還是dropbear,如果沒(méi)有移植過(guò)dropbear,這里可以把dropbear相關(guān)的直接刪除掉。
然后將前面openssh編譯安裝目錄下的文件拷貝到device/board/${VENDOR}/${PRODUCT}/files/openssh
中:
openssh/
|-- bin
| |-- scp
| |-- sftp
| |-- ssh
| |-- ssh-add
| |-- ssh-agent
| |-- ssh-keygen
| `-- ssh-keyscan
|-- BUILD.gn
|-- etc
| |-- ssh
| | |-- authorized_keys
| | |-- moduli
| | |-- ssh_config
| | |-- sshd_config
| | |-- ssh_host_dsa_key
| | |-- ssh_host_dsa_key.pub
| | |-- ssh_host_rsa_key
| | `-- ssh_host_rsa_key.pub
| `-- sshd.cfg
|-- libexe
| |-- sftp-server
| |-- ssh-keysign
| |-- ssh-pkcs11-helper
| `-- ssh-sk-helper
`-- sbin
`-- sshd
device/board/${VENDOR}/${PRODUCT}/files/openssh/BUILD.gn
# Copyright (C) 2024
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("http://build/ohos.gni")
bin_source_list = [
"bin/scp",
"bin/sftp",
"bin/ssh",
"sbin/sshd",
"libexe/sftp-server",
]
foreach(_bin_src, bin_source_list) {
_target_name = string_replace(_bin_src, "/", "_")
ohos_prebuilt_executable("${_target_name}_bin") {
source = "${_bin_src}"
install_enable = true
install_images = [ system_base_dir ]
module_install_dir = "bin"
part_name = "rockchip_products"
}
}
etc_source_list = [
"etc/ssh/authorized_keys",
"etc/ssh/moduli",
"etc/ssh/ssh_config",
"etc/ssh/sshd_config",
"etc/ssh/ssh_host_dsa_key",
"etc/ssh/ssh_host_dsa_key.pub",
"etc/ssh/ssh_host_rsa_key",
"etc/ssh/ssh_host_rsa_key.pub",
]
foreach(_etc_src, etc_source_list) {
_target_name = string_replace(_etc_src, "/", "_")
ohos_prebuilt_etc("${_target_name}_etc") {
source = "${_etc_src}"
install_enable = true
install_images = [ system_base_dir ]
module_install_dir = "etc/ssh"
part_name = "rockchip_products"
}
}
ohos_prebuilt_etc("sshd.init") {
source = "etc/sshd.cfg"
relative_install_dir = "init"
part_name = "rockchip_products"
}
group("openssh") {
deps = [ ":sshd.init" ]
foreach(_bin_src, bin_source_list) {
_depname = string_replace(_bin_src, "/", "_")
deps += [ ":${_depname}_bin" ]
}
foreach(_etc_src, etc_source_list) {
_depname = string_replace(_etc_src, "/", "_")
deps += [ ":${_depname}_etc" ]
}
}
gn語(yǔ)法中可以通過(guò)string_replace將源路徑字符串中的"/“替換為”_“,因?yàn)橐蕾嚹繕?biāo)名稱中不能出現(xiàn)”/",否則gn會(huì)報(bào)錯(cuò)。gn更多語(yǔ)法可以閱讀源碼third_party/gn/docs/reference.md
device/board/${VENDOR}/${PRODUCT}/files/openssh/etc/sshd.cfg
{
"jobs" : [{
"name" : "post-fs",
"cmds" : [
"mkdir /data/ssh",
"mkdir /data/ssh/var",
"mkdir /data/ssh/var/log",
"mkdir /data/ssh/var/run",
"mkdir /data/ssh/var/empty"
]
}, {
"name" : "boot && param:persist.sys.sshd.enable=*",
"condition" : "boot && persist.sys.sshd.enable=*",
"cmds" : [
"setparam sys.sshd.enable ${persist.sys.sshd.enable}"
]
}, {
"name" : "param:persist.sys.sshd.enable=*",
"condition" : "persist.sys.sshd.enable=*",
"cmds" : [
"setparam sys.sshd.enable ${persist.sys.sshd.enable}"
]
}, {
"name" : "param:sys.sshd.enable=true",
"condition" : "sys.sshd.enable=true",
"cmds" : [
"mkdir /data/ssh",
"start sshd"
]
}, {
"name" : "param:sys.sshd.enable=false",
"condition" : "sys.sshd.enable=false",
"cmds" : [
"stop ssh"
]
}
],
"services" : [{
"name" : "sshd",
"path" : ["/system/bin/sshd", "-f", "/etc/ssh/sshd_config", "-D"],
"uid" : "root",
"gid" : [ "root", "shell", "log", "readproc" ],
"sandbox" : 0,
"start-mode" : "condition",
"secon" : "u:r:sh:s0",
"disabled" : 1
}
]
}
這里需要將系統(tǒng)參數(shù)persist.sys.sshd.enable
設(shè)置為true
才能讓sshd服務(wù)默認(rèn)啟動(dòng)。
device/board/${VENDOR}/${PRODUCT}/files/openssh/etc/ssh/sshd_config
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
AuthorizedKeysFile /etc/ssh/authorized_keys
PasswordAuthentication yes
PidFile /data/ssh/var/run/sshd.pid
Subsystem sftp internal-sftp
密鑰對(duì)文件ssh_host_dsa_key
和ssh_host_dsa_key.pub
,ssh_host_rsa_key
和ssh_host_rsa_key.pub
,以及已認(rèn)證公鑰列表文件authorized_keys
請(qǐng)自行生成。
另外DAC配置文件中需要為ssh的密鑰文件配置權(quán)限,其他用戶不能對(duì)私鑰文件有任何可訪問(wèn)權(quán)限,否則啟動(dòng)sshd服務(wù)時(shí)會(huì)因?yàn)樗借€文件權(quán)限太開(kāi)放而退出:
build/ohos/images/mkimage/dac.txt
diff --git a/ohos/images/mkimage/dac.txt b/ohos/images/mkimage/dac.txt
index 163b069..d2646f8 100644
--- a/ohos/images/mkimage/dac.txt
+++ b/ohos/images/mkimage/dac.txt
@@ -52,3 +62,9 @@ updater/lib/ld-musl-aaarch64-asan.so.1,00755, 0, 2000, 0
updater/lib/ld-musl-x86_64-asan.so.1,00755, 0, 2000, 0
vendor/etc/thermal_config/hdf/thermal_hdi_config.xml,00644, 3025, 3025, 0
system/etc/ledconfig/led_config.json,00644, 3025, 3025, 0
+system/etc/ssh/authorized_keys, 00600, 0, 0, 0
+system/etc/ssh/ssh_host_rsa_key,00600, 0, 0, 0
+system/etc/ssh/ssh_host_dsa_key,00600, 0, 0, 0
+system/etc/ssh/*.pub, 00644, 0, 0, 0
+system/etc/ssh/moduli, 00644, 0, 0, 0
+system/etc/ssh/ssh*_config, 00644, 0, 0, 0
對(duì)應(yīng)system的image config文件中需要通過(guò)–dac_config選項(xiàng)來(lái)指定該文件作為dac配置。
新增服務(wù)sshd需要添加到特權(quán)進(jìn)程列表中:
vendor/${VENDOR}/${PRODUCT}/security_config/high_privilege_process_list.json文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-815162.html
{
"name": "sshd",
"uid": "root"
}
startup_guard的白名單中列表也要增加sshd服務(wù):
developtools/integration_verification/tools/startup_guard/rules/NO-Config-Cmds-In-Init/whitelist.json文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-815162.html
[
{
"start-modes": [
{
"start-mode":"condition",
"service":[
"sshd",
"mmi_uinput_service"
]
}
],
"start-cmd":[
"sshd",
"concurrent_task_service"
]
}
]
到了這里,關(guān)于OpenHarmony移植OpenSSH-9.6p1的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!