1171568Sscottl/*- 2211095Sdes * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il> 3171568Sscottl * All rights reserved. 4171568Sscottl * 5171568Sscottl * Redistribution and use in source and binary forms, with or without 6171568Sscottl * modification, are permitted provided that the following conditions 7171568Sscottl * are met: 8171568Sscottl * 1. Redistributions of source code must retain the above copyright 9171568Sscottl * notice, this list of conditions and the following disclaimer. 10171568Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11171568Sscottl * notice, this list of conditions and the following disclaimer in the 12171568Sscottl * documentation and/or other materials provided with the distribution. 13171568Sscottl * 14171568Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171568Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171568Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171568Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171568Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171568Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171568Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171568Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171568Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171568Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171568Sscottl * SUCH DAMAGE. 25171568Sscottl * 26171568Sscottl */ 27171568Sscottl 28171568Sscottl/* 29171568Sscottl | $Id: auth_subr.c,v 2.2 2007/06/01 08:09:37 danny Exp $ 30171568Sscottl */ 31171568Sscottl 32171568Sscottl#include <sys/cdefs.h> 33171568Sscottl__FBSDID("$FreeBSD$"); 34171568Sscottl 35171568Sscottl#include <sys/param.h> 36171568Sscottl#include <sys/types.h> 37171568Sscottl#include <sys/socket.h> 38171568Sscottl#include <sys/sysctl.h> 39171568Sscottl 40171568Sscottl#include <netinet/in.h> 41171568Sscottl#include <netinet/tcp.h> 42171568Sscottl#include <arpa/inet.h> 43171568Sscottl#include <unistd.h> 44171568Sscottl#include <stdlib.h> 45171568Sscottl#include <stdio.h> 46171568Sscottl#include <string.h> 47171568Sscottl#include <fcntl.h> 48171568Sscottl 49171568Sscottl#include <md5.h> 50171568Sscottl#include <sha.h> 51171568Sscottl 52254657Strasz#include <dev/iscsi_initiator/iscsi.h> 53171568Sscottl#include "iscontrol.h" 54171568Sscottl 55171568Sscottlstatic int 56171568SscottlchapMD5(char id, char *cp, char *chapSecret, unsigned char *digest) 57171568Sscottl{ 58171568Sscottl MD5_CTX ctx; 59171568Sscottl char *tmp; 60171568Sscottl int len; 61171568Sscottl 62171568Sscottl debug_called(3); 63171568Sscottl 64171568Sscottl MD5Init(&ctx); 65171568Sscottl 66171568Sscottl MD5Update(&ctx, &id, 1); 67171568Sscottl 68171568Sscottl if((len = str2bin(chapSecret, &tmp)) == 0) { 69171568Sscottl // print error 70171568Sscottl return -1; 71171568Sscottl } 72171568Sscottl MD5Update(&ctx, tmp, len); 73171568Sscottl free(tmp); 74171568Sscottl 75171568Sscottl if((len = str2bin(cp, &tmp)) == 0) { 76171568Sscottl // print error 77171568Sscottl return -1; 78171568Sscottl } 79171568Sscottl MD5Update(&ctx, tmp, len); 80171568Sscottl free(tmp); 81171568Sscottl 82171568Sscottl MD5Final(digest, &ctx); 83171568Sscottl 84171568Sscottl 85171568Sscottl return 0; 86171568Sscottl} 87171568Sscottl 88171568Sscottlstatic int 89171568SscottlchapSHA1(char id, char *cp, char *chapSecret, unsigned char *digest) 90171568Sscottl{ 91171568Sscottl SHA1_CTX ctx; 92171568Sscottl char *tmp; 93171568Sscottl int len; 94171568Sscottl 95171568Sscottl debug_called(3); 96171568Sscottl 97171568Sscottl SHA1_Init(&ctx); 98171568Sscottl 99171568Sscottl SHA1_Update(&ctx, &id, 1); 100171568Sscottl 101171568Sscottl if((len = str2bin(chapSecret, &tmp)) == 0) { 102171568Sscottl // print error 103171568Sscottl return -1; 104171568Sscottl } 105171568Sscottl SHA1_Update(&ctx, tmp, len); 106171568Sscottl free(tmp); 107171568Sscottl 108171568Sscottl if((len = str2bin(cp, &tmp)) == 0) { 109171568Sscottl // print error 110171568Sscottl return -1; 111171568Sscottl } 112171568Sscottl SHA1_Update(&ctx, tmp, len); 113171568Sscottl free(tmp); 114171568Sscottl 115171568Sscottl SHA1_Final(digest, &ctx); 116171568Sscottl 117171568Sscottl return 0; 118171568Sscottl 119171568Sscottl} 120171568Sscottl/* 121171568Sscottl | the input text format can be anything that the rfc3270 defines 122171568Sscottl | (see section 5.1 and str2bin) 123171568Sscottl | digest length for md5 is 128bits, and for sha1 is 160bits. 124171568Sscottl | digest is an ASCII string which represents the bits in 125171568Sscottl | hexadecimal or base64 according to the challenge(cp) format 126171568Sscottl */ 127171568Sscottlchar * 128171568SscottlchapDigest(char *ap, char id, char *cp, char *chapSecret) 129171568Sscottl{ 130171568Sscottl int len; 131171568Sscottl unsigned char digest[20]; 132171568Sscottl char encoding[3]; 133171568Sscottl 134171568Sscottl debug_called(3); 135171568Sscottl 136171568Sscottl len = 0; 137171568Sscottl if(strcmp(ap, "5") == 0 && chapMD5(id, cp, chapSecret, digest) == 0) 138171568Sscottl len = 16; 139171568Sscottl else 140171568Sscottl if(strcmp(ap, "7") == 0 && chapSHA1(id, cp, chapSecret, digest) == 0) 141171568Sscottl len = 20; 142171568Sscottl 143171568Sscottl if(len) { 144171568Sscottl sprintf(encoding, "%.2s", cp); 145171568Sscottl return bin2str(encoding, digest, len); 146171568Sscottl } 147171568Sscottl 148171568Sscottl return NULL; 149171568Sscottl} 150171568Sscottl 151171568Sscottlchar * 152211095SdesgenChapChallenge(char *encoding, uint len) 153171568Sscottl{ 154171568Sscottl int fd; 155171568Sscottl unsigned char tmp[1024]; 156171568Sscottl 157171568Sscottl if(len > sizeof(tmp)) 158171568Sscottl return NULL; 159171568Sscottl 160171568Sscottl if((fd = open("/dev/random", O_RDONLY)) != -1) { 161171568Sscottl read(fd, tmp, len); 162171568Sscottl close(fd); 163171568Sscottl return bin2str(encoding, tmp, len); 164171568Sscottl } 165171568Sscottl perror("/dev/random"); 166171568Sscottl // make up something ... 167171568Sscottl return NULL; 168171568Sscottl} 169171568Sscottl 170171568Sscottl#ifdef TEST_AUTH 171171568Sscottlstatic void 172171568Sscottlpuke(char *str, unsigned char *dg, int len) 173171568Sscottl{ 174171568Sscottl printf("%3d] %s\n 0x", len, str); 175171568Sscottl while(len-- > 0) 176171568Sscottl printf("%02x", *dg++); 177171568Sscottl printf("\n"); 178171568Sscottl} 179171568Sscottl 180171568Sscottlmain(int cc, char **vv) 181171568Sscottl{ 182171568Sscottl char *p, *ap, *ip, *cp, *chapSecret, *digest; 183171568Sscottl int len; 184171568Sscottl 185171568Sscottl#if 0 186171568Sscottl ap = "5"; 187171568Sscottl chapSecret = "0xa5aff013dd839b1edd31ee73a1df0b1b"; 188171568Sscottl// chapSecret = "abcdefghijklmnop"; 189171568Sscottl len = str2bin(chapSecret, &cp); 190171568Sscottl puke(chapSecret, cp, len); 191171568Sscottl 192171568Sscottl ip = "238"; 193171568Sscottl cp = "0xbd456029"; 194171568Sscottl 195171568Sscottl 196171568Sscottl if((digest = chapDigest(ap, ip, cp, chapSecret)) != NULL) { 197171568Sscottl len = str2bin(digest, &cp); 198171568Sscottl puke(digest, cp, len); 199171568Sscottl } 200171568Sscottl#else 201171568Sscottl printf("%d] %s\n", 24, genChallenge("0X", 24)); 202171568Sscottl#endif 203171568Sscottl} 204171568Sscottl#endif 205