100-pubkey_path.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. src/svr-authpubkey.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++----
  2. 1 file changed, 55 insertions(+), 4 deletions(-)
  3. --- a/src/svr-authpubkey.c
  4. +++ b/src/svr-authpubkey.c
  5. @@ -79,6 +79,39 @@ static void send_msg_userauth_pk_ok(cons
  6. const unsigned char* keyblob, unsigned int keybloblen);
  7. static int checkfileperm(char * filename);
  8. +static const char * const global_authkeys_dir = "/etc/dropbear";
  9. +/* strlen(global_authkeys_dir) */
  10. +#define n_global_authkeys_dir 13
  11. +static const char * const authkeys_file = "authorized_keys";
  12. +/* strlen(authkeys_file) */
  13. +#define n_authkeys_file 15
  14. +
  15. +/* OpenWrt-specific:
  16. + use OpenWrt' global authorized keys directory if:
  17. + 1. logging as uid 0 (typically root).
  18. + 2. "svr_opts.authorized_keys_dir" is set to default i.e. no "-D" option was specified
  19. + OR
  20. + "-D" option is specified as homedir-relative path ("~" or "~/...")
  21. + OR
  22. + "-D" option is specified as "/etc/dropbear".
  23. + */
  24. +static int is_openwrt_defaults(void) {
  25. + if (ses.authstate.pw_uid != 0) return 0;
  26. + switch (svr_opts.authorized_keys_dir[0]) {
  27. + case '~':
  28. + switch (svr_opts.authorized_keys_dir[1]) {
  29. + case 0:
  30. + return 1;
  31. + case '/':
  32. + return 1;
  33. + }
  34. + break;
  35. + case '/':
  36. + return (strcmp(svr_opts.authorized_keys_dir, global_authkeys_dir) == 0);
  37. + }
  38. + return 0;
  39. +}
  40. +
  41. /* process a pubkey auth request, sending success or failure message as
  42. * appropriate */
  43. void svr_auth_pubkey(int valid_user) {
  44. @@ -439,16 +472,22 @@ out:
  45. static char *authorized_keys_filepath() {
  46. size_t len = 0;
  47. char *pathname = NULL, *dir = NULL;
  48. - const char *filename = "authorized_keys";
  49. +
  50. + if (is_openwrt_defaults()) {
  51. + len = n_global_authkeys_dir + n_authkeys_file + 2;
  52. + pathname = m_malloc(len);
  53. + snprintf(pathname, len, "%s/%s", global_authkeys_dir, authkeys_file);
  54. + return pathname;
  55. + }
  56. dir = expand_homedir_path_home(svr_opts.authorized_keys_dir,
  57. ses.authstate.pw_dir);
  58. /* allocate max required pathname storage,
  59. * = dir + "/" + "authorized_keys" + '\0' */;
  60. - len = strlen(dir) + strlen(filename) + 2;
  61. + len = strlen(dir) + n_authkeys_file + 2;
  62. pathname = m_malloc(len);
  63. - snprintf(pathname, len, "%s/%s", dir, filename);
  64. + snprintf(pathname, len, "%s/%s", dir, authkeys_file);
  65. m_free(dir);
  66. return pathname;
  67. }
  68. @@ -549,11 +588,23 @@ out:
  69. * When this path is inside the user's home dir it checks up to and including
  70. * the home dir, otherwise it checks every path component. */
  71. static int checkpubkeyperms() {
  72. - char *path = authorized_keys_filepath(), *sep = NULL;
  73. + char *path = NULL, *sep = NULL;
  74. int ret = DROPBEAR_SUCCESS;
  75. + if (is_openwrt_defaults()) {
  76. + TRACE(("enter checkpubkeyperms/openwrt"))
  77. + if (checkfileperm(global_authkeys_dir) != DROPBEAR_SUCCESS) {
  78. + TRACE(("checkpubkeyperms: bad perm on %s", global_authkeys_dir))
  79. + ret = DROPBEAR_FAILURE;
  80. + }
  81. + TRACE(("leave checkpubkeyperms/openwrt"))
  82. + return ret;
  83. + }
  84. +
  85. TRACE(("enter checkpubkeyperms"))
  86. + path = authorized_keys_filepath();
  87. +
  88. /* Walk back up path checking permissions, stopping at either homedir,
  89. * or root if the path is outside of the homedir. */
  90. while ((sep = strrchr(path, '/')) != NULL) {