1 /*
2  *	Apple Filing Protocol Support - by David Maciejak @ GMAIL dot com
3  *
4  *	tested with afpfs-ng 0.8.1
5  *	AFPFS-NG: http://alexthepuffin.googlepages.com/home
6  *
7  */
8 
9 #include "hydra-mod.h"
10 
11 #ifndef LIBAFP
dummy_afp()12 void dummy_afp() { printf("\n"); }
13 #else
14 
15 #define FREE(x)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                \
16   if (x != NULL) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             \
17     free(x);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \
18     x = NULL;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \
19   }
20 
21 #include <afpfs-ng/afp.h>
22 #include <afpfs-ng/libafpclient.h>
23 #include <stdio.h>
24 
25 extern char *HYDRA_EXIT;
26 
stdout_fct(void * priv,enum loglevels loglevel,int32_t logtype,const char * message)27 void stdout_fct(void *priv, enum loglevels loglevel, int32_t logtype, const char *message) {
28   // fprintf(stderr, "[ERROR] Caught unknown error %s\n", message);
29 }
30 
31 static struct libafpclient afpclient = {
32     .unmount_volume = NULL,
33     .log_for_client = stdout_fct,
34     .forced_ending_hook = NULL,
35     .scan_extra_fds = NULL,
36     .loop_started = NULL,
37 };
38 
server_subconnect(struct afp_url url)39 static int32_t server_subconnect(struct afp_url url) {
40   struct afp_connection_request *conn_req;
41   struct afp_server *server = NULL;
42 
43   conn_req = malloc(sizeof(struct afp_connection_request));
44   //  server = malloc(sizeof(struct afp_server));
45 
46   memset(conn_req, 0, sizeof(struct afp_connection_request));
47 
48   conn_req->url = url;
49   conn_req->url.requested_version = 31;
50 
51   // fprintf(stderr, "AFP connection - username: %s password: %s server: %s\n",
52   // url.username, url.password, url.servername);
53 
54   if (strlen(url.uamname) > 0) {
55     if ((conn_req->uam_mask = find_uam_by_name(url.uamname)) == 0) {
56       fprintf(stderr, "[ERROR] Unknown UAM: %s\n", url.uamname);
57       FREE(conn_req);
58       FREE(server);
59       return -1;
60     }
61   } else {
62     conn_req->uam_mask = default_uams_mask();
63   }
64 
65   // fprintf(stderr,  "Initiating connection attempt.\n");
66   if ((server = afp_server_full_connect(NULL, conn_req)) == NULL) {
67     FREE(conn_req);
68     //    FREE(server);
69     return -1;
70   }
71   // fprintf(stderr,  "Connected to server: %s via UAM: %s\n",
72   // server->server_name_printable, uam_bitmap_to_string(server->using_uam));
73 
74   FREE(conn_req);
75   FREE(server);
76 
77   return 0;
78 }
79 
start_afp(int32_t s,char * ip,int32_t port,unsigned char options,char * miscptr,FILE * fp)80 int32_t start_afp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
81   char *empty = "";
82   char *login, *pass, mlogin[AFP_MAX_USERNAME_LEN], mpass[AFP_MAX_PASSWORD_LEN];
83   struct afp_url tmpurl;
84 
85   /* Build AFP authentication request */
86   libafpclient_register(&afpclient);
87   afp_main_quick_startup(NULL);
88   init_uams();
89   afp_default_url(&tmpurl);
90 
91   if (strlen(login = hydra_get_next_login()) == 0)
92     login = empty;
93   if (strlen(pass = hydra_get_next_password()) == 0)
94     pass = empty;
95 
96   strncpy(tmpurl.servername, hydra_address2string(ip), AFP_SERVER_NAME_LEN - 1);
97   tmpurl.servername[AFP_SERVER_NAME_LEN] = 0;
98   strncpy(mlogin, login, AFP_MAX_USERNAME_LEN - 1);
99   mlogin[AFP_MAX_USERNAME_LEN - 1] = 0;
100   strncpy(mpass, pass, AFP_MAX_PASSWORD_LEN - 1);
101   mpass[AFP_MAX_PASSWORD_LEN - 1] = 0;
102   memcpy(&tmpurl.username, mlogin, AFP_MAX_USERNAME_LEN);
103   memcpy(&tmpurl.password, mpass, AFP_MAX_PASSWORD_LEN);
104 
105   if (server_subconnect(tmpurl) == 0) {
106     hydra_report_found_host(port, ip, "afp", fp);
107     hydra_completed_pair_found();
108     if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
109       return 3;
110     return 2;
111   } else {
112     hydra_completed_pair();
113     if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
114       return 2;
115   }
116   return 1;
117 }
118 
service_afp(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)119 void service_afp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
120   int32_t run = 1, next_run = 1, sock = -1;
121   int32_t myport = PORT_AFP;
122 
123   hydra_register_socket(sp);
124   if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
125     return;
126 
127   while (1) {
128     switch (run) {
129     case 1: /* connect and service init function */
130       if (sock >= 0)
131         sock = hydra_disconnect(sock);
132       if ((options & OPTION_SSL) == 0) {
133         if (port != 0)
134           myport = port;
135         sock = hydra_connect_tcp(ip, myport);
136         port = myport;
137       }
138       if (sock < 0) {
139         if (quiet != 1)
140           fprintf(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int32_t)getpid());
141         hydra_child_exit(1);
142       }
143 
144       next_run = 2;
145       break;
146 
147     case 2:
148 
149       /*
150        *      Here we start the password cracking process
151        */
152 
153       next_run = start_afp(sock, ip, port, options, miscptr, fp);
154       break;
155     case 3:
156 
157       if (sock >= 0)
158         sock = hydra_disconnect(sock);
159       hydra_child_exit(0);
160       return;
161 
162     default:
163 
164       fprintf(stderr, "[ERROR] Caught unknown return code, exiting!\n");
165       hydra_child_exit(0);
166     }
167     run = next_run;
168   }
169 }
170 
171 #endif
172 
service_afp_init(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)173 int32_t service_afp_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
174   // called before the childrens are forked off, so this is the function
175   // which should be filled if initial connections and service setup has to be
176   // performed once only.
177   //
178   // fill if needed.
179   //
180   // return codes:
181   //   0 all OK
182   //   -1  error, hydra will exit, so print a good error message here
183 
184   return 0;
185 }
186