예제 #1
0
static char *
chap_BuildAnswer(char *name, char *key, u_char id, char *challenge
#ifndef NODES
		 , u_char type, char *peerchallenge, char *authresponse,
		 int lanman
#endif
                )
{
  char *result, *digest;
  size_t nlen, klen;

  nlen = strlen(name);
  klen = strlen(key);

#ifndef NODES
  if (type == 0x80) {
    char expkey[AUTHLEN << 2];
    MD4_CTX MD4context;
    size_t f;

    if ((result = malloc(1 + nlen + MS_CHAP_RESPONSE_LEN)) == NULL)
      return result;

    digest = result;					/* the response */
    *digest++ = MS_CHAP_RESPONSE_LEN;			/* 49 */
    memcpy(digest + MS_CHAP_RESPONSE_LEN, name, nlen);
    if (lanman) {
      memset(digest + 24, '\0', 25);
      mschap_LANMan(digest, challenge + 1, key);	/* LANMan response */
    } else {
      memset(digest, '\0', 25);
      digest += 24;

      for (f = 0; f < klen; f++) {
        expkey[2*f] = key[f];
        expkey[2*f+1] = '\0';
      }
      /*
       *           -----------
       * expkey = | k\0e\0y\0 |
       *           -----------
       */
      MD4Init(&MD4context);
      MD4Update(&MD4context, expkey, klen << 1);
      MD4Final(digest, &MD4context);

      /*
       *           ---- -------- ---------------- ------- ------
       * result = | 49 | LANMan | 16 byte digest | 9 * ? | name |
       *           ---- -------- ---------------- ------- ------
       */
      mschap_NT(digest, challenge + 1);
    }
    /*
     *           ---- -------- ------------- ----- ------
     *          |    |  struct MS_ChapResponse24  |      |
     * result = | 49 | LANMan  |  NT digest | 0/1 | name |
     *           ---- -------- ------------- ----- ------
     * where only one of LANMan & NT digest are set.
     */
  } else if (type == 0x81) {
    char expkey[AUTHLEN << 2];
    char pwdhash[CHAP81_HASH_LEN];
    char pwdhashhash[CHAP81_HASH_LEN];
    char *ntresponse;
    size_t f;

    if ((result = malloc(1 + nlen + CHAP81_RESPONSE_LEN)) == NULL)
      return result;

    memset(result, 0, 1 + nlen + CHAP81_RESPONSE_LEN);

    digest = result;
    *digest++ = CHAP81_RESPONSE_LEN;		/* value size */

    /* Copy our challenge */
    memcpy(digest, peerchallenge + 1, CHAP81_CHALLENGE_LEN);

    /* Expand password to Unicode XXX */
    for (f = 0; f < klen; f++) {
      expkey[2*f] = key[f];
      expkey[2*f+1] = '\0';
    }

    ntresponse = digest + CHAP81_NTRESPONSE_OFF;

    /* Get some needed hashes */
    NtPasswordHash(expkey, klen * 2, pwdhash);
    HashNtPasswordHash(pwdhash, pwdhashhash);

    /* Generate NTRESPONSE to respond on challenge call */
    GenerateNTResponse(challenge + 1, peerchallenge + 1, name,
                       expkey, klen * 2, ntresponse);

    /* Generate MPPE MASTERKEY */
    GetMasterKey(pwdhashhash, ntresponse, MPPE_MasterKey);    /* XXX Global ! */

    /* Generate AUTHRESPONSE to verify on auth success */
    GenerateAuthenticatorResponse(expkey, klen * 2, ntresponse,
                                  peerchallenge + 1, challenge + 1, name,
                                  authresponse);

    authresponse[CHAP81_AUTHRESPONSE_LEN] = 0;

    memcpy(digest + CHAP81_RESPONSE_LEN, name, nlen);
  } else
#endif
  if ((result = malloc(nlen + 17)) != NULL) {
    /* Normal MD5 stuff */
    MD5_CTX MD5context;

    digest = result;
    *digest++ = 16;				/* value size */

    MD5Init(&MD5context);
    MD5Update(&MD5context, &id, 1);
    MD5Update(&MD5context, key, klen);
    MD5Update(&MD5context, challenge + 1, *challenge);
    MD5Final(digest, &MD5context);

    memcpy(digest + 16, name, nlen);
    /*
     *           ---- -------- ------
     * result = | 16 | digest | name |
     *           ---- -------- ------
     */
  }

  return result;
}
예제 #2
0
int mresponse_main(int argc, char **argv) {
  uint8_t chap_ident = 0;
  uint8_t challenge[32];
  char buffer[512];
  MD5_CTX context;

  int idx = 0;
  int usent = 0;
  int usepap = 0;

  if (argc < 2)
    return usage(argv[0]);

  if (!strcmp(argv[1],"-nt")) {
    usent = 1;
    argc--;
    idx++;
  }

  if (!strcmp(argv[1],"-pap")) {
    usepap = 1;
    argc--;
    idx++;
  }

  if (usent && usepap)
    return usage(argv[0]);

  if (argc < 4)
    return usage(argv[0]);

  if (argc == 5) 
    chap_ident = atoi(argv[idx+4]);

  /* challenge - argv 1 */
  memset(buffer, 0, sizeof(buffer));
  strcpy(buffer, argv[idx+1]);
  hextochar(buffer, challenge, MD5LEN);

  /* uamsecret - argv 2 */
  MD5Init(&context);
  MD5Update(&context, challenge, MD5LEN);
  MD5Update(&context, (uint8_t*)argv[idx+2], strlen(argv[idx+2]));
  MD5Final(challenge, &context);

  if (usepap) {
    uint8_t user_password[RADIUS_PWSIZE + 1];
    uint8_t p[RADIUS_PWSIZE + 1];
    int m, n, plen = strlen(argv[idx+3]);
    
    memset(p, 0, sizeof(p));
    safe_strncpy((char *)p, argv[idx+3], RADIUS_PWSIZE);
    
    for (m=0; m < plen;) {
      for (n=0; n < REDIR_MD5LEN; m++, n++) {
	user_password[m] = p[m] ^ challenge[n];
      }
    }
    
    chartohex(user_password, buffer, plen);
    printf("%s\n", buffer);
    
  } else if (usent) {
    
#ifdef HAVE_OPENSSL
    uint8_t ntresponse[24];

    if (argc < 5)
      return usage(argv[0]);

    GenerateNTResponse(challenge, challenge,
		       (uint8_t*)argv[idx+3], strlen(argv[idx+3]),
		       (uint8_t*)argv[idx+4], strlen(argv[idx+4]),
		       ntresponse);
    chartohex(ntresponse, buffer, 24);
    printf("%s\n", buffer);

#else

    printf("Requires OpenSSL Support\n");

#endif

  } else {
    uint8_t response[32];

    /* password - argv 3 */
    MD5Init(&context);
    MD5Update(&context, (uint8_t*)&chap_ident, 1);	  
    MD5Update(&context, (uint8_t*)argv[idx+3], strlen(argv[idx+3]));
    MD5Update(&context, challenge, MD5LEN);
    MD5Final(response, &context);
    
    chartohex(response, buffer, MD5LEN);
    printf("%s\n", buffer);
  }

  return 0;
}