gsasl-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CVS gsasl/lib/digest-md5


From: gsasl-commit
Subject: CVS gsasl/lib/digest-md5
Date: Fri, 17 Dec 2004 04:41:51 +0100

Update of /home/cvs/gsasl/lib/digest-md5
In directory dopio:/tmp/cvs-serv18400

Added Files:
        test-parser.c parser.h parser.c 
Log Message:
Add, unfinished.



--- /home/cvs/gsasl/lib/digest-md5/test-parser.c        2004/12/17 03:41:50     
NONE
+++ /home/cvs/gsasl/lib/digest-md5/test-parser.c        2004/12/17 03:41:50     
1.1
/* test-parser.c --- Self tests of DIGEST-MD5 parser.
 * Copyright (C) 2004  Simon Josefsson
 *
 * This file is part of GNU SASL Library.
 *
 * GNU SASL Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * GNU SASL Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with GNU SASL Library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *
 */

#include <stdio.h>

#include "parser.h"

int
main (int argc, char *argv[])
{
  digest_md5_finish tmp;
  int rc;

  {
    char *token = "rspauth=\"4711\"";

    rc = digest_md5_parse_finish (token, &tmp);
    if (rc == 0)
      printf ("`%s' -> `%s'? %s\n", token, tmp.rspauth,
              strcmp ("4711", tmp.rspauth) == 0 ? "ok" : "FAILURE");
    else
      printf ("FAILURE\n");
  }

  {
    char *token = "rspauth=\"4711\", foo=bar";

    rc = digest_md5_parse_finish (token, &tmp);
    if (rc == 0)
      printf ("FAILURE\n");
    else
      printf ("`%s' -> invalid? ok\n", token);
  }

  {
    char *token = "rspauth=4711, foo=bar";

    rc = digest_md5_parse_finish (token, &tmp);
    if (rc == 0)
      printf ("FAILURE\n");
    else
      printf ("`%s' -> invalid? ok\n", token);
  }

  return 0;
}
--- /home/cvs/gsasl/lib/digest-md5/parser.h     2004/12/17 03:41:50     NONE
+++ /home/cvs/gsasl/lib/digest-md5/parser.h     2004/12/17 03:41:50     1.1
/* parser.h --- DIGEST-MD5 parser.
 * Copyright (C) 2004  Simon Josefsson
 *
 * This file is part of GNU SASL Library.
 *
 * GNU SASL Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * GNU SASL Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with GNU SASL Library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *
 */

/* Get size_t. */
#include <stddef.h>

/*
 * digest-challenge  =
 *       1#( realm | nonce | qop-options | stale | server_maxbuf | charset
 *             algorithm | cipher-opts | auth-param )
 *
 * realm             = "realm" "=" <"> realm-value <">
 * realm-value       = qdstr-val
 * nonce             = "nonce" "=" <"> nonce-value <">
 * nonce-value       = *qdtext
 * qop-options       = "qop" "=" <"> qop-list <">
 * qop-list          = 1#qop-value
 * qop-value         = "auth" | "auth-int" | "auth-conf" | qop-token
 *                    ;; qop-token is reserved for identifying future
 *                    ;; extensions to DIGEST-MD5
 * qop-token         = token
 * stale             = "stale" "=" "true"
 * server_maxbuf     = "maxbuf" "=" maxbuf-value
 * maxbuf-value      = 1*DIGIT
 * charset           = "charset" "=" "utf-8"
 * algorithm         = "algorithm" "=" "md5-sess"
 * cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
 * cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
 *                     "rc4-56" | "aes-cbc" | cipher-token
 *                     ;; "des" and "3des" ciphers are obsolete.
 *                     ;; cipher-token is reserved for new ciphersuites
 * cipher-token      = token
 * auth-param        = token "=" ( token | quoted-string )
 *
 */
struct digest_md5_challenge {
  size_t nrealms;
  char **realms;
  char *nonce;
  char *qop;
  int stale;
  unsigned long servermaxbuf;
  int utf8;
  char *ciphers;
};
typedef struct digest_md5_challenge digest_md5_challenge;

/*
 * digest-response  = 1#( username | realm | nonce | cnonce |
 *                        nonce-count | qop | digest-uri | response |
 *                        client_maxbuf | charset | cipher | authzid |
 *                        auth-param )
 *
 *     username         = "username" "=" <"> username-value <">
 *     username-value   = qdstr-val
 *     cnonce           = "cnonce" "=" <"> cnonce-value <">
 *     cnonce-value     = *qdtext
 *     nonce-count      = "nc" "=" nc-value
 *     nc-value         = 8LHEX
 *     client_maxbuf    = "maxbuf" "=" maxbuf-value
 *     qop              = "qop" "=" qop-value
 *     digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
 *     digest-uri-value  = serv-type "/" host [ "/" serv-name ]
 *     serv-type        = 1*ALPHA
 *     serv-name        = host
 *     response         = "response" "=" response-value
 *     response-value   = 32LHEX
 *     LHEX             = "0" | "1" | "2" | "3" |
 *                        "4" | "5" | "6" | "7" |
 *                        "8" | "9" | "a" | "b" |
 *                        "c" | "d" | "e" | "f"
 *     cipher           = "cipher" "=" cipher-value
 *     authzid          = "authzid" "=" <"> authzid-value <">
 *     authzid-value    = qdstr-val
 *
 */
struct digest_md5_response {
  char *username;
  char *realm;
  char *nonce;
  char *cnonce;
  unsigned long noncecount;
  char *qop;
  char *digesturi;
  char *response;
  unsigned long clientmaxbuf;
  int utf8;
  int cipher;
  char *authzid;
};
typedef struct digest_md5_response digest_md5_response;


/*
 * response-auth = "rspauth" "=" response-value
 */
struct digest_md5_finish {
  char *rspauth;
};
typedef struct digest_md5_finish digest_md5_finish;

extern int digest_md5_parse_challenge (const char *challenge,
                                       digest_md5_challenge *out);

extern int digest_md5_parse_response (const char *response,
                                      digest_md5_response *out);

extern int digest_md5_parse_finish (const char *finish,
                                    digest_md5_finish *out);
--- /home/cvs/gsasl/lib/digest-md5/parser.c     2004/12/17 03:41:51     NONE
+++ /home/cvs/gsasl/lib/digest-md5/parser.c     2004/12/17 03:41:51     1.1
/* parser.c --- DIGEST-MD5 parser.
 * Copyright (C) 2004  Simon Josefsson
 *
 * This file is part of GNU SASL Library.
 *
 * GNU SASL Library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * GNU SASL Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with GNU SASL Library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307 USA
 *
 */

#if HAVE_CONFIG_H
# include "config.h"
#endif

/* Get prototypes. */
#include "parser.h"

/* Get malloc, free. */
#include <stdlib.h>

/* Get memcpy, strlen. */
#include <string.h>

/* Parse comma separate list into words.
   Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
   From the GNU C Library, under GNU LGPL version 2.1.
   Contributed by Ulrich Drepper <address@hidden>, 1996.
   Modified for Libgsasl by Simon Josefsson <address@hidden>
   Copyright (C) 2002  Simon Josefsson

   Parse comma separated suboption from *OPTIONP and match against
   strings in TOKENS.  If found return index and set *VALUEP to
   optional value introduced by an equal sign.  If the suboption is
   not part of TOKENS return in *VALUEP beginning of unknown
   suboption.  On exit *OPTIONP is set to the beginning of the next
   token or at the terminating NUL character.  */
static int
digest_md5_getsubopt (char **optionp,
                      const char *const *tokens,
                      char **valuep)
{
  char *endp, *vstart;
  int cnt;
  int inside_quote = 0;

  if (**optionp == '\0')
    return -1;

  /* Find end of next token.  */
  endp = *optionp;
  while (*endp != '\0' && (inside_quote || (!inside_quote && *endp != ',')))
    {
      if (*endp == '"')
        inside_quote = !inside_quote;
      endp++;
    }

  /* Find start of value.  */
  vstart = memchr (*optionp, '=', endp - *optionp);
  if (vstart == NULL)
    vstart = endp;

  /* Try to match the characters between *OPTIONP and VSTART against
     one of the TOKENS.  */
  for (cnt = 0; tokens[cnt] != NULL; ++cnt)
    if (memcmp (*optionp, tokens[cnt], vstart - *optionp) == 0
        && tokens[cnt][vstart - *optionp] == '\0')
      {
        /* We found the current option in TOKENS.  */
        *valuep = vstart != endp ? vstart + 1 : NULL;

        while (*valuep && (**valuep == ' ' ||
                           **valuep == '\t' ||
                           **valuep == '\r' ||
                           **valuep == '\n' || **valuep == '"'))
          (*valuep)++;

        if (*endp != '\0')
          {
            *endp = '\0';
            *optionp = endp + 1;
          }
        else
          *optionp = endp;
        endp--;
        while (*endp == ' ' ||
               *endp == '\t' ||
               *endp == '\r' || *endp == '\n' || *endp == '"')
          *endp-- = '\0';
        while (**optionp == ' ' ||
               **optionp == '\t' || **optionp == '\r' || **optionp == '\n')
          (*optionp)++;

        return cnt;
      }

  /* The current suboption does not match any option.  */
  *valuep = *optionp;

  if (*endp != '\0')
    *endp++ = '\0';
  *optionp = endp;
  while (**optionp == ' ' ||
         **optionp == '\t' || **optionp == '\r' || **optionp == '\n')
    (*optionp)++;

  return -1;
}
#define MAXBUF_MIN 17
#define MAXBUF_MAX 16777215
#define DEFAULT_CHARSET "utf-8"
#define DEFAULT_ALGORITHM "md5-sess"

enum
  {
    /* the order must match the following struct */
    CHALLENGE_REALM = 0,
    CHALLENGE_NONCE,
    CHALLENGE_QOP,
    CHALLENGE_STALE,
    CHALLENGE_MAXBUF,
    CHALLENGE_CHARSET,
    CHALLENGE_ALGORITHM,
    CHALLENGE_CIPHER
  };

const char *const digest_challenge_opts[] = {
  /* the order must match the previous enum */
  "realm",
  "nonce",
  "qop",
  "stale",
  "maxbuf",
  "charset",
  "algorithm",
  "cipher",
  NULL
};

static int
parse_challenge (char *challenge, digest_md5_challenge *out)
{
  int done_algorithm;
  char *value;

  memset (out, 0, sizeof (*out));

  while (*challenge != '\0')
    switch (digest_md5_getsubopt (&challenge, digest_challenge_opts, &value))
      {
      case CHALLENGE_REALM:
        {
          char **tmp;
          out->nrealms++;
          tmp = realloc (out->realms, out->nrealms * sizeof (*out->realms));
          if (!tmp)
            return -1;
          out->realms = tmp;
          out->realms[out->nrealms - 1] = strdup (value);
          if (!out->realms[out->nrealms - 1])
            return -1;
        }
        break;

      case CHALLENGE_NONCE:
        if (out->nonce)
          return -1;
        out->nonce = strdup (value);
        if (!out->nonce)
          return -1;
        break;

      case CHALLENGE_QOP:
        /* FIXME: sub-parse. */
        if (out->qop)
          return -1;
        out->qop = strdup (value);
        if (!out->qop)
          return -1;
        break;

      case CHALLENGE_STALE:
        if (out->stale)
          return -1;
        out->stale = 1;
        break;

      case CHALLENGE_MAXBUF:
        if (out->servermaxbuf)
          return -1;
        out->servermaxbuf = strtoul (value, NULL, 10);
        if (out->servermaxbuf < MAXBUF_MIN
            || out->servermaxbuf > MAXBUF_MAX)
          return -1;
        break;

[172 lines skipped]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]