/[mailutils]/mailutils/auth/gsasl.c
ViewVC logotype

Diff of /mailutils/auth/gsasl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by gray, Wed Jan 22 13:11:21 2003 UTC revision 1.2 by gray, Wed Jan 22 20:19:19 2003 UTC
# Line 23  Line 23 
23    
24  #include <stdlib.h>  #include <stdlib.h>
25  #include <string.h>  #include <string.h>
26    #include <limits.h>
27    #include <unistd.h>
28  #include <mailutils/argp.h>  #include <mailutils/argp.h>
29  #include <mailutils/error.h>  #include <mailutils/error.h>
30  #include <mailutils/mu_auth.h>  #include <mailutils/mu_auth.h>
# Line 31  Line 33 
33    
34  #include <gsasl.h>  #include <gsasl.h>
35    
36    char *gsasl_cram_md5_pwd = SITE_CRAM_MD5_PWD;
37    
38    #define ARG_CRAM_PASSWD 1
39    
40    static struct argp_option _gsasl_argp_options[] = {
41      {NULL, 0, NULL, 0, N_("GSASL options"), 0},
42      {"cram-passwd", ARG_CRAM_PASSWD, N_("FILE"), 0,
43       N_("Specify password file for CRAM-MD5 authentication"), 0},
44      { NULL,      0, NULL, 0, NULL, 0 }
45    };
46    
47    static error_t
48    _gsasl_argp_parser (int key, char *arg, struct argp_state *state)
49    {
50      switch (key)
51        {
52        case ARG_CRAM_PASSWD:
53          gsasl_cram_md5_pwd = arg;
54          break;
55    
56        default:
57          return ARGP_ERR_UNKNOWN;
58        }
59      return 0;
60    }
61    
62    static struct argp _gsasl_argp = {
63      _gsasl_argp_options,
64      _gsasl_argp_parser
65    };
66    
67    static struct argp_child _gsasl_argp_child = {
68      &_gsasl_argp,
69      0,
70      NULL,
71      0
72    };
73    
74    void
75    mu_gsasl_init_argp ()
76    {
77      if (mu_register_capa ("gsasl", &_gsasl_argp_child))
78        {
79          mu_error (_("INTERNAL ERROR: cannot register argp capability gsasl"));
80          abort ();
81        }
82    }
83    
84    
85  struct _gsasl_stream {  struct _gsasl_stream {
86    Gsasl_session_ctx *sess_ctx; /* Context */    Gsasl_session_ctx *sess_ctx; /* Context */
87    int last_err;        /* Last Gsasl error code */    int last_err;        /* Last Gsasl error code */
88        
89    stream_t stream;     /* Underlying stream */    int fd;              /* File descriptor */
   size_t offset;       /* Current offset */  
90    
91    char *buffer;        /* Line buffer */    char *buffer;        /* Line buffer */
92    size_t size;         /* Allocated size */    size_t size;         /* Allocated size */
# Line 47  static void Line 97  static void
97  _gsasl_destroy (stream_t stream)  _gsasl_destroy (stream_t stream)
98  {  {
99    struct _gsasl_stream *s = stream_get_owner (stream);    struct _gsasl_stream *s = stream_get_owner (stream);
   stream_destroy (&s->stream, stream_get_owner (s->stream));  
100    free (s->buffer);    free (s->buffer);
101    s->buffer = NULL;    s->buffer = NULL;
102  }  }
# Line 106  _gsasl_readline (stream_t stream, char * Line 155  _gsasl_readline (stream_t stream, char *
155      {      {
156        char buf[80];        char buf[80];
157        size_t sz;        size_t sz;
         
       rc = stream_readline (s->stream, buf, sizeof (buf), s->offset, &sz);  
       if (rc)  
         return rc;  
158    
159        s->offset += sz;        sz = read (s->fd, buf, sizeof (buf));
160                if (sz == (size_t) -1)
161            {
162              if (errno == EINTR)
163                continue;
164              return errno;
165            }
166    
167        rc = buffer_grow (s, buf, sz);        rc = buffer_grow (s, buf, sz);
168        if (rc)        if (rc)
169          return rc;          return rc;
170    
171          len = UINT_MAX; /* override the bug in libgsasl */
172        rc = gsasl_decode (s->sess_ctx, s->buffer, s->level, NULL, &len);        rc = gsasl_decode (s->sess_ctx, s->buffer, s->level, NULL, &len);
173      }      }
174    while (rc == GSASL_NEEDS_MORE);    while (rc == GSASL_NEEDS_MORE);
# Line 148  _gsasl_readline (stream_t stream, char * Line 200  _gsasl_readline (stream_t stream, char *
200        len = osize;        len = osize;
201      }      }
202    else    else
203      memcpy (optr, bufp, len);      {
204          buffer_drop (s);
205          memcpy (optr, bufp, len);
206        }
207      
208    if (nbytes)    if (nbytes)
209      *nbytes = len;      *nbytes = len;
210        
# Line 158  _gsasl_readline (stream_t stream, char * Line 213  _gsasl_readline (stream_t stream, char *
213    return 0;    return 0;
214  }  }
215    
216    int
217    write_chunk (struct _gsasl_stream *s, char *start, char *end)
218    {
219      size_t chunk_size = end - start + 1;
220      size_t len;
221      size_t wrsize;
222      char *buf = NULL;
223          
224      len = UINT_MAX; /* override the bug in libgsasl */
225      gsasl_encode (s->sess_ctx, start, chunk_size, NULL, &len);
226      buf = malloc (len);
227      if (!buf)
228        return ENOMEM;
229    
230      gsasl_encode (s->sess_ctx, start, chunk_size, buf, &len);
231    
232      wrsize = 0;
233      do
234        {
235          size_t sz = write (s->fd, buf + wrsize, len - wrsize);
236          if (sz == (size_t)-1)
237            {
238              if (errno == EINTR)
239                continue;
240              free (buf);
241              return errno;
242            }
243          wrsize += sz;
244        }
245      while (wrsize < len);
246      
247      free (buf);
248    
249      return 0;
250    }
251    
252    
253  static int  static int
254  _gsasl_write (stream_t stream, const char *iptr, size_t isize,  _gsasl_write (stream_t stream, const char *iptr, size_t isize,
255                off_t offset, size_t *nbytes)                off_t offset, size_t *nbytes)
256  {  {
257    int rc;    int rc;
258      size_t total = 0;
259    struct _gsasl_stream *s = stream_get_owner (stream);    struct _gsasl_stream *s = stream_get_owner (stream);
260        
261    rc = buffer_grow (s, iptr, isize);    rc = buffer_grow (s, iptr, isize);
262    if (rc)    if (rc)
263      return rc;      return rc;
264      
265    if (s->level >= 2    if (s->level > 2)
       && s->buffer[s->level - 2] == '\r'  
       && s->buffer[s->level - 1] == '\n')  
266      {      {
267        size_t len, wrsize;        char *start, *end;
       char *buf = NULL;  
268                
269        gsasl_encode (s->sess_ctx, s->buffer, s->level, NULL, &len);        for (start = s->buffer, end = strchr (start, '\n');
270        buf = malloc (len);             end && end < s->buffer + s->level;
271        if (!buf)             start = end + 1, end = strchr (start, '\n'))
272          return ENOMEM;          if (end[-1] == '\r')
273              {
274        gsasl_encode (s->sess_ctx, s->buffer, s->level, buf, &len);              int rc = write_chunk (s, start, end);
275        rc = stream_write (s->stream, buf, len, s->offset, &wrsize);              if (rc)
276        free (buf);                return rc;
277        if (rc)            }
         return rc;  
       s->offset += wrsize;  
278    
279        if (nbytes)        if (start > s->buffer)
280          *nbytes = wrsize;          {
281              if (start < s->buffer + s->level)
282                {
283                  int rest = s->buffer + s->level - start + 1;
284                  memmove (s->buffer, start, rest);
285                  s->level = rest;
286                }
287              else
288                s->level = 0;
289            }
290        }
291      
292      if (nbytes)
293        *nbytes = isize;
294                
       s->level = 0;  
   }  
295    return 0;    return 0;
296  }  }
297    
298  static int  static int
299  _gsasl_flush (stream_t stream)  _gsasl_flush (stream_t stream)
300  {  {
   struct _gsasl_stream *s = stream_get_owner (stream);  
   stream_flush (s->stream);  
301    return 0;    return 0;
302  }  }
303    
304  static int  static int
305  _gsasl_close (stream_t stream)  _gsasl_close (stream_t stream)
306  {  {
307      int flags;
308    struct _gsasl_stream *s = stream_get_owner (stream);    struct _gsasl_stream *s = stream_get_owner (stream);
309    stream_close (s->stream);  
310      stream_get_flags (stream, &flags);
311      if (!(flags & MU_STREAM_NO_CLOSE))
312        close (s->fd);
313    if (s->sess_ctx)    if (s->sess_ctx)
314      gsasl_server_finish (s->sess_ctx);      gsasl_server_finish (s->sess_ctx);
315    return 0;    return 0;
# Line 231  _gsasl_strerror (stream_t stream, const Line 332  _gsasl_strerror (stream_t stream, const
332    
333    
334  int  int
335  gsasl_stream_create (stream_t *stream, stream_t ins,  gsasl_stream_create (stream_t *stream, int fd,
336                       Gsasl_session_ctx *ctx, int flags)                       Gsasl_session_ctx *ctx, int flags)
337  {  {
338    struct _gsasl_stream *s;    struct _gsasl_stream *s;
339      int rc;
340        
341    if (stream == NULL)    if (stream == NULL)
342      return EINVAL;      return EINVAL;
343    
# Line 248  gsasl_stream_create (stream_t *stream, s Line 350  gsasl_stream_create (stream_t *stream, s
350    if (s == NULL)    if (s == NULL)
351      return ENOMEM;      return ENOMEM;
352    
353    s->stream = ins;    s->fd = fd;
354    s->sess_ctx = ctx;    s->sess_ctx = ctx;
355    
356      rc = stream_create (stream, flags|MU_STREAM_NO_CHECK, s);
357      if (rc)
358        {
359          free (s);
360          return rc;
361        }
362    
363    stream_set_open (*stream, _gsasl_open, s);    stream_set_open (*stream, _gsasl_open, s);
364    stream_set_close (*stream, _gsasl_close, s);    stream_set_close (*stream, _gsasl_close, s);
365    stream_set_flush (*stream, _gsasl_flush, s);    stream_set_flush (*stream, _gsasl_flush, s);
# Line 261  gsasl_stream_create (stream_t *stream, s Line 370  gsasl_stream_create (stream_t *stream, s
370      stream_set_readline (*stream, _gsasl_readline, s);      stream_set_readline (*stream, _gsasl_readline, s);
371    else    else
372      stream_set_write (*stream, _gsasl_write, s);      stream_set_write (*stream, _gsasl_write, s);
373        
374    return 0;    return 0;
375  }  }
376        

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26