I wanted to use rsync / ssh combination to do a backup of a phone that I don’t want to root. There were few problems:
a) the rsync4android failed with an error that said: ‘ssh: exiting: string is too long’:
b) other solutions meant being root.
I’ve decided to cross-compile openssh-5.8p2 (which came with my busybox) so that I can use it in a combination with rsync (which I’ve also cross compiled) and all controlled by GScript (this will be a topic of a separate post).
The troubles encountered with getting openssh to run are that there’s no luck for the getpw* methods in Android (as /etc/passwd doesn’t exist and thus they return null. Just executing ssh on the phone produced the error: “You don’t exist, go away!”
I’ve tracked this down into ssh.c file:
pw = getpwuid(original_real_uid);
if (!pw) {
logit("You don't exist, go away!");
exit(255);
}
Just patching this line doesn’t work, since there will be segmentation faults and other calls to getpwuid
I’ve created a small patch that addresses this issue:
diff -rupN openssh-5.8p2-orig/misc.c openssh-5.8p2/misc.c
--- openssh-5.8p2-orig/misc.c 2011-01-13 02:21:36.000000000 +0100
+++ openssh-5.8p2/misc.c 2015-05-03 13:21:07.488601303 +0200
@@ -533,7 +533,7 @@ tilde_expand_filename(const char *filena
user[slash] = '\0';
if ((pw = getpwnam(user)) == NULL)
fatal("tilde_expand_filename: No such user %s", user);
- } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
+ } else if ((pw = vi_getpwuid(uid)) == NULL) /* ~/path */
fatal("tilde_expand_filename: No such uid %ld", (long)uid);
if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
@@ -996,3 +996,27 @@ sock_set_v6only(int s)
error("setsockopt IPV6_V6ONLY: %s", strerror(errno));
#endif
}
+
+/*
+ * viulian: since getpwuid fails on nonrooted phones (or roote
+ * but without /etc/passwd, let's replace it
+ */
+struct passwd* vi_getpwuid(uid_t uid) {
+
+ struct passwd *pw = (struct passwd *)calloc(1, sizeof(struct passwd));
+ if (!pw) {
+ logit("Not enough memory.");
+ exit(255);
+ }
+
+ pw->pw_name = strdup("android");
+ pw->pw_passwd = strdup("********");
+ pw->pw_uid = getuid();
+ pw->pw_gid = getgid();
+ pw->pw_gecos = strdup("android");
+ pw->pw_dir = strdup("/sdcard");
+ pw->pw_shell = strdup("/system/bin/sh");
+
+ return pw;
+}
+
diff -rupN openssh-5.8p2-orig/misc.h openssh-5.8p2/misc.h
--- openssh-5.8p2-orig/misc.h 2010-12-01 01:50:35.000000000 +0100
+++ openssh-5.8p2/misc.h 2015-05-03 12:45:31.284430274 +0200
@@ -102,4 +102,6 @@ char *read_passphrase(const char *, int)
int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
+struct passwd* vi_getpwuid(uid_t);
+
#endif /* _MISC_H */
diff -rupN openssh-5.8p2-orig/ssh.c openssh-5.8p2/ssh.c
--- openssh-5.8p2-orig/ssh.c 2011-02-04 01:42:15.000000000 +0100
+++ openssh-5.8p2/ssh.c 2015-05-03 12:42:42.134518990 +0200
@@ -268,7 +268,7 @@ main(int ac, char **av)
}
#endif
/* Get user data. */
- pw = getpwuid(original_real_uid);
+ pw = vi_getpwuid(original_real_uid);
if (!pw) {
logit("You don't exist, go away!");
exit(255);
@@ -1481,7 +1481,7 @@ load_public_identity_files(void)
xfree(keys);
}
#endif /* ENABLE_PKCS11 */
- if ((pw = getpwuid(original_real_uid)) == NULL)
+ if ((pw = vi_getpwuid(original_real_uid)) == NULL)
fatal("load_public_identity_files: getpwuid failed");
pwname = xstrdup(pw->pw_name);
pwdir = xstrdup(pw->pw_dir);
What it does is that it introduces a fake getpwuid method (called vi_getpwuid) which returns a valid passwd struct but filled with fake data (I haven’t investigated the security risks linked to this – I just wanted to get the code running). It assumes the username is ‘android’ (the username is in fact the application id, but I haven’t studied how to retrieve that from the NDK layer).
It also assumes the user home dir to be /sdcard (where ssh will create the .ssh/known_hosts file.
By trial and error, I found 3 places where the changes had to be done to get ssh to work via rsync: there were two checks in ssh.c file and one more in misc.c itself inside the tilde_expand_filename method. This too had to be fixed, otherwise ssh would complain with:
tilde_expand_filename: No such uid 11041
Hope this helps!

k007sam
THANK YOU MAN! I SPENT ALMOST FUCKING 2 DAYS ON THIS SHIT! THANK YOU SO MUCH. SO WIERD Android SSH 8.0 works and 9.0 fails due to this problem.