2 * Copyright (c) 2004 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 while(fgets(buf
+ strlen(buf
), size
- strlen(buf
), p
->input
) != NULL
) {
55 if((p
= strchr(buf
, '\n')) != NULL
) {
56 while(p
> buf
&& p
[-1] == '\r')
61 /* just assume we ran out of buffer space, we'll catch eof
64 p
= realloc(buf
, size
);
73 static char auth_msg
[128];
75 pop_auth_set_error(const char *message
)
77 strlcpy(auth_msg
, message
, sizeof(auth_msg
));
80 static struct auth_mech
*methods
[] = {
88 auth_execute(POP
*p
, struct auth_mech
*m
, void *state
, const char *line
)
91 size_t input_length
, output_length
;
100 pop_auth_set_error("out of memory");
101 return POP_AUTH_FAILURE
;
103 input_length
= base64_decode(line
, input
);
104 if(input_length
== (size_t)-1) {
105 pop_auth_set_error("base64 decode error");
106 return POP_AUTH_FAILURE
;
109 output
= NULL
; output_length
= 0;
110 status
= (*m
->loop
)(p
, state
, input
, input_length
, &output
, &output_length
);
111 if(output_length
> 0) {
113 base64_encode(output
, output_length
, &s
);
114 fprintf(p
->output
, "+ %s\r\n", s
);
123 auth_loop(POP
*p
, struct auth_mech
*m
)
129 status
= (*m
->init
)(p
, &state
);
131 status
= auth_execute(p
, m
, state
, p
->pop_parm
[2]);
133 while(status
== POP_AUTH_CONTINUE
) {
136 (*m
->cleanup
)(p
, state
);
137 return pop_msg(p
, POP_FAILURE
, "error reading data");
139 if(strcmp(line
, "*") == 0) {
140 (*m
->cleanup
)(p
, state
);
141 return pop_msg(p
, POP_FAILURE
, "terminated by client");
143 status
= auth_execute(p
, m
, state
, line
);
148 (*m
->cleanup
)(p
, state
);
149 if(status
== POP_AUTH_FAILURE
)
150 return pop_msg(p
, POP_FAILURE
, "%s", auth_msg
);
152 status
= login_user(p
);
153 if(status
!= POP_SUCCESS
)
155 return pop_msg(p
, POP_SUCCESS
, "authentication complete");
163 for (i
= 0; methods
[i
] != NULL
; ++i
)
164 if (strcasecmp(p
->pop_parm
[1], methods
[i
]->name
) == 0)
165 return auth_loop(p
, methods
[i
]);
166 return pop_msg(p
, POP_FAILURE
,
167 "Authentication method %s unknown", p
->pop_parm
[1]);
171 pop_capa_sasl(POP
*p
)
175 if(methods
[0] == NULL
)
178 fprintf(p
->output
, "SASL");
179 for (i
= 0; methods
[i
] != NULL
; ++i
)
180 fprintf(p
->output
, " %s", methods
[i
]->name
);
181 fprintf(p
->output
, "\r\n");