log_extauth.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include <config.h>
  2. #ifdef WITH_EXTAUTH
  3. #include "ftpd.h"
  4. #include "dynamic.h"
  5. #include "ftpwho-update.h"
  6. #include "globals.h"
  7. #include "log_extauth.h"
  8. #include "log_extauth_p.h"
  9. #include "safe_rw.h"
  10. #ifdef WITH_TLS
  11. # include "tls.h"
  12. #endif
  13. #ifdef WITH_DMALLOC
  14. # include <dmalloc.h>
  15. #endif
  16. static struct sockaddr_un *saddr;
  17. static signed char auth_finalized;
  18. void pw_extauth_parse(const char * const file)
  19. {
  20. size_t file_len;
  21. if (file == NULL || (file_len = strlen(file)) <= (size_t) 0U) {
  22. return;
  23. }
  24. if ((saddr = malloc(sizeof(*saddr) + file_len +
  25. (size_t) 1U)) == NULL) {
  26. die_mem();
  27. }
  28. memcpy(saddr->sun_path, file, file_len + (size_t) 1U);
  29. saddr->sun_family = AF_UNIX;
  30. }
  31. void pw_extauth_exit(void)
  32. {
  33. free(saddr);
  34. saddr = NULL;
  35. }
  36. static void callback_reply_auth_ok(const char *str, AuthResult * const result)
  37. {
  38. result->auth_ok = atoi(str);
  39. }
  40. static void callback_reply_uid(const char *str, AuthResult * const result)
  41. {
  42. result->uid = (uid_t) strtoul(str, NULL, 10);
  43. }
  44. static void callback_reply_gid(const char *str, AuthResult * const result)
  45. {
  46. result->gid = (gid_t) strtoul(str, NULL, 10);
  47. }
  48. static void callback_reply_dir(const char *str, AuthResult * const result)
  49. {
  50. if (*str == '/') {
  51. free((void *) (result->dir));
  52. result->dir = strdup(str);
  53. }
  54. }
  55. static void callback_reply_slow_tilde_expansion(const char *str, AuthResult * const result)
  56. {
  57. result->slow_tilde_expansion = (atoi(str) != 0);
  58. }
  59. static void callback_reply_throttling_bandwidth_ul(const char *str, AuthResult * const result)
  60. {
  61. #ifdef THROTTLING
  62. result->throttling_bandwidth_ul = strtoul(str, NULL, 10);
  63. result->throttling_ul_changed = 1;
  64. #else
  65. (void) str;
  66. (void) result;
  67. #endif
  68. }
  69. static void callback_reply_throttling_bandwidth_dl(const char *str, AuthResult * const result)
  70. {
  71. #ifdef THROTTLING
  72. result->throttling_bandwidth_dl = strtoul(str, NULL, 10);
  73. result->throttling_dl_changed = 1;
  74. #else
  75. (void) str;
  76. (void) result;
  77. #endif
  78. }
  79. static void callback_reply_user_quota_size(const char *str, AuthResult * const result)
  80. {
  81. #ifdef QUOTAS
  82. result->user_quota_size = strtoull(str, NULL, 10);
  83. result->quota_size_changed = 1;
  84. #else
  85. (void) str;
  86. (void) result;
  87. #endif
  88. }
  89. static void callback_reply_user_quota_files(const char *str, AuthResult * const result)
  90. {
  91. #ifdef QUOTAS
  92. result->user_quota_files = strtoull(str, NULL, 10);
  93. result->quota_files_changed = 1;
  94. #else
  95. (void) str;
  96. (void) result;
  97. #endif
  98. }
  99. static void callback_reply_ratio_upload(const char *str, AuthResult * const result)
  100. {
  101. #ifdef RATIOS
  102. result->ratio_upload = (unsigned int) strtoul(str, NULL, 10);
  103. result->ratio_ul_changed = 1;
  104. #else
  105. (void) str;
  106. (void) result;
  107. #endif
  108. }
  109. static void callback_reply_ratio_download(const char *str, AuthResult * const result)
  110. {
  111. #ifdef RATIOS
  112. result->ratio_download = (unsigned int) strtoul(str, NULL, 10);
  113. result->ratio_dl_changed = 1;
  114. #else
  115. (void) str;
  116. (void) result;
  117. #endif
  118. }
  119. static void callback_reply_per_user_max(const char *str, AuthResult * const result)
  120. {
  121. #ifdef PER_USER_LIMITS
  122. result->per_user_max = (unsigned int) strtoul(str, NULL, 10);
  123. #else
  124. (void) str;
  125. (void) result;
  126. #endif
  127. }
  128. static void callback_reply_end(const char *str, AuthResult * const result)
  129. {
  130. (void) str;
  131. (void) result;
  132. auth_finalized |= 1;
  133. }
  134. void pw_extauth_check(AuthResult * const result,
  135. const char *account, const char *password,
  136. const struct sockaddr_storage * const sa,
  137. const struct sockaddr_storage * const peer)
  138. {
  139. int kindy = -1;
  140. int err;
  141. int tries = EXTAUTH_MAX_CONNECT_TRIES;
  142. ssize_t readnb;
  143. char *linepnt;
  144. char *crpoint;
  145. char sa_hbuf[NI_MAXHOST];
  146. char sa_port[NI_MAXSERV];
  147. char peer_hbuf[NI_MAXHOST];
  148. char line[4096];
  149. size_t line_len;
  150. #ifndef WITH_TLS
  151. const char *client_sni_name = "";
  152. #endif
  153. result->auth_ok = 0;
  154. if (getnameinfo((struct sockaddr *) sa, STORAGE_LEN(*sa),
  155. sa_hbuf, sizeof sa_hbuf,
  156. sa_port, sizeof sa_port,
  157. NI_NUMERICHOST | NI_NUMERICSERV) != 0 ||
  158. getnameinfo((struct sockaddr *) peer, STORAGE_LEN(*peer),
  159. peer_hbuf, sizeof peer_hbuf,
  160. NULL, (size_t) 0U,
  161. NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
  162. return;
  163. }
  164. tryagain:
  165. if ((kindy = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
  166. goto bye;
  167. }
  168. while ((err = connect(kindy, (struct sockaddr *) saddr, SUN_LEN(saddr)))
  169. != 0 && errno == EINTR);
  170. if (err != 0) {
  171. close(kindy);
  172. kindy = -1;
  173. if (tries > 0) {
  174. sleep(EXTAUTH_MAX_CONNECT_DELAY);
  175. tries--;
  176. goto tryagain;
  177. }
  178. goto bye;
  179. }
  180. if (SNCHECK(snprintf(line, sizeof line,
  181. EXTAUTH_CLIENT_ACCOUNT "%s\n"
  182. EXTAUTH_CLIENT_PASSWORD "%s\n"
  183. EXTAUTH_CLIENT_SA_HOST "%s\n"
  184. EXTAUTH_CLIENT_SA_PORT "%s\n"
  185. EXTAUTH_CLIENT_PEER_HOST "%s\n"
  186. EXTAUTH_CLIENT_SNI_NAME "%s\n"
  187. EXTAUTH_CLIENT_ENCRYPTED "%d\n"
  188. EXTAUTH_CLIENT_END "\n",
  189. account, password, sa_hbuf, sa_port, peer_hbuf,
  190. client_sni_name == NULL ? "" : client_sni_name,
  191. tls_cnx != NULL),
  192. sizeof line)) {
  193. goto bye;
  194. }
  195. line_len = strlen(line);
  196. if (safe_write(kindy, line, line_len, -1) != (ssize_t) line_len) {
  197. goto bye;
  198. }
  199. result->uid = (uid_t) 0;
  200. result->gid = (gid_t) 0;
  201. result->dir = NULL;
  202. result->slow_tilde_expansion = 1;
  203. auth_finalized = 0;
  204. if ((readnb = safe_read(kindy, line, sizeof line - 1U)) <= (ssize_t) 0) {
  205. goto bye;
  206. }
  207. line[readnb] = 0;
  208. linepnt = line;
  209. while ((crpoint = strchr(linepnt, '\n')) != NULL) {
  210. const ExtauthCallBack *scanned;
  211. size_t keyword_len;
  212. *crpoint = 0;
  213. scanned = extauth_callbacks;
  214. while (scanned->keyword != NULL) {
  215. keyword_len = strlen(scanned->keyword);
  216. if (strncmp(scanned->keyword, linepnt, keyword_len) == 0) {
  217. scanned->func(linepnt + keyword_len, result);
  218. break;
  219. }
  220. scanned++;
  221. }
  222. linepnt = crpoint + 1;
  223. }
  224. if (auth_finalized == 0 ||
  225. (result->auth_ok == 1 &&
  226. (result->uid <= (uid_t) 0 || result->gid <= (gid_t) 0 ||
  227. result->dir == NULL))) {
  228. result->auth_ok = -1;
  229. }
  230. bye:
  231. if (kindy != -1) {
  232. close(kindy);
  233. }
  234. }
  235. #endif