syncing examples
[tprouty/samba.git] / examples / LDAP / smbldap-tools / mkntpwd / mkntpwd.c
1 /*
2         This code is based on work from 
3         L0phtcrack 1.5 06.02.97 mudge@l0pht.com
4
5         The code also contains sources from:
6                 . routines from the samba code source
7                   md4.c smbdes.c
8
9         Anton Roeckseisen (anton@genua.de)
10
11 */
12
13 /*
14  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "mkntpwd.h"
28
29 void str_to_key(unsigned char *,unsigned char *);
30 void usage(char *);
31 int PutUniCode(char *dst,char *src);
32 void printlanhash(char *tmp);
33 void mdfour(unsigned char *out, unsigned char *in, int n);
34 void E_P16(unsigned char *p14,unsigned char *p16);
35
36
37 void main(int argc, char **argv) {
38         extern char *optarg;
39         int c;
40
41         int printlan = 0;
42         char lanpwd[LMPASSWDLEN+1];
43         int printnt = 0;
44         char inputfile[FILENAMEBUFFER+1] = "";
45         FILE* InputFilePtr;
46         int just_pwd = 0;
47         int i;
48         char hashout[17];
49
50         char ntpasswd[NTPASSWDLEN+1]; 
51         char *hold;
52         unsigned char *p16;
53         int uni_len;
54         char passwd[NTPASSWDLEN+1];
55
56         if (argc==1)
57                 usage(argv[0]);
58
59         if (argc==2)
60                 just_pwd=1;
61         else
62                 just_pwd=0;
63
64         lanpwd[0] = '\0';
65         ntpasswd[0] = '\0';
66
67         while ( (c = getopt(argc, argv, "L:N:f:")) != EOF){
68                 switch(c) {
69                 case 'L':
70                         printlan++;
71                         strncpy(lanpwd,optarg,LMPASSWDLEN);
72                         lanpwd[LMPASSWDLEN]='\0';
73                         for (i=0;i<LMPASSWDLEN;i++)
74                                 lanpwd[i]=toupper(lanpwd[i]);
75                         break;
76                 case 'N':
77                         printnt++;
78                         strncpy(passwd,optarg,NTPASSWDLEN);
79                         passwd[NTPASSWDLEN]='\0';
80                         break;
81                 case 'f': 
82                         strncpy(inputfile,optarg,FILENAMEBUFFER);
83                         inputfile[FILENAMEBUFFER]='\0';
84                         break;
85                 default:
86                         usage(argv[0]);
87                 }
88         }
89
90         /* Get password from file or STDIN */
91         if (inputfile[0]!='\0') {
92
93                 just_pwd=0; /* make sure no shit is happening... */
94
95                 /* get NT-password (longer) */
96                 if (strcmp(inputfile,"-")==0) {
97                         fgets(passwd,NTPASSWDLEN,stdin);
98                 } else {
99                         if ((InputFilePtr=fopen(inputfile,"r")) == NULL)
100                                 fprintf(stderr,"Couldn't open passwordfile: %s",inputfile) ;
101                         fgets(passwd,NTPASSWDLEN,InputFilePtr);
102                         fclose(InputFilePtr);
103                 }
104                 while (strlen(passwd)>0 && passwd[strlen(passwd)-1]=='\n')
105                         passwd[strlen(passwd)-1]='\0';
106
107                 /* create LANMAN-password (shorter) */
108                 strncpy(lanpwd,passwd,LMPASSWDLEN);
109                 lanpwd[LMPASSWDLEN]='\0';
110                 for (i=0;i<LMPASSWDLEN;i++)
111                         lanpwd[i]=toupper(lanpwd[i]);
112                 printlan++;
113                 printnt++;
114
115         }
116
117
118         /* Assume the one and only Arg is the new password! */
119
120         if (argc>1 && just_pwd==1) { 
121                 strncpy(lanpwd,argv[1],LMPASSWDLEN);
122                 lanpwd[LMPASSWDLEN]='\0';
123                 for (i=0;i<LMPASSWDLEN;i++)
124                         lanpwd[i]=toupper(lanpwd[i]);
125                 printlan++;
126
127                 strncpy(passwd,argv[1],NTPASSWDLEN);
128                 passwd[NTPASSWDLEN]='\0';
129                 printnt++;
130         }
131
132         if (printlan >0) {
133                 memset(hashout,'\0',17);
134                 E_P16((uchar *)lanpwd,hashout);
135                 printlanhash(hashout);
136         }
137
138         if (printnt >0) {
139
140                 if (printlan>0) printf(":");
141
142                 memset(ntpasswd, '\0', sizeof(ntpasswd));
143
144                 if (passwd[strlen(passwd)-1] == '\n') /* strip the \n - this 
145                                         is done in LowerString for the case sensitive
146                                         check */
147                 passwd[strlen(passwd)-1] = '\0';
148
149                 hold = (char *)malloc(NTPASSWDLEN * 2); /* grab space for 
150                                                        unicode */
151                 if (hold == NULL){
152                         fprintf(stderr, "out of memory...crackntdialog hold\n");
153                         exit(1);
154                 }
155
156                 uni_len = PutUniCode(hold, passwd); /* convert to 
157                                                    unicode and return correct 
158                                                    unicode length for md4 */
159
160                 p16 = (unsigned char*)malloc(17); /* grab space for md4 hash */
161                 if (p16 == NULL){
162                       fprintf(stderr, "out of memory...crackntdialect p16\n");
163                       exit(1);
164                 }
165                 
166                 memset(p16,'\0',17);
167                 mdfour(p16,hold, uni_len);
168
169                 printlanhash(p16);
170                     
171                 free(p16);
172                 free(hold);
173         }
174
175         printf("\n");
176
177         exit(0);
178
179 }
180
181 /*****************************************************************************/
182 /*****************************************************************************/
183 /*****************************************************************************/
184
185 void usage(char *progname){
186    char *p;
187
188    p = strrchr(progname, '\\');
189    if (p == NULL)
190         p = progname;
191    else
192         p++;
193
194    fprintf(stderr, "Usage: %s [-L lanmgrpwd] [-N ntpasswd]\n",p);
195    fprintf(stderr, "       %s password\n",p);
196    fprintf(stderr, "       %s -f [-] [filename]\n\n",p);
197    fprintf(stderr, "     -L lanmgrpasswd  LanManager cleartextpwd <= 14 chars\n");
198    fprintf(stderr, "     -N ntpasswd      NT cleartextpwd <=128 chars (usually <=14)\n\n");
199    fprintf(stderr, "     with both options present the encrypted LanManager-Pwd is \n");
200    fprintf(stderr, "     printed first, followed by a ':' and the encrypted NT-Pwd.\n\n");
201    fprintf(stderr, "     The second usage behaves like %s -L pwd -N pwd\n\n",p);
202    fprintf(stderr, "     The third usage reads the password from STDIN or a File. Printout\n");
203    fprintf(stderr, "     is the same as second.\n\n");
204    fprintf(stderr, "anton@genua.de\n\n");
205    exit(1);
206 }
207
208
209 /*******************************************************************
210 write a string in unicoode format
211 ********************************************************************/
212 int PutUniCode(char *dst,char *src) 
213 {                       
214   int ret = 0;  
215   while (*src) {
216     dst[ret++] = src[0];
217     dst[ret++] = 0;
218     src++;
219   }
220   dst[ret++]=0; 
221   dst[ret++]=0; 
222   return(ret-2); /* the way they do the md4 hash they don't represent
223                     the last null. ie 'A' becomes just 0x41 0x00 - not
224                     0x41 0x00 0x00 0x00 */
225 }
226
227 /*
228   print binary buffer as hex-string
229 */
230 void printlanhash(char *tmp) {
231
232         int i;
233         unsigned char c;
234         char outbuffer[33];
235
236
237         /* build string from binary hash */
238         for(i=0;i<16;i++) {
239                 c=tmp[i];
240                 sprintf(outbuffer+2*i,"%x",(c>>4) & 0x0f);
241                 sprintf(outbuffer+2*i+1,"%x",c & 0x0f);
242         }
243
244         /* convert to uppercase */
245         for(i=0;i<32;i++)
246                 outbuffer[i] = toupper(outbuffer[i]);
247         outbuffer[32]='\0';
248
249         /* print out hex-string */
250         printf("%s",outbuffer);
251 }
252
253