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