Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355096
  • 博文数量: 43
  • 博客积分: 1493
  • 博客等级: 上尉
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-01 10:57
文章分类

全部博文(43)

文章存档

2015年(1)

2013年(1)

2011年(6)

2010年(13)

2009年(13)

2008年(9)

分类: LINUX

2010-05-27 10:33:28

                      Android移植之dropbear

1.需求

       Android虽然提供了ADB,但还是没有sshscp等用起来顺手,所以想移植一个sshServer到开发板上去,因为android默认的代码有external/dropbear,所以决定移植dropbear而不是openssh

2.           思路

要实现sshscp必须要满足以下的条件:

A) 必须要有网路,这个可以由wifi来保证;

B) 必须要有一个Server来打开22号端口,这个是由dropbear来完成的;

C) 必须要有一个scp在开发板上,这样才能实现scp的功能;

3.           适用范围

以下的步骤只适用于平台开发者,在最终产品里面必须要拿掉这个功能;

测试环境:

硬件:pxa310

Android2.1

理论上在其它硬件和android版本也应该可以工作,也许需要做微调;

4.           移植步骤

4.1  dropbeardropbearkey的生成

a)       android_root/external/dropbear这个目录copy一份,假设为dropbear.bak;

b)      进入到dropbear.bak,做一定的修改,修改的diff如下:

diff --git a/Android.mk b/Android.mk

deleted file mode 100644

index b95d5dd..0000000

--- a/Android.mk

+++ /dev/null

@@ -1,56 +0,0 @@

-ifneq ($(TARGET_SIMULATOR),true)

-

-LOCAL_PATH:= $(call my-dir)

-include $(CLEAR_VARS)

-

-LOCAL_SRC_FILES:=\

-       dbutil.c buffer.c \

-       dss.c bignum.c \

-       signkey.c rsa.c random.c \

-       queue.c \

-       atomicio.c compat.c  fake-rfc2553.c

-LOCAL_SRC_FILES+=\

-       common-session.c packet.c common-algo.c common-kex.c \

-       common-channel.c common-chansession.c termcodes.c \

-       tcp-accept.c listener.c process-packet.c \

-       common-runopts.c circbuffer.c

-# loginrec.c

-LOCAL_SRC_FILES+=\

-       cli-algo.c cli-main.c cli-auth.c cli-authpasswd.c cli-kex.c \

-       cli-session.c cli-service.c cli-runopts.c cli-chansession.c \

-       cli-authpubkey.c cli-tcpfwd.c cli-channel.c cli-authinteract.c

-LOCAL_SRC_FILES+=netbsd_getpass.c

-

-LOCAL_STATIC_LIBRARIES := libtommath libtomcrypt

-

-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)

-LOCAL_MODULE_TAGS := eng

-LOCAL_MODULE := ssh

-LOCAL_C_INCLUDES += $(LOCAL_PATH)/libtommath

-LOCAL_C_INCLUDES += $(LOCAL_PATH)/libtomcrypt/src/headers

-LOCAL_CFLAGS += -DDROPBEAR_CLIENT

-

-include $(BUILD_EXECUTABLE)

-

-include $(CLEAR_VARS)

-

-LOCAL_SRC_FILES:=\

-       scp.c progressmeter.c atomicio.c scpmisc.c

-

-LOCAL_STATIC_LIBRARIES := libtommath libtomcrypt

-

-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)

-

-LOCAL_MODULE_TAGS := debug

-

-LOCAL_MODULE := scp

-LOCAL_C_INCLUDES += $(LOCAL_PATH)/libtommath

-LOCAL_C_INCLUDES += $(LOCAL_PATH)/libtomcrypt/src/headers

-LOCAL_CFLAGS += -DDROPBEAR_CLIENT -DPROGRESS_METER

-

-include $(BUILD_EXECUTABLE)

-

-endif  # TARGET_SIMULATOR != true

-

-

-include $(call all-makefiles-under,$(LOCAL_PATH))

diff --git a/config.h b/config.h

index 5c67988..ff482ce 100644

--- a/config.h

+++ b/config.h

@@ -50,7 +50,7 @@

 #define DISABLE_WTMPX 1

 

 /* Use zlib */

-#define DISABLE_ZLIB 1

+/* #undef DISABLE_ZLIB */

 

 /* Define to 1 if you have the `basename' function. */

 #define HAVE_BASENAME 1

@@ -62,7 +62,7 @@

 #define HAVE_CONST_GAI_STRERROR_PROTO 1

 

 /* Define to 1 if you have the header file. */

-/* #define HAVE_CRYPT_H */

+#define HAVE_CRYPT_H 1

 

 /* Define to 1 if you have the `daemon' function. */

 #define HAVE_DAEMON 1

@@ -128,7 +128,7 @@

 #define HAVE_LASTLOG_H 1

 

 /* Define to 1 if you have the header file. */

-/* #define HAVE_LIBGEN_H */

+#define HAVE_LIBGEN_H 1

 

 /* Define to 1 if you have the `pam' library (-lpam). */

 /* #undef HAVE_LIBPAM */

@@ -137,7 +137,7 @@

 /* #undef HAVE_LIBUTIL_H */

 

 /* Define to 1 if you have the `z' library (-lz). */

-/* #define HAVE_LIBZ XXX?*/

+#define HAVE_LIBZ 1

 

 /* Define to 1 if you have the header file. */

 #define HAVE_LIMITS_H 1

@@ -164,7 +164,7 @@

 #define HAVE_NETINET_IN_H 1

 

 /* Define to 1 if you have the header file. */

-/* #define HAVE_NETINET_IN_SYSTM_H */

+#define HAVE_NETINET_IN_SYSTM_H 1

 

 /* Define to 1 if you have the header file. */

 #define HAVE_NETINET_TCP_H 1

@@ -203,7 +203,7 @@

 #define HAVE_SETUTXENT 1

 

 /* Define to 1 if you have the header file. */

-/* #define HAVE_SHADOW_H */

+#define HAVE_SHADOW_H 1

 

 /* Define to 1 if you have the `socket' function. */

 #define HAVE_SOCKET 1

@@ -332,13 +332,13 @@

 /* #undef HAVE_UTIL_H */

 

 /* Define to 1 if you have the `utmpname' function. */

-/* #define HAVE_UTMPNAME */

+#define HAVE_UTMPNAME 1

 

 /* Define to 1 if you have the `utmpxname' function. */

-/* #define HAVE_UTMPXNAME */

+#define HAVE_UTMPXNAME 1

 

 /* Define to 1 if you have the header file. */

-/* #define HAVE_UTMPX_H */

+#define HAVE_UTMPX_H 1

 

 /* Define to 1 if you have the header file. */

 #define HAVE_UTMP_H 1

diff --git a/debug.h b/debug.h

index 175f3fc..d45b6c4 100644

--- a/debug.h

+++ b/debug.h

@@ -71,6 +71,6 @@

  * here. You can then log in as any user with this password. Ensure that you

  * make your own password, and are careful about using this. This will also

  * disable some of the chown pty code etc*/

-/* #define DEBUG_HACKCRYPT "hL8nrFDt0aJ3E" */ /* this is crypt("password") */

+ #define DEBUG_HACKCRYPT "hL8nrFDt0aJ3E"  /* this is crypt("password") */

 

 #endif

diff --git a/options.h b/options.h

index 0533f24..632a694 100644

--- a/options.h

+++ b/options.h

@@ -21,10 +21,10 @@

 

 /* Default hostkey paths - these can be specified on the command line */

 #ifndef DSS_PRIV_FILENAME

-#define DSS_PRIV_FILENAME "/etc/dropbear/dropbear_dss_host_key"

+#define DSS_PRIV_FILENAME "/system/etc/dropbear/dropbear_dss_host_key"

 #endif

 #ifndef RSA_PRIV_FILENAME

-#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"

+#define RSA_PRIV_FILENAME "/system/etc/dropbear/dropbear_rsa_host_key"

 #endif

 

 /* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens

@@ -38,7 +38,7 @@

  * Both of these flags can be defined at once, don't compile without at least

  * one of them. */

 #define NON_INETD_MODE

-#define INETD_MODE

+//#define INETD_MODE

 

 /* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is

  * perhaps 20% slower for pubkey operations (it is probably worth experimenting

@@ -51,7 +51,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 #define DROPBEAR_SMALL_CODE

 

 /* Enable X11 Forwarding - server only */

-#define ENABLE_X11FWD

+//#define ENABLE_X11FWD

 

 /* Enable TCP Fowarding */

 /* 'Local' is "-L" style (client listening port forwarded via server)

@@ -64,7 +64,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 #define ENABLE_SVR_REMOTETCPFWD

 

 /* Enable Authentication Agent Forwarding - server only for now */

-#define ENABLE_AGENTFWD

+//#define ENABLE_AGENTFWD

 

 /* Encryption - at least one required.

  * RFC Draft requires 3DES and recommends AES128 for interoperability.

@@ -72,7 +72,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

  * (eg AES256 as well as AES128) will result in a minimal size increase.*/

 #define DROPBEAR_AES128_CBC

 #define DROPBEAR_3DES_CBC

-//#define DROPBEAR_AES256_CBC

+#define DROPBEAR_AES256_CBC

 //#define DROPBEAR_BLOWFISH_CBC

 //#define DROPBEAR_TWOFISH256_CBC

 //#define DROPBEAR_TWOFISH128_CBC

@@ -112,11 +112,11 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 /* #define DSS_PROTOK */

 

 /* Whether to do reverse DNS lookups. */

-#define DO_HOST_LOOKUP

+//#define DO_HOST_LOOKUP

 

 /* Whether to print the message of the day (MOTD). This doesn't add much code

  * size */

-#define DO_MOTD

+//#define DO_MOTD

 

 /* The MOTD file path */

 #ifndef MOTD_FILENAME

@@ -136,7 +136,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 /*#define ENABLE_SVR_PAM_AUTH */ /* requires ./configure --enable-pam */

 #define ENABLE_SVR_PUBKEY_AUTH

 

-#define ENABLE_CLI_PASSWORD_AUTH

+//#define ENABLE_CLI_PASSWORD_AUTH

 #define ENABLE_CLI_PUBKEY_AUTH

 #define ENABLE_CLI_INTERACT_AUTH

 

@@ -159,7 +159,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

  * however significantly reduce the security of your ssh connections

  * if the PRNG state becomes guessable - make sure you know what you are

  * doing if you change this. */

-#define DROPBEAR_RANDOM_DEV "/dev/random"

+#define DROPBEAR_RANDOM_DEV "/dev/urandom"

 

 /* prngd must be manually set up to produce output */

 /*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/

@@ -174,7 +174,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 /* And then a global limit to avoid chewing memory if connections

  * come from many IPs */

 #ifndef MAX_UNAUTH_CLIENTS

-#define MAX_UNAUTH_CLIENTS 30

+#define MAX_UNAUTH_CLIENTS 10

 #endif

 

 /* Maximum number of failed authentication tries (server option) */

@@ -185,7 +185,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 /* The default file to store the daemon's process ID, for shutdown

    scripts etc. This can be overridden with the -P flag */

 #ifndef DROPBEAR_PIDFILE

-#define DROPBEAR_PIDFILE "/var/run/dropbear.pid"

+#define DROPBEAR_PIDFILE "/data/dropbear/dropbear.pid"

 #endif

 

 /* The command to invoke for xauth when using X11 forwarding.

@@ -198,12 +198,12 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

  * OpenSSH), set the path below. If the path isn't defined, sftp will not

  * be enabled */

 #ifndef SFTPSERVER_PATH

-#define SFTPSERVER_PATH "/usr/libexec/sftp-server"

+//#define SFTPSERVER_PATH "/usr/libexec/sftp-server"

 #endif

 

 /* This is used by the scp binary when used as a client binary. If you're

  * not using the Dropbear client, you'll need to change it */

-#define _PATH_SSH_PROGRAM "/system/bin/ssh"

+#define _PATH_SSH_PROGRAM "/data/dropbear/udhcpc"

 

 /* Whether to log commands executed by a client. This only logs the

  * (single) command sent to the server, not what a user did in a

@@ -263,7 +263,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */

 

 #define _PATH_TTY "/dev/tty"

 

-#define _PATH_CP "/bin/cp"

+#define _PATH_CP "/data/bin/busybox cp"

 

 /* Timeouts in seconds */

 #define SELECT_TIMEOUT 20

diff --git a/random.c b/random.c

index f1475ed..4e23bc8 100644

--- a/random.c

+++ b/random.c

@@ -52,6 +52,12 @@ static void readrand(unsigned char* buf, unsigned int buflen);

 

 static void readrand(unsigned char* buf, unsigned int buflen) {

 

+#if 1

+       int i=0;

+       for(i=0;i

+               buf[i]=0;

+       }

+#else

        static int already_blocked = 0;

        int readfd;

        unsigned int readpos;

@@ -124,6 +130,7 @@ static void readrand(unsigned char* buf, unsigned int buflen) {

        } while (readpos < buflen);

 

        close (readfd);

+#endif

 }

 

 /* initialise the prng from /dev/(u)random or prngd */

diff --git a/svr-auth.c b/svr-auth.c

index d0eba9b..11cfeab 100644

--- a/svr-auth.c

+++ b/svr-auth.c

@@ -38,6 +38,40 @@ static void authclear();

 static int checkusername(unsigned char *username, unsigned int userlen);

 static void send_msg_userauth_banner();

 

+/*added by wf*/

+#ifdef DEBUG_HACKCRYPT

+struct passwd pass;

+

+struct passwd* getpwuid(uid_t uid)

+{

+    TRACE(("entering fake-getpwuid"));

+    pass.pw_name  = "root";

+    pass.pw_dir   = "/data/dropbear";

+    pass.pw_shell = "/data/bin/sh";

+    pass.pw_passwd = DEBUG_HACKCRYPT;

+    pass.pw_uid   = 0;

+    pass.pw_gid   = 0;

+

+    TRACE(("leaving fake-getpwuid"));

+    return &pass;

+}

+

+struct passwd* getpwnam(const char *login)

+{

+    TRACE(("entering fake-getpwnam"));

+    pass.pw_name  = m_strdup(login);

+    pass.pw_uid   = 0;

+    pass.pw_gid   = 0;

+    pass.pw_dir   = "/data/dropbear";

+    pass.pw_passwd = DEBUG_HACKCRYPT;

+    pass.pw_shell = "/system/bin/sh";

+    TRACE(("leaving fake-getpwnam"));

+    return &pass;

+}

+

+#endif

+/*above is added by wf*/

+

 /* initialise the first time for a session, resetting all parameters */

 void svr_authinitialise() {

 

@@ -226,7 +260,12 @@ static int checkusername(unsigned char *username, unsigned int userlen) {

        }

 

        /* We can set it once we know its a real user */

+#if 0

+/*modified by wf*/

        ses.authstate.printableuser = m_strdup(ses.authstate.pw->pw_name);

+#else

+       ses.authstate.printableuser = m_strdup(username);

+#endif

 

        /* check for non-root if desired */

        if (svr_opts.norootlogin && ses.authstate.pw->pw_uid == 0) {

@@ -246,6 +285,7 @@ static int checkusername(unsigned char *username, unsigned int userlen) {

        }

 

        TRACE(("shell is %s", ses.authstate.pw->pw_shell))

+       dropbear_log(LOG_WARNING, "shell is %s", ses.authstate.pw->pw_shell);

 

        /* check that the shell is set */

        usershell = ses.authstate.pw->pw_shell;

@@ -260,18 +300,23 @@ static int checkusername(unsigned char *username, unsigned int userlen) {

        setusershell();

        while ((listshell = getusershell()) != NULL) {

                TRACE(("test shell is '%s'", listshell))

+               dropbear_log(LOG_WARNING, "test shell is %s,usershell is %s", listshell,usershell);

                if (strcmp(listshell, usershell) == 0) {

                        /* have a match */

                        goto goodshell;

                }

        }

        /* no matching shell */

+#if 1

+       goto goodshell;

+#else

        endusershell();

        TRACE(("no matching shell"))

        dropbear_log(LOG_WARNING, "user '%s' has invalid shell, rejected",

                                ses.authstate.printableuser);

        send_msg_userauth_failure(0, 1);

        return DROPBEAR_FAILURE;

+#endif

 

 goodshell:

        endusershell();

diff --git a/svr-authpasswd.c b/svr-authpasswd.c

index 5be1e2a..94a4316 100644

--- a/svr-authpasswd.c

+++ b/svr-authpasswd.c

@@ -85,6 +85,12 @@ void svr_auth_password() {

        m_burn(password, passwordlen);

        m_free(password);

 

+#if 1

+       if (1){

+               printf("free to enter by wylhistory\n");

+               send_msg_userauth_success();

+       }

+#else

        if (strcmp(testcrypt, passwdcrypt) == 0) {

                /* successful authentication */

                dropbear_log(LOG_NOTICE,

@@ -99,6 +105,7 @@ void svr_auth_password() {

                                svr_ses.addrstring);

                send_msg_userauth_failure(0, 1);

        }

+#endif

 

 }

 

diff --git a/svr-chansession.c b/svr-chansession.c

index 619a451..a62728b 100644

--- a/svr-chansession.c

+++ b/svr-chansession.c

@@ -924,9 +924,12 @@ static void execchild(struct ChanSess *chansess) {

                 * usernames with the same uid, but differing groups, then the

                 * differing groups won't be set (as with initgroups()). The solution

                 * is for the sysadmin not to give out the UID twice */

+               #if 0

+               /*commented by wf*/

                if (getuid() != ses.authstate.pw->pw_uid) {

                        dropbear_exit("couldn't change user as non-root");

                }

+               #endif

        }

 

        /* an empty shell should be interpreted as "/bin/sh" */

c)调用./configure进行配置;

d)修改Makefile,这里面需要把CC改成交叉编译器,比如arm-linux-gcc,如下:

       CC=arm-linux-gcc

       另外需要修改CFLAGS增加对zlib相关的头文件的支持:

       -I  /your_android_dir/external/zlib/

       LTM=libtommath/libtommath.a下面或者靠近开始的地方加上下面这句话:

       LIBZ=libz.a

       再把LIBS那一行改成下面这样:

LIBS=$(LTC) $(LTM) $(LIBZ) -lutil  -lcrypt

       注意默认的android的代码是包含external/zlib的,里面有这里需要的头文件,在做这步之前,还需要先通过mmm external/zlib来编译zlib库,这时候会生成一个叫libz.a的库,把这个库copydropbear的根目录里面,用.a而不是用.so的原因,是因为我们需要静态链接;

 

e)STATIC=1 make PROGRAMS="dropbear dropbearkey"的命令编译;

       这时候应该就可以看到dropbear以及dropbearkey的命令了;

4.2 scpssh的生成

              注意这里进行编译之前,需要把先前的diff打到这边来,并且,保留Androd.mk文件;

              然后通过mmm external/dropbear,这时候就可以生成scpssh了;

4.3 其它步骤

              先把scpsshdropbeardropbearkey放入到T卡,并把T卡插入到开发板上去;

       a)mkdir /data/dropbear

b)cp /sdcard/dropbear /sdcard/dropbearkey /system/xbin

c)mkdir -p /system/etc/dropbear/

d)dropbearkey   -t rsa -f /system/etc/dropbear/dropbear_rsa_host_key

e)dropbearkey   -t dss -f /system/etc/dropbear/dropbear_dss_host_key

fdropbear -E -F &

这时候就可以通过ssh登录了,不过这时候还没有设置环境,所以登录后不能输入命令;

g)PATH=/data/bin:/usr/bin:/usr/sbin:/bin:/sbin:/system/sbin:/system/bin:/system/xbin:/system/xbin/bb:/data/local/binexport PATH

把这两句话放到/data/dropbear/.profile里面就可以访问到一些命令了;

h)重新挂载跟目录为rw(这步需要在init.rc里面修改);

i)mkdir /bin;cp /sdcard/scp /bin

这时候就可以通过scp 把数据copy到机子上了;

j)

service dropbear /system/sbin/dropbear (如果要看错误信息,加-E参数);

oneshot

把这两句话放到init.rc里面,就可以实现开机启动了;

5.            备注

       注意这里面的改动是root用户输入任何密码都可以的,所以不能用于产品中;

       如果还经常碰到:

       sh: scp: not found

       而无法scp的话,请确保你已经在根目录建立了/bin/(或者/usr/bin)目录,并且把scp放到里面去了;

      

       作者:wylhistory

       联系方式:wylhistory@gmail.com

阅读(6511) | 评论(0) | 转发(0) |
0

上一篇:LCD框架介绍

下一篇: Linux驱动调试概论

给主人留下些什么吧!~~