Logo Search packages:      
Sourcecode: yubikey-server-c version File versions  Download package

util.c

/*
  Copyright (C) 2009 Tollef Fog Heen <tfheen@err.no>
  
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License version 2 as
  published by the Free Software Foundation.
  
  This program 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 General Public License for more details.
  
  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <assert.h>
#include "util.h"

void *ysc_memdup(void *p, size_t len)
{
      void *r;
      r = malloc(len);
      assert(r != NULL);
      memcpy(r, p, len);
      return r;
}

size_t ysc_nstrstr(const char *haystack, const char *needle)
{
      size_t n = 0;
      while ((haystack = strstr(haystack, needle)) != NULL) {
            n++;
            haystack += strlen(needle);
      }
      return n;
}


/* Like strftime, but better, calls strftime under the hood
   %N => nanoseconds (not implemented)
   %v => milliseconds

   if tv is null, call gettimeofday for you
*/

size_t ysc_strftime(char *s, size_t max, const char *format,
                const struct timeval *tv) {
      struct tm tm;
      int i, j, flen;
      struct timeval tvv;
      /* '%v' is two bytes less than what a %v needs */
      size_t fdup_len = strlen(format) + ysc_nstrstr(format, "%v") * 2;
      char *fdup = malloc(fdup_len); /* XXX check failure */
      size_t r;

      if (tv == NULL)
        assert(gettimeofday(&tvv, NULL) == 0);
      else {
        memcpy(&tvv, tv, sizeof(struct timeval));
      }
      gmtime_r(&tvv.tv_sec, &tm);
      /* Do %N and %v first, then hand off to strftime */
      flen = strlen(format);
      for (i = 0, j = 0; i < flen; i++, j++) {
            if (format[i] == '%') {
                  switch (format[i+1]) {
/*                case 'N':
                        break;
*/
                  case 'v':
                        j += snprintf(fdup+j, 4, "%.3zd",
                                    tvv.tv_usec / 1000);
                        i++;
                        continue;
                        break;
                  default:
                        fdup[j] = format[i];
                        continue;
                  }
            } else {
                  fdup[j] = format[i];
            }
      }
      r = strftime(s, max, fdup, &tm);
      free(fdup);
      return r;
}

/* Base 64 functions */

/*
 * AUTHOR:         Bob Trower 08/04/01
 *
 * COPYRIGHT:      Copyright (c) Trantor Standard Systems Inc., 2001
 *
 * LICENCE:        Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

unsigned char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static void ysc_b64_encodeblock(unsigned char in[3], unsigned char out[4], int len)
{
      out[0] = cb64[in[0] >> 2];
      out[1] = cb64[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
      out[2] = (unsigned char) (len > 1 ? cb64[((in[1] & 0x0f) << 2) |
                                     (len > 2 ? 
                                      ((in[2] & 0xc0) >> 6) :
                                      0 )] : '=');
      out[3] = (unsigned char) (len > 2 ? cb64[in[2] & 0x3f] : '=');
}

char *ysc_b64_encode(char *s, ssize_t len)
{
      char *r = calloc((len/3+1)*4+1, 1);
      char *tmp = r;
      unsigned char out[4];

      while (len > 0) {
            ysc_b64_encodeblock((unsigned char*)s, out, len);
            memcpy(tmp, out, 4);
            tmp += 4;
            len -= 3;
            s += 3;
      }
      return r;
}

static void ysc_b64_decodeblock(unsigned const char in[4], unsigned char out[3])
{
      out[0] = (unsigned char) ((in[0] - 'A') << 2 | (in[1] - 'A') >> 4);
      out[1] = (unsigned char) ((in[1] - 'A') << 4 | (in[2] - 'A') >> 2);
      out[2] = (unsigned char) ((((in[2] - 'A') << 6) & 0xc0) | (in[3] - 'A'));
}

ssize_t ysc_b64_decode(const char *s, char **decoded)
{
      ssize_t len = strlen(s);
      char *tmp;
      unsigned char out[3];
      ssize_t r = 0;

      *decoded = malloc((len/4+1)*3+1);
      tmp = *decoded;
      if ((len % 4) != 0) {
            return 0;
            /* XXX free memory */
      }

      while (*s != '\0') {
            ysc_b64_decodeblock((unsigned char*)s, out);
            memcpy(tmp, out, 3);
            tmp += 3;
            if (s[2] == '=') {
                  r += 1;
            } else if (s[3] == '=') {
                  r += 2;
            } else {
                  r += 3;
            }
            s += 4;
      }
      return r;
}

Generated by  Doxygen 1.6.0   Back to index