Merge pull request #85 from Callum-/dilatometer
[matches/MCTX3420.git] / testing / login / login.c
1 #define _BSD_SOURCE
2 #define _XOPEN_SOURCE
3
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <pwd.h>
10 #include <assert.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <stdbool.h>
14
15 // Compile with: gcc -std=c99 -lcrypt
16
17 /** Deliberately make this smaller so we can test for buffer overflow problems **/
18 #define BUFSIZ 50
19
20
21 bool EnterTheShadowRealm(const char * shadow, const char * salt, const char * username, const char * passwd)
22 {
23
24         if (strlen(username) + strlen(passwd) >= BUFSIZ-1)
25         {
26                 fprintf(stderr, "User/Password too long!\n");
27                 return false;
28         }
29
30         FILE * f = fopen(shadow, "r");
31         if (f == NULL)
32         {
33                 fprintf(stderr, "Can't open %s - %s\n", shadow, strerror(errno));
34                 return false;
35         }
36
37         char buffer[BUFSIZ];
38         int passwd_index = -1;
39         int garbage_index = -1;
40         while (fgets(buffer, BUFSIZ, f) != NULL) // NOTE: Restrict username+password strings to BUFSIZ... what could possibly go wrong?
41         {
42
43                 printf("Scanning %d: %s", strlen(buffer), buffer);
44         
45                 for (int i = 0; i < BUFSIZ-1; ++i)
46                 {
47                         if (buffer[i] == ':')
48                         {
49                                 buffer[i] = '\0';
50                                 passwd_index = i+1;
51                                 break;
52                         }
53                 }
54
55                 if (strcmp(username,buffer) == 0)
56                 {
57                         printf("User matches! %s\n", buffer);
58                         break;
59                 } 
60                 passwd_index = -1;
61         }
62
63         if (passwd_index <= 0)
64         {
65                 fprintf(stderr, "No user found matching %s\n", username);
66                 return false;
67         }
68
69         for (int i = passwd_index; i < BUFSIZ-1; ++i)
70         {
71                 if (buffer[i] == ':' || buffer[i] == '\n')
72                 {
73                         buffer[i] = '\0';
74                         garbage_index = i+1;
75                 }
76         }
77
78         printf("Salted Entry: %s\n", buffer+passwd_index);
79         printf("Salted Attempt: %s\n", crypt(passwd, salt));
80         
81         return (strcmp(crypt(passwd, salt), passwd) == 0);
82         
83 }
84
85
86 int main(int argc, char ** argv)
87 {
88         char * shadow = "shadow";
89         if (argc > 1)
90         {
91                 shadow = argv[1];
92         }
93
94
95         
96         
97         // Get the username and password
98         // Need to get these passed through HTTPS at some point
99         printf("Username: ");
100         char username[BUFSIZ];
101         if (fgets(username, BUFSIZ, stdin) != username)
102         {
103                 fprintf(stderr, "Username too long!\n");
104                 exit(EXIT_FAILURE);
105         }
106
107         username[strlen(username)-1] = '\0';
108
109         char * password = getpass("Password: "); //NOTE: getpass is deprecated. Just here for testing.
110         password[strlen(password)-1] = '\0';
111         
112         printf("Could we enter the shadow realm? %d\n", EnterTheShadowRealm(shadow, "A9", username, password));
113         
114         
115         
116         return 0;
117 }

UCC git Repository :: git.ucc.asn.au