1e25c779eSMatthew Dillon /*-
2e25c779eSMatthew Dillon * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
3e25c779eSMatthew Dillon * All rights reserved.
4e25c779eSMatthew Dillon *
5e25c779eSMatthew Dillon * Redistribution and use in source and binary forms, with or without
6e25c779eSMatthew Dillon * modification, are permitted provided that the following conditions
7e25c779eSMatthew Dillon * are met:
8e25c779eSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
9e25c779eSMatthew Dillon * notice, this list of conditions and the following disclaimer.
10e25c779eSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
11e25c779eSMatthew Dillon * notice, this list of conditions and the following disclaimer in the
12e25c779eSMatthew Dillon * documentation and/or other materials provided with the distribution.
13e25c779eSMatthew Dillon *
14e25c779eSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15e25c779eSMatthew Dillon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16e25c779eSMatthew Dillon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17e25c779eSMatthew Dillon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18e25c779eSMatthew Dillon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19e25c779eSMatthew Dillon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20e25c779eSMatthew Dillon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21e25c779eSMatthew Dillon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22e25c779eSMatthew Dillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23e25c779eSMatthew Dillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24e25c779eSMatthew Dillon * SUCH DAMAGE.
25e25c779eSMatthew Dillon *
26e25c779eSMatthew Dillon */
27e25c779eSMatthew Dillon
28e25c779eSMatthew Dillon /*
29e25c779eSMatthew Dillon | $Id: auth_subr.c,v 2.2 2007/06/01 08:09:37 danny Exp $
30e25c779eSMatthew Dillon */
31e25c779eSMatthew Dillon
32e25c779eSMatthew Dillon #include <sys/param.h>
33e25c779eSMatthew Dillon #include <sys/types.h>
34e25c779eSMatthew Dillon #include <sys/socket.h>
35e25c779eSMatthew Dillon #include <sys/sysctl.h>
36e25c779eSMatthew Dillon
37e25c779eSMatthew Dillon #include <netinet/in.h>
38e25c779eSMatthew Dillon #include <netinet/tcp.h>
39e25c779eSMatthew Dillon #include <arpa/inet.h>
40e25c779eSMatthew Dillon #include <unistd.h>
41e25c779eSMatthew Dillon #include <stdlib.h>
42e25c779eSMatthew Dillon #include <stdio.h>
43e25c779eSMatthew Dillon #include <string.h>
44e25c779eSMatthew Dillon #include <fcntl.h>
45e25c779eSMatthew Dillon
46*66937313Szrj #include <openssl/md5.h>
47*66937313Szrj #include <openssl/sha.h>
48e25c779eSMatthew Dillon
49e25c779eSMatthew Dillon #include "iscsi.h"
50e25c779eSMatthew Dillon #include "iscontrol.h"
51e25c779eSMatthew Dillon
52e25c779eSMatthew Dillon static int
chapMD5(char id,char * cp,char * chapSecret,unsigned char * digest)53e25c779eSMatthew Dillon chapMD5(char id, char *cp, char *chapSecret, unsigned char *digest)
54e25c779eSMatthew Dillon {
55e25c779eSMatthew Dillon MD5_CTX ctx;
56e25c779eSMatthew Dillon char *tmp;
57e25c779eSMatthew Dillon int len;
58e25c779eSMatthew Dillon
59e25c779eSMatthew Dillon debug_called(3);
60e25c779eSMatthew Dillon
61*66937313Szrj MD5_Init(&ctx);
62e25c779eSMatthew Dillon
63*66937313Szrj MD5_Update(&ctx, &id, 1);
64e25c779eSMatthew Dillon
65e25c779eSMatthew Dillon if((len = str2bin(chapSecret, &tmp)) == 0) {
66e25c779eSMatthew Dillon // print error
67e25c779eSMatthew Dillon return -1;
68e25c779eSMatthew Dillon }
69*66937313Szrj MD5_Update(&ctx, tmp, len);
70e25c779eSMatthew Dillon free(tmp);
71e25c779eSMatthew Dillon
72e25c779eSMatthew Dillon if((len = str2bin(cp, &tmp)) == 0) {
73e25c779eSMatthew Dillon // print error
74e25c779eSMatthew Dillon return -1;
75e25c779eSMatthew Dillon }
76*66937313Szrj MD5_Update(&ctx, tmp, len);
77e25c779eSMatthew Dillon free(tmp);
78e25c779eSMatthew Dillon
79*66937313Szrj MD5_Final(digest, &ctx);
80e25c779eSMatthew Dillon
81e25c779eSMatthew Dillon
82e25c779eSMatthew Dillon return 0;
83e25c779eSMatthew Dillon }
84e25c779eSMatthew Dillon
85e25c779eSMatthew Dillon static int
chapSHA1(char id,char * cp,char * chapSecret,unsigned char * digest)86e25c779eSMatthew Dillon chapSHA1(char id, char *cp, char *chapSecret, unsigned char *digest)
87e25c779eSMatthew Dillon {
88*66937313Szrj SHA_CTX ctx;
89e25c779eSMatthew Dillon char *tmp;
90e25c779eSMatthew Dillon int len;
91e25c779eSMatthew Dillon
92e25c779eSMatthew Dillon debug_called(3);
93e25c779eSMatthew Dillon
94e25c779eSMatthew Dillon SHA1_Init(&ctx);
95e25c779eSMatthew Dillon
96e25c779eSMatthew Dillon SHA1_Update(&ctx, &id, 1);
97e25c779eSMatthew Dillon
98e25c779eSMatthew Dillon if((len = str2bin(chapSecret, &tmp)) == 0) {
99e25c779eSMatthew Dillon // print error
100e25c779eSMatthew Dillon return -1;
101e25c779eSMatthew Dillon }
102e25c779eSMatthew Dillon SHA1_Update(&ctx, tmp, len);
103e25c779eSMatthew Dillon free(tmp);
104e25c779eSMatthew Dillon
105e25c779eSMatthew Dillon if((len = str2bin(cp, &tmp)) == 0) {
106e25c779eSMatthew Dillon // print error
107e25c779eSMatthew Dillon return -1;
108e25c779eSMatthew Dillon }
109e25c779eSMatthew Dillon SHA1_Update(&ctx, tmp, len);
110e25c779eSMatthew Dillon free(tmp);
111e25c779eSMatthew Dillon
112e25c779eSMatthew Dillon SHA1_Final(digest, &ctx);
113e25c779eSMatthew Dillon
114e25c779eSMatthew Dillon return 0;
115e25c779eSMatthew Dillon
116e25c779eSMatthew Dillon }
117e25c779eSMatthew Dillon /*
118e25c779eSMatthew Dillon | the input text format can be anything that the rfc3270 defines
119e25c779eSMatthew Dillon | (see section 5.1 and str2bin)
120e25c779eSMatthew Dillon | digest length for md5 is 128bits, and for sha1 is 160bits.
121e25c779eSMatthew Dillon | digest is an ASCII string which represents the bits in
122e25c779eSMatthew Dillon | hexadecimal or base64 according to the challenge(cp) format
123e25c779eSMatthew Dillon */
124e25c779eSMatthew Dillon char *
chapDigest(char * ap,char id,char * cp,char * chapSecret)125e25c779eSMatthew Dillon chapDigest(char *ap, char id, char *cp, char *chapSecret)
126e25c779eSMatthew Dillon {
127e25c779eSMatthew Dillon int len;
128e25c779eSMatthew Dillon unsigned char digest[20];
129e25c779eSMatthew Dillon char encoding[3];
130e25c779eSMatthew Dillon
131e25c779eSMatthew Dillon debug_called(3);
132e25c779eSMatthew Dillon
133e25c779eSMatthew Dillon len = 0;
134e25c779eSMatthew Dillon if(strcmp(ap, "5") == 0 && chapMD5(id, cp, chapSecret, digest) == 0)
135e25c779eSMatthew Dillon len = 16;
136e25c779eSMatthew Dillon else
137e25c779eSMatthew Dillon if(strcmp(ap, "7") == 0 && chapSHA1(id, cp, chapSecret, digest) == 0)
138e25c779eSMatthew Dillon len = 20;
139e25c779eSMatthew Dillon
140e25c779eSMatthew Dillon if(len) {
141e25c779eSMatthew Dillon sprintf(encoding, "%.2s", cp);
142e25c779eSMatthew Dillon return bin2str(encoding, digest, len);
143e25c779eSMatthew Dillon }
144e25c779eSMatthew Dillon
145e25c779eSMatthew Dillon return NULL;
146e25c779eSMatthew Dillon }
147e25c779eSMatthew Dillon
148e25c779eSMatthew Dillon char *
genChapChallenge(char * encoding,size_t len)149e25c779eSMatthew Dillon genChapChallenge(char *encoding, size_t len)
150e25c779eSMatthew Dillon {
151e25c779eSMatthew Dillon int fd;
152e25c779eSMatthew Dillon unsigned char tmp[1024];
153e25c779eSMatthew Dillon
154e25c779eSMatthew Dillon if(len > sizeof(tmp))
155e25c779eSMatthew Dillon return NULL;
156e25c779eSMatthew Dillon
157e25c779eSMatthew Dillon if((fd = open("/dev/random", O_RDONLY)) != -1) {
158e25c779eSMatthew Dillon read(fd, tmp, len);
159e25c779eSMatthew Dillon close(fd);
160e25c779eSMatthew Dillon return bin2str(encoding, tmp, len);
161e25c779eSMatthew Dillon }
162e25c779eSMatthew Dillon perror("/dev/random");
163e25c779eSMatthew Dillon // make up something ...
164e25c779eSMatthew Dillon return NULL;
165e25c779eSMatthew Dillon }
166e25c779eSMatthew Dillon
167e25c779eSMatthew Dillon #ifdef TEST_AUTH
168e25c779eSMatthew Dillon static void
puke(char * str,unsigned char * dg,int len)169e25c779eSMatthew Dillon puke(char *str, unsigned char *dg, int len)
170e25c779eSMatthew Dillon {
171e25c779eSMatthew Dillon printf("%3d] %s\n 0x", len, str);
172e25c779eSMatthew Dillon while(len-- > 0)
173e25c779eSMatthew Dillon printf("%02x", *dg++);
174e25c779eSMatthew Dillon printf("\n");
175e25c779eSMatthew Dillon }
176e25c779eSMatthew Dillon
main(int cc,char ** vv)177e25c779eSMatthew Dillon main(int cc, char **vv)
178e25c779eSMatthew Dillon {
179e25c779eSMatthew Dillon char *p, *ap, *ip, *cp, *chapSecret, *digest;
180e25c779eSMatthew Dillon int len;
181e25c779eSMatthew Dillon
182e25c779eSMatthew Dillon #if 0
183e25c779eSMatthew Dillon ap = "5";
184e25c779eSMatthew Dillon chapSecret = "0xa5aff013dd839b1edd31ee73a1df0b1b";
185e25c779eSMatthew Dillon // chapSecret = "abcdefghijklmnop";
186e25c779eSMatthew Dillon len = str2bin(chapSecret, &cp);
187e25c779eSMatthew Dillon puke(chapSecret, cp, len);
188e25c779eSMatthew Dillon
189e25c779eSMatthew Dillon ip = "238";
190e25c779eSMatthew Dillon cp = "0xbd456029";
191e25c779eSMatthew Dillon
192e25c779eSMatthew Dillon
193e25c779eSMatthew Dillon if((digest = chapDigest(ap, ip, cp, chapSecret)) != NULL) {
194e25c779eSMatthew Dillon len = str2bin(digest, &cp);
195e25c779eSMatthew Dillon puke(digest, cp, len);
196e25c779eSMatthew Dillon }
197e25c779eSMatthew Dillon #else
198e25c779eSMatthew Dillon printf("%d] %s\n", 24, genChallenge("0X", 24));
199e25c779eSMatthew Dillon #endif
200e25c779eSMatthew Dillon }
201e25c779eSMatthew Dillon #endif
202