pamauth.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* plugin for 3proxy with PAM auth only for *NIX (linux,*bsd)
  2. Kirill Lopuchov <lopuchov@mail.ru>
  3. Compile with: gcc -shared -o pamauth.so pamauth.c -lpam -DNOODBC
  4. */
  5. #include "../../structures.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <security/pam_appl.h>
  11. pthread_mutex_t pam_mutex;
  12. static int already_loaded = 0;
  13. static struct auth pamauth;
  14. #ifdef USERCASE
  15. static int usercaselow = 0;
  16. #endif
  17. static unsigned char *service=NULL;
  18. static struct pluginlink * pl;
  19. static char *password = NULL;
  20. static int password_conversation ( int num_msg, const struct pam_message **msg,
  21. struct pam_response **resp,
  22. void *appdata_ptr)
  23. {
  24. if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
  25. {
  26. return PAM_CONV_ERR;
  27. }
  28. if (!appdata_ptr) appdata_ptr = password;
  29. if (!appdata_ptr)
  30. {
  31. return PAM_CONV_ERR;
  32. }
  33. *resp = calloc (num_msg, sizeof (struct pam_response));
  34. if (!*resp)
  35. {
  36. return PAM_CONV_ERR;
  37. }
  38. (*resp)[0].resp = strdup ((char *) appdata_ptr);
  39. (*resp)[0].resp_retcode = 0;
  40. return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
  41. }
  42. #ifdef USERCASE
  43. static void lower (char *string)
  44. {
  45. int length, i;
  46. length = strlen(string);
  47. for (i=0; i<length; i++)
  48. {
  49. string[i] = tolower(string[i]);
  50. }
  51. }
  52. #endif
  53. /* --------------------------------------------------------------------------*/
  54. static int pamfunc(struct clientparam *param)
  55. {
  56. pam_handle_t *pamh = NULL;
  57. int retval;
  58. int rc=0;
  59. struct pam_conv conv = {
  60. &password_conversation,
  61. NULL };
  62. /* test proxy user auth ------------------------*/
  63. if(!param->username || !param->password) return 4;
  64. /*if(strlen(param->password)==0) return 4;*/
  65. #ifdef USERCASE
  66. if (usercaselow > 0)
  67. { lower(param->username); }
  68. #endif
  69. /*start process auth */
  70. conv.appdata_ptr = (char *) param->password;
  71. pthread_mutex_lock(&pam_mutex);
  72. if (!pamh)
  73. {
  74. retval = pam_start ((char *)service, "3proxy@" , &conv, &pamh);
  75. }
  76. if (retval == PAM_SUCCESS)
  77. retval = pam_set_item (pamh, PAM_USER, param->username);
  78. /*fprintf(stderr,"pam_set_item1 rc=%d\n",retval);*/
  79. if (retval == PAM_SUCCESS)
  80. retval = pam_set_item (pamh, PAM_CONV, &conv);
  81. /*fprintf(stderr,"pam_set_item2 rc=%d\n",retval); */
  82. if (retval == PAM_SUCCESS)
  83. retval = pam_authenticate (pamh, 0);
  84. /*fprintf(stderr,"pam_authenticate rc=%d\n",retval);*/
  85. if (retval == PAM_SUCCESS) { /*auth OK*/ rc=0; }
  86. else { /*auth ERR*/ rc=5; }
  87. if (pamh)
  88. retval = pam_end (pamh, retval);
  89. if (retval != PAM_SUCCESS)
  90. { pamh = NULL; }
  91. pthread_mutex_unlock(&pam_mutex);
  92. return rc;
  93. }
  94. #ifdef WATCOM
  95. #pragma aux start "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
  96. #undef PLUGINCALL
  97. #define PLUGINCALL
  98. #endif
  99. /*------------------------------- MAIN --------------------------------------
  100. start plugin init */
  101. PLUGINAPI int PLUGINCALL start(struct pluginlink * pluginlink, int argc, unsigned char** argv)
  102. {
  103. if(argc < 2) return 1;
  104. pl = pluginlink;
  105. if(service) free(service);
  106. service=strdup((char *)argv[1]);
  107. if (already_loaded) { return (0); }
  108. already_loaded = 1;
  109. pthread_mutex_init(&pam_mutex, NULL);
  110. pamauth.preauthorize = pluginlink->checkpreACL;
  111. pamauth.authenticate = pamfunc;
  112. pamauth.authorize = pluginlink->checkACL;
  113. pamauth.desc = "pam";
  114. pamauth.next = pluginlink->authfuncs->next;
  115. pluginlink->authfuncs->next = &pamauth;
  116. return 0;
  117. }