0
|
1 /* Copyright (C) 2002 Timo Sirainen */
|
|
2
|
|
3 #include "common.h"
|
|
4 #include "auth.h"
|
|
5 #include "cookie.h"
|
|
6
|
|
7 #include <stdlib.h>
|
|
8
|
|
9 typedef struct _AuthModuleList AuthModuleList;
|
|
10
|
|
11 struct _AuthModuleList {
|
|
12 AuthModuleList *next;
|
|
13
|
|
14 AuthModule module;
|
|
15 };
|
|
16
|
|
17 AuthMethod auth_methods;
|
|
18 char *const *auth_realms;
|
|
19
|
|
20 static AuthModuleList *auth_modules;
|
|
21 static AuthReplyData failure_reply;
|
|
22
|
|
23 void auth_register_module(AuthModule *module)
|
|
24 {
|
|
25 AuthModuleList *list;
|
|
26
|
|
27 i_assert((auth_methods & module->method) == 0);
|
|
28
|
|
29 auth_methods |= module->method;
|
|
30
|
|
31 list = i_new(AuthModuleList, 1);
|
|
32 memcpy(&list->module, module, sizeof(AuthModule));
|
|
33
|
|
34 list->next = auth_modules;
|
|
35 auth_modules = list;
|
|
36 }
|
|
37
|
|
38 void auth_unregister_module(AuthModule *module)
|
|
39 {
|
|
40 AuthModuleList **pos, *list;
|
|
41
|
|
42 if ((auth_methods & module->method) == 0)
|
|
43 return; /* not registered */
|
|
44
|
|
45 auth_methods &= ~module->method;
|
|
46
|
|
47 for (pos = &auth_modules; *pos != NULL; pos = &(*pos)->next) {
|
|
48 if ((*pos)->module.method == module->method) {
|
|
49 list = *pos;
|
|
50 *pos = (*pos)->next;
|
|
51 i_free(list);
|
|
52 break;
|
|
53 }
|
|
54 }
|
|
55 }
|
|
56
|
|
57 void auth_init_request(AuthInitRequestData *request,
|
|
58 AuthCallback callback, void *user_data)
|
|
59 {
|
|
60 AuthModuleList *list;
|
|
61
|
|
62 if ((auth_methods & request->method) == 0) {
|
|
63 /* unsupported method */
|
|
64 i_error("BUG: imap-login requested unsupported "
|
|
65 "auth method %d", request->method);
|
|
66 failure_reply.id = request->id;
|
|
67 callback(&failure_reply, NULL, user_data);
|
|
68 return;
|
|
69 }
|
|
70
|
|
71 for (list = auth_modules; list != NULL; list = list->next) {
|
|
72 if (list->module.method == request->method) {
|
|
73 list->module.init(request, callback, user_data);
|
|
74 return;
|
|
75 }
|
|
76 }
|
|
77
|
|
78 i_assert(0);
|
|
79 }
|
|
80
|
|
81 void auth_continue_request(AuthContinuedRequestData *request,
|
|
82 const unsigned char *data,
|
|
83 AuthCallback callback, void *user_data)
|
|
84 {
|
|
85 CookieData *cookie_data;
|
|
86
|
|
87 cookie_data = cookie_lookup(request->cookie);
|
|
88 if (cookie_data == NULL) {
|
|
89 /* timeouted cookie */
|
|
90 failure_reply.id = request->id;
|
|
91 callback(&failure_reply, NULL, user_data);
|
|
92 } else {
|
|
93 cookie_data->auth_continue(cookie_data, request, data,
|
|
94 callback, user_data);
|
|
95 }
|
|
96 }
|
|
97
|
|
98 extern AuthModule auth_plain;
|
|
99 extern AuthModule auth_digest_md5;
|
|
100
|
|
101 void auth_init(void)
|
|
102 {
|
|
103 char *const *methods;
|
|
104 const char *env;
|
|
105
|
|
106 auth_modules = NULL;
|
|
107 auth_methods = 0;
|
|
108
|
|
109 memset(&failure_reply, 0, sizeof(failure_reply));
|
|
110 failure_reply.result = AUTH_RESULT_FAILURE;
|
|
111
|
|
112 /* register wanted methods */
|
|
113 env = getenv("METHODS");
|
|
114 if (env == NULL || *env == '\0')
|
|
115 i_fatal("METHODS environment is unset");
|
|
116
|
|
117 methods = t_strsplit(env, " ");
|
|
118 while (*methods != NULL) {
|
|
119 if (strcasecmp(*methods, "plain") == 0)
|
|
120 auth_register_module(&auth_plain);
|
|
121 else if (strcasecmp(*methods, "digest-md5") == 0)
|
|
122 auth_register_module(&auth_digest_md5);
|
|
123 else {
|
|
124 i_fatal("Unknown authentication method '%s'",
|
|
125 *methods);
|
|
126 }
|
|
127 methods++;
|
|
128 }
|
|
129
|
|
130 /* get our realm - note that we allocate from temp. memory pool so
|
|
131 this function should never be called inside I/O loop or anywhere
|
|
132 else where t_pop() is called */
|
|
133 env = getenv("REALMS");
|
|
134 if (env == NULL)
|
|
135 env = "";
|
|
136 auth_realms = t_strsplit(env, " ");
|
|
137 }
|
|
138
|
|
139 void auth_deinit(void)
|
|
140 {
|
|
141 auth_unregister_module(&auth_plain);
|
|
142 auth_unregister_module(&auth_digest_md5);
|
|
143 }
|