New silcconfig library and server parser. Merged silc-newconfig-final.patch.
[silc.git] / apps / silcer / src / silcerapp.cc
1 /*
2
3   silcerapp.cc 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silcerapp.hh"
21 #include "gtkspell.h"
22
23 #include <sys/utsname.h>
24 #include <glade/glade.h>
25 #include <libgnome/gnome-triggers.h>
26 #include <libgnome/gnome-util.h>
27 #include <libgnomeui/gnome-window-icon.h>
28 #include <gnome--/client.h>
29
30 // Pointer to the application
31 SilcerApp *Silcer_App;
32 string package = "silcer";
33 string version = "1.0";
34
35 SilcClient silc_client;
36 SilcClientConnection silc_client_conn;
37
38 static int 
39 silc_create_key_pair(char *pkcs_name, int bits, char *path,
40                      char *identifier, 
41                      SilcPublicKey *ret_pub_key,
42                      SilcPrivateKey *ret_prv_key)
43 {
44   SilcPKCS pkcs;
45   SilcPublicKey pub_key;
46   SilcPrivateKey prv_key;
47   SilcRng rng;
48   unsigned char *key;
49   uint32 key_len;
50   char pkfile[256], prvfile[256];
51
52   if (!pkcs_name || !path)
53     return FALSE;
54
55   if (!bits)
56     bits = 1024;
57
58   rng = silc_rng_alloc();
59   silc_rng_init(rng);
60   silc_rng_global_init(rng);
61
62   /* Generate keys */
63   silc_pkcs_alloc((const unsigned char *)pkcs_name, &pkcs);
64   pkcs->pkcs->init(pkcs->context, bits, rng);
65
66   /* Save public key into file */
67   key = silc_pkcs_get_public_key(pkcs, &key_len);
68   pub_key = silc_pkcs_public_key_alloc(pkcs->pkcs->name, identifier,
69                                        key, key_len);
70   *ret_pub_key = pub_key;
71
72   memset(key, 0, sizeof(key_len));
73   silc_free(key);
74
75   /* Save private key into file */
76   key = silc_pkcs_get_private_key(pkcs, &key_len);
77   prv_key = silc_pkcs_private_key_alloc(pkcs->pkcs->name, key, key_len);
78   *ret_prv_key = prv_key;
79
80   memset(key, 0, sizeof(key_len));
81   silc_free(key);
82
83   silc_rng_free(rng);
84   silc_pkcs_free(pkcs);
85
86   return TRUE;
87 }
88
89 static
90 void silc_op_say(SilcClient client, SilcClientConnection conn, 
91                  SilcClientMessageType type, char *msg, ...)
92 {
93   va_list va;
94   char *str;
95
96   va_start(va, msg);
97   str = g_strdup_vprintf(msg, va);
98   Silcer_App->_MainDialog->print((string)str);
99   g_free(str);
100   va_end(va);
101 }
102
103 static
104 void silc_channel_message(SilcClient client, SilcClientConnection conn, 
105                           SilcClientEntry sender, SilcChannelEntry channel, 
106                           SilcMessageFlags flags, char *msg)
107 {
108   Silcer_App->_MainDialog->print((string)msg, (string)sender->nickname);
109 }
110
111 static
112 void silc_private_message(SilcClient client, SilcClientConnection conn,
113                           SilcClientEntry sender, SilcMessageFlags flags,
114                           char *msg)
115 {
116   Silcer_App->_MainDialog->print((string)msg);
117 }
118
119 static
120 void silc_notify(SilcClient client, SilcClientConnection conn, 
121                  SilcNotifyType type, ...)
122 {
123   va_list va;
124   
125   va_start(va, type);
126   Silcer_App->_MainDialog->print((string)va_arg(va, char *));
127   va_end(va);
128 }
129
130 static
131 void silc_connect(SilcClient client, SilcClientConnection conn, int success)
132 {
133   silc_client_conn = conn;
134 }
135
136 static
137 void silc_disconnect(SilcClient client, SilcClientConnection conn)
138 {
139   silc_client_conn = NULL;
140 }
141
142 static
143 void silc_auth_meth(SilcClient client, 
144                     SilcClientConnection conn,
145                     char *hostname, uint16 port,
146                     SilcGetAuthMeth completion, void *context)
147 {
148   completion(TRUE, SILC_AUTH_NONE, NULL, 0, context);
149 }
150
151 static
152 void silc_verify_public_key(SilcClient client, SilcClientConnection conn,
153                             SilcSocketType conn_type, unsigned char *pk, 
154                             uint32 pk_len, SilcSKEPKType pk_type,
155                             SilcVerifyPublicKey completion, void *context)
156 {
157   completion(TRUE, context);
158 }
159
160 static
161 void silc_command(SilcClient client, SilcClientConnection conn, 
162                   SilcClientCommandContext cmd_context, int success,
163                   SilcCommand command)
164 {
165
166 }
167
168 static
169 void silc_command_reply(SilcClient client, SilcClientConnection conn,
170                         SilcCommandPayload cmd_payload, int success,
171                         SilcCommand command, SilcCommandStatus status, ...)
172 {
173
174 }
175
176 /* SILC client operations */
177 SilcClientOperations ops = {
178   silc_op_say,
179   silc_channel_message,
180   silc_private_message,
181   silc_notify,
182   silc_command,
183   silc_command_reply,
184   silc_connect,
185   silc_disconnect,
186   silc_auth_meth,
187   silc_verify_public_key,
188   NULL,
189   NULL,
190   NULL,
191   NULL
192 };
193
194 SILC_TASK_CALLBACK(connect_client)
195 {
196   SilcClient client = (SilcClient)context;
197   silc_client_connect_to_server(client, 706, "silc.silcnet.org", NULL);
198 }
199
200 SilcerApp::SilcerApp(int argc, char **argv)
201   : _GnomeApp(package, version, argc, argv),
202   _gclient(Gnome::Client::master_client())
203 {
204   // Save application pointer
205   Silcer_App = this;
206
207   // Initialize SILC stuff
208   silc_debug = TRUE;
209   silc_debug_hexdump = TRUE;
210   silc_log_set_debug_string("*client*,*net*,*ske*");
211
212   // Initialize SILC Client Library */
213   silc_client = silc_client_alloc(&ops, NULL, NULL, "SILC-1.0-0.6.2");
214   silc_client->realname = "Foo T. Bar";
215   silc_client->username = "foobar";
216   silc_client->hostname = "foo.bar.foobar.com";
217   silc_cipher_register_default();
218   silc_pkcs_register_default();
219   silc_hash_register_default();
220   silc_hmac_register_default();
221   silc_create_key_pair("rsa", 1024, "kk", "UN=foobar, "
222                        "HN=foo.bar.foobar.com", 
223                        &silc_client->public_key, &silc_client->private_key);
224   silc_client_init(silc_client);
225
226   // Setup SILC scheduler as timeout task
227   Gnome::Main::timeout.connect(slot(this, &SilcerApp::silc_scheduler), 50);
228
229   // XXXXX
230   // This is now used to directly connect to silc.silcnet.org router
231   // XXXXX
232   silc_schedule_task_add(silc_client->schedule, 0, connect_client, 
233                          silc_client, 0, 1, SILC_TASK_TIMEOUT, 
234                          SILC_TASK_PRI_NORMAL); 
235
236    // Initialize glade
237   glade_gnome_init();
238
239   // Locate glade files
240   if (!g_file_exists(string(_SourceDir + "SilcerMainDlg.glade").c_str()))
241     _SourceDir = "./";
242   if (!g_file_exists(string(_SourceDir + "SilcerMainDlg.glade").c_str()))
243     _SourceDir = "./ui/";
244   if (!g_file_exists(string(_SourceDir + "SilcerMainDlg.glade").c_str()))
245     _SourceDir = "./src/";
246   if (!g_file_exists(string(_SourceDir + "SilcerMainDlg.glade").c_str())) {
247     g_error("Could not find SilcerMainDlg.glade");
248     exit(-1);
249   }
250
251   _MainDialog = new SilcerMainDlg();
252 }
253
254 SilcerApp::~SilcerApp()
255 {
256   delete _MainDialog;
257 }
258
259 void SilcerApp::run()
260 {
261   // Let the gnome app start processing messages
262   Gnome::Main::run();
263 }
264
265 void SilcerApp::quit()
266 {
267   // Stop gtk/gnome message loop
268   Gnome::Main::quit();
269   delete Silcer_App;
270 }
271
272 GladeXML *SilcerApp::load_resource(const char *name)
273 {
274   return glade_xml_new(string(_SourceDir + name + ".glade").c_str(), name);
275 }
276
277 GladeXML *SilcerApp::load_resource(const char *name, const char *filename)
278 {
279   return glade_xml_new(string(_SourceDir + filename + ".glade").c_str(), name);
280 }
281
282 gint SilcerApp::silc_scheduler()
283 {
284   // Run the SILC client once, and return immediately.  This function
285   // is called every 50 milliseconds by the Gnome main loop, to process
286   // SILC stuff.  This function will read data, and write data to network,
287   // etc.  Makes the client library tick! :)
288   silc_client_run_one(silc_client);
289   return 1;
290 }