1 /*
2  *
3  *   Ophcrack is a Lanmanager/NTLM hash cracker based on the faster time-memory
4  *   trade-off using rainbow tables.
5  *
6  *   Created with the help of: Maxime Mueller, Luca Wullschleger, Claude
7  *   Hochreutiner, Andreas Huber and Etienne Dysli.
8  *
9  *   Copyright (c) 2008 Philippe Oechslin, Cedric Tissieres, Bertrand Mesot
10  *
11  *   Ophcrack is free software; you can redistribute it and/or modify
12  *   it under the terms of the GNU General Public License as published by
13  *   the Free Software Foundation; either version 2 of the License, or
14  *   (at your option) any later version.
15  *
16  *   Ophcrack is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *   GNU General Public License for more details.
20  *
21  *   You should have received a copy of the GNU General Public License
22  *   along with Ophcrack; if not, write to the Free Software
23  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  *
25  *   This program is released under the GPL with the additional exemption
26  *   that compiling, linking, and/or using OpenSSL is allowed.
27  *
28  *
29  *
30  *
31 */
32 #include <stdlib.h>
33 #include <pthread.h>
34 #include <string.h>
35 #include <semaphore.h>
36 
37 #include "message.h"
38 /*-------------------------------------------------------------------------*/
39 pthread_mutex_t *msg_mutex = 0;
40 sem_t *msg_sem = 0;
41 
42 list_t *msg_queue;
43 struct timeval msg_time;
44 /*-------------------------------------------------------------------------*/
message_init(void)45 void message_init(void) {
46   msg_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
47   pthread_mutex_init(msg_mutex, 0);
48 
49 #ifndef OSX
50   msg_sem = (sem_t*)malloc(sizeof(sem_t));
51 
52   if (sem_init(msg_sem, 0, 0) != 0) {
53     fprintf(stderr, "message_init: cannot initialise the semaphore\n");
54     exit(1);
55   }
56 #else
57   sem_unlink("ophcrack_message");
58   msg_sem = sem_open("ophcrack_message", O_CREAT | O_EXCL, 0, 0);
59 
60   if (msg_sem == SEM_FAILED) {
61     fprintf(stderr, "message_init: cannot initialise the semaphore\n");
62     exit(1);
63   }
64 #endif
65 
66   msg_queue = list_alloc();
67   gettimeofday(&msg_time, 0);
68 }
69 /*-------------------------------------------------------------------------*/
message_alloc(msg_kind_t kind)70 message_t *message_alloc(msg_kind_t kind) {
71   static uint32_t gid = 0;
72 
73   message_t *msg = (message_t*)malloc(sizeof(message_t));
74   msg->kind = kind;
75   msg->data = 0;
76   msg->id   = gid++;
77 
78   gettimeofday(&msg->time, 0);
79   msg->time.tv_sec -= msg_time.tv_sec;
80 
81   return msg;
82 }
83 /*-------------------------------------------------------------------------*/
message_free(message_t * msg)84 void message_free(message_t *msg) {
85   switch (msg->kind) {
86   case msg_done: {
87     msg_done_t *done = msg->data;
88     free(done);
89   } break;
90 
91   case msg_preload:
92   case msg_unload: {
93     msg_load_t *load = msg->data;
94     free(load);
95   } break;
96 
97   case msg_work: {
98     msg_work_t *work = msg->data;
99     free(work);
100   } break;
101 
102   case msg_found: {
103     msg_found_t *found = msg->data;
104     free(found);
105   } break;
106 
107   case msg_bforce: {
108     msg_bforce_t *force = msg->data;
109     free(force);
110   } break;
111 
112   case msg_pause:
113     break;
114   }
115 
116   free(msg);
117 }
118 /*-------------------------------------------------------------------------*/
message_add(message_t * msg)119 void message_add(message_t *msg) {
120   pthread_mutex_lock(msg_mutex);
121   list_add_tail(msg_queue, msg);
122 
123   sem_post(msg_sem);
124   pthread_mutex_unlock(msg_mutex);
125 }
126 /*-------------------------------------------------------------------------*/
message_insert_first(list_t * messages)127 void message_insert_first(list_t *messages) {
128   pthread_mutex_lock(msg_mutex);
129 
130   while (messages->size > 0) {
131     message_t *msg = list_rem_tail(messages);
132 
133     list_add_head(msg_queue, msg);
134     sem_post(msg_sem);
135   }
136 
137   pthread_mutex_unlock(msg_mutex);
138 }
139 /*-------------------------------------------------------------------------*/
message_get(void)140 message_t *message_get(void) {
141   sem_wait(msg_sem);
142 
143   pthread_mutex_lock(msg_mutex);
144   message_t *msg = list_rem_head(msg_queue);
145   pthread_mutex_unlock(msg_mutex);
146 
147   return msg;
148 }
149 /*-------------------------------------------------------------------------*/
message_tryget(void)150 message_t *message_tryget(void) {
151   int ret = sem_trywait(msg_sem);
152   message_t *msg = 0;
153 
154   if (ret == 0) {
155     pthread_mutex_lock(msg_mutex);
156     msg = list_rem_head(msg_queue);
157     pthread_mutex_unlock(msg_mutex);
158   }
159 
160   return msg;
161 }
162 /*-------------------------------------------------------------------------*/
message_done(ophkind_t kind)163 void message_done(ophkind_t kind) {
164   message_t *msg = message_alloc(msg_done);
165   msg_done_t *done = (msg_done_t*)malloc(sizeof(msg_done_t));
166 
167   done->kind = kind;
168 
169   msg->data = done;
170   message_add(msg);
171 }
172 /*-------------------------------------------------------------------------*/
message_preload(table_t * tbl,table_preload_t preload,int done,uint64_t size)173 void message_preload(table_t *tbl, table_preload_t preload, int done, uint64_t size) {
174   message_t *msg = message_alloc(msg_preload);
175   msg_load_t *load = (msg_load_t*)malloc(sizeof(msg_load_t));
176 
177   load->tbl = tbl;
178   load->preload = preload;
179   load->done = done;
180   load->size = size;
181 
182   msg->data = load;
183   message_add(msg);
184 }
185 /*-------------------------------------------------------------------------*/
message_unload(table_t * tbl,uint64_t size)186 void message_unload(table_t *tbl, uint64_t size) {
187   message_t *msg = message_alloc(msg_unload);
188   msg_load_t *load = (msg_load_t*)malloc(sizeof(msg_load_t));
189 
190   load->tbl = tbl;
191   load->preload = preload_none;
192   load->done = 1;
193   load->size = size;
194 
195   msg->data = load;
196   message_add(msg);
197 }
198 /*-------------------------------------------------------------------------*/
message_work(hash_t * hsh,table_t * tbl,ophkind_t kind,int cmin,int cmax)199 void message_work(hash_t *hsh, table_t *tbl, ophkind_t kind, int cmin, int cmax) {
200   message_t *msg = message_alloc(msg_work);
201   msg_work_t *work = (msg_work_t*)malloc(sizeof(msg_work_t));
202 
203   work->hsh   = hsh;
204   work->tbl   = tbl;
205   work->kind  = kind;
206   work->cmin  = cmin;
207   work->cmax  = cmax;
208 
209   msg->data = work;
210   message_add(msg);
211 }
212 /*-------------------------------------------------------------------------*/
message_found(hash_t * hsh,table_t * tbl,int col)213 void message_found(hash_t *hsh, table_t *tbl, int col) {
214   message_t *msg = message_alloc(msg_found);
215   msg_found_t *found = (msg_found_t*)malloc(sizeof(msg_found_t));
216 
217   found->hsh = hsh;
218   found->tbl = tbl;
219   found->col = col;
220 
221   msg->data = found;
222   message_add(msg);
223 }
224 /*-------------------------------------------------------------------------*/
message_bforce(int done,uint64_t count)225 void message_bforce(int done, uint64_t count) {
226   message_t *msg = message_alloc(msg_bforce);
227   msg_bforce_t *force = (msg_bforce_t*)malloc(sizeof(msg_bforce_t));
228 
229   force->done  = done;
230   force->count = count;
231 
232   msg->data = force;
233   message_add(msg);
234 }
235 /*-------------------------------------------------------------------------*/
message_pause(void)236 void message_pause(void) {
237   message_t *msg = message_alloc(msg_pause);
238   message_add(msg);
239 }
240