Logo Search packages:      
Sourcecode: ddns3-client version File versions  Download package

auth.c

/*
 *    DDNS v3 Client
 *
 *          Author:           Alan Yates <alany@ay.com.au>
 *          Version:    $Id: auth.c,v 1.1.1.1 2002/07/19 11:47:20 alany Exp $
 */
#define _XOPEN_SOURCE
#ifdef WIN32
#include <windows.h>
#include <process.h>
#else
#include <unistd.h>
#endif
#include <string.h>
#include "ctx.h"
#include "auth.h"
#include "crypto.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static char *ddns3_auth_salts = 
      "abcdefghijklmnopqrstuzwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890./";

static int
auth_plaintext(struct ddns3_ctx *c, char *user, char *passwd) {
      if(!strstr(c->hello, "plaintext")) return -1;

      sprintf(c->buf, "LOGIN %s %s", user, passwd);
      return 0;
}

#ifndef WIN32
static int
auth_crypt(struct ddns3_ctx *c, char *user, char *passwd) {
      char salt[2];
      char *hash;

      if(!strstr(c->hello, "crypt")) return -1;

      srand(getpid() * time(0));
      salt[0] = ddns3_auth_salts[rand() % strlen(ddns3_auth_salts)];
      salt[1] = ddns3_auth_salts[rand() % strlen(ddns3_auth_salts)];
      hash = ddns3_crypto_crypt(passwd, salt);
      sprintf(c->buf, "LOGIN %s %s", user, hash);
      free(hash);
      return 0;
}
#endif

static int
auth_md5(struct ddns3_ctx *c, char *user, char *passwd) {
      char *hash;

      if(!strstr(c->hello, "md5")) return -1;

      hash = ddns3_crypto_md5hash(passwd, strlen(passwd));
      sprintf(c->buf, "LOGIN %s %s", user, hash);
      free(hash);
      return 0;
}

static int
auth_ddns(struct ddns3_ctx *c, char *user, char *passwd) {
      char *hash, *p;
      char buf[4096];

      if(!strstr(c->hello, "ddns")) return -1;

      strcpy(buf, passwd);
      strcat(buf, ":");
      p = strstr(c->hello, "ddns{");
      strncat(buf, p+5, 32);
      hash = ddns3_crypto_md5hash(buf, strlen(buf));
      sprintf(c->buf, "LOGIN %s %s", user, hash);
      free(hash);
      return 0;
}

/* FIXME: there is no server support for strong auth yet */
static int
auth_strong(struct ddns3_ctx *c, char *user, char *passwd) {
      char *phash, *uhash, *challenge, *p;
      char buf[4096];
      int i;

      if(!strstr(c->hello, "ddns")) return -1;

      /* password hash */
      strcpy(buf, passwd);
      strcat(buf, ":");
      p = strstr(c->hello, "ddns{");
      strncat(buf, p+5, 32);
      phash = ddns3_crypto_md5hash(buf, strlen(buf));

      /* random challenge */
      srand(getpid() * time(0));
      for(i = 0; i < 100; i++) buf[i] = rand();
      challenge = ddns3_crypto_md5hash(buf, 100);

      /* username hash */
      strcpy(buf, user);
      strcat(buf, ":");
      strncat(buf, challenge, 32);
      uhash = ddns3_crypto_md5hash(buf, strlen(buf));

      sprintf(c->buf, "LOGIN %s %s %s", uhash, phash, challenge);

      free(uhash);
      free(phash);
      free(challenge);
      return 0;
}


static struct ddns3_auth known_auths[] = {
      {"plaintext",     auth_plaintext},
#ifndef WIN32
      {"crypt",   auth_crypt},
#endif
      {"md5",           auth_md5},
      {"ddns",    auth_ddns},
      {"strong",  auth_strong},
      {0, 0}
};

int
ddns3_auth_makechallenge(struct ddns3_ctx *c, char *auth, char *user, char *passwd) {
      int i;
      int ret = -2;
      
      for(i = 0; known_auths[i].name; i++)
            if(!strcmp(known_auths[i].name, auth)) {
                  ret = known_auths[i].makechallenge(c, user, passwd);
                  break;
            }
      if(ret < -1)
            strcpy(c->buf, "client_error: authentication type unknown to client\n");
      else if(ret < 0)
            strcpy(c->buf, "client_error: authentication type not supported by server\n");

      return ret;
}

Generated by  Doxygen 1.6.0   Back to index