From: Pekka Riikonen Date: Sun, 21 Oct 2001 17:53:11 +0000 (+0000) Subject: updates. X-Git-Tag: silcertest~72 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=70fceb1b71e76e1ff2719988cad63a9113b38641 updates. --- diff --git a/CHANGES b/CHANGES index 0e8d4c6a..77ccd3a9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +Sun Oct 21 20:21:02 EDT 2001 Pekka Riikonen + + * Renamed silc_file_read and silc_file_write to functions + silc_file_readfile and silc_file_writefile. Added function + silc_file_open and silc_file_close. Affected files + lib/silcutil/silcutil.[ch]. + Thu Oct 18 20:58:13 EDT 2001 Pekka Riikonen * Resolve the client info when received private message or diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 6324f3df..b832c49e 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -1172,8 +1172,7 @@ void silc_failure(SilcClient client, SilcClientConnection conn, int silc_key_agreement(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, char *hostname, - int port, - SilcKeyAgreementCallback *completion, + uint16 port, SilcKeyAgreementCallback *completion, void **context) { char portstr[12]; diff --git a/apps/irssi/src/silc/core/client_ops.h b/apps/irssi/src/silc/core/client_ops.h index 38ccf656..c231cddb 100644 --- a/apps/irssi/src/silc/core/client_ops.h +++ b/apps/irssi/src/silc/core/client_ops.h @@ -54,7 +54,6 @@ void silc_failure(SilcClient client, SilcClientConnection conn, SilcProtocol protocol, void *failure); int silc_key_agreement(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, char *hostname, - int port, - SilcKeyAgreementCallback *completion, + uint16 port, SilcKeyAgreementCallback *completion, void **context); #endif diff --git a/apps/irssi/src/silc/core/silc-nicklist.c b/apps/irssi/src/silc/core/silc-nicklist.c index 892cf457..2a517db2 100644 --- a/apps/irssi/src/silc/core/silc-nicklist.c +++ b/apps/irssi/src/silc/core/silc-nicklist.c @@ -53,6 +53,9 @@ SILC_NICK_REC *silc_nicklist_insert(SILC_CHANNEL_REC *channel, SILC_NICK_REC *silc_nicklist_find(SILC_CHANNEL_REC *channel, SilcClientEntry client) { + if (!client || !client->nickname) + return NULL; + return (SILC_NICK_REC *)nicklist_find_unique(CHANNEL(channel), client->nickname, client); } diff --git a/apps/silcd/command.c b/apps/silcd/command.c index fafd56b1..e45e75af 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3424,7 +3424,7 @@ SILC_SERVER_CMD_FUNC(motd) if (server->config && server->config->motd && server->config->motd->motd_file) { /* Send motd */ - motd = silc_file_read(server->config->motd->motd_file, &motd_len); + motd = silc_file_readfile(server->config->motd->motd_file, &motd_len); if (!motd) goto out; diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index b18da81a..d2e19b74 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -962,7 +962,7 @@ void silc_server_send_motd(SilcServer server, if (server->config && server->config->motd && server->config->motd->motd_file) { - motd = silc_file_read(server->config->motd->motd_file, &motd_len); + motd = silc_file_readfile(server->config->motd->motd_file, &motd_len); if (!motd) return; diff --git a/includes/clientlibincludes.h b/includes/clientlibincludes.h index 8e026002..959e13a8 100644 --- a/includes/clientlibincludes.h +++ b/includes/clientlibincludes.h @@ -30,6 +30,7 @@ #include "client.h" #include "command.h" #include "command_reply.h" +#include "client_ftp.h" #include "idlist.h" #include "protocol.h" #include "silcapi.h" diff --git a/lib/silcclient/Makefile.am b/lib/silcclient/Makefile.am index 43032ca3..b9b36334 100644 --- a/lib/silcclient/Makefile.am +++ b/lib/silcclient/Makefile.am @@ -26,6 +26,7 @@ libsilcclient_a_SOURCES = \ client_notify.c \ client_prvmsg.c \ client_channel.c \ + client_ftp.c \ command.c \ command_reply.c \ idlist.c \ diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index c7c17591..b8d98dbd 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -183,6 +183,7 @@ SilcClientConnection silc_client_add_connection(SilcClient client, conn->remote_port = port; conn->context = context; conn->pending_commands = silc_dlist_init(); + conn->ftp_sessions = silc_dlist_init(); /* Add the connection to connections table */ for (i = 0; i < client->conns_count; i++) @@ -207,9 +208,16 @@ void silc_client_del_connection(SilcClient client, SilcClientConnection conn) for (i = 0; i < client->conns_count; i++) if (client->conns[i] == conn) { + + silc_idcache_free(conn->client_cache); + silc_idcache_free(conn->channel_cache); + silc_idcache_free(conn->server_cache); if (conn->pending_commands) silc_dlist_uninit(conn->pending_commands); + silc_free(conn->remote_host); + silc_dlist_uninit(conn->ftp_sessions); silc_free(conn); + client->conns[i] = NULL; } } @@ -1720,31 +1728,3 @@ silc_client_request_authentication_method(SilcClient client, conn, client->params->connauth_request_secs, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } - -/* Called when file transfer packet is received. This will parse the - packet and give it to the file transfer protocol. */ - -void silc_client_ftp(SilcClient client, - SilcSocketConnection sock, - SilcPacketContext *packet) -{ - SilcClientConnection conn = (SilcClientConnection)sock->user_data; - uint8 type; - int ret; - - /* Parse the payload */ - ret = silc_buffer_unformat(packet->buffer, - SILC_STR_UI_CHAR(&type), - SILC_STR_END); - if (ret == -1) - return; - - /* We support only type number 1 (== SFTP) */ - if (type != 1) - return; - - silc_buffer_pull(packet->buffer, 1); - - /* Give it to the file transfer protocol processor. */ - //silc_sftp_client_receive_process(xxx, sock, packet); -} diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 2275194b..d8bee7ad 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -27,6 +27,7 @@ typedef struct SilcClientConnectionStruct *SilcClientConnection; typedef struct SilcClientPingStruct SilcClientPing; typedef struct SilcClientAwayStruct SilcClientAway; typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement; +typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession; #include "idlist.h" #include "command.h" @@ -135,6 +136,11 @@ struct SilcClientConnectionStruct { /* Authentication request context. */ SilcClientConnAuthRequest connauth; + /* File transmission sessions */ + SilcDList ftp_sessions; + uint32 next_session_id; + SilcClientFtpSession active_session; + /* Pointer back to the SilcClient. This object is passed to the application and the actual client object is accesible through this pointer. */ SilcClient client; diff --git a/lib/silcclient/client_keyagr.c b/lib/silcclient/client_keyagr.c index b23f6550..336ea5b7 100644 --- a/lib/silcclient/client_keyagr.c +++ b/lib/silcclient/client_keyagr.c @@ -357,7 +357,7 @@ void silc_client_send_key_agreement(SilcClient client, silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT, client_entry->id, SILC_ID_CLIENT, NULL, NULL, buffer->data, buffer->len, FALSE); - silc_free(buffer); + silc_buffer_free(buffer); } static int diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index 8e870e13..9141372c 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -311,7 +311,7 @@ void silc_client_get_clients_by_list(SilcClient client, if (entry) { if (entry->status & SILC_CLIENT_STATUS_RESOLVING) { - client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING; + entry->status &= ~SILC_CLIENT_STATUS_RESOLVING; silc_free(client_id); silc_buffer_pull(client_id_list, idp_len); continue; diff --git a/lib/silcclient/silcapi.h b/lib/silcclient/silcapi.h index c3725a9e..e7d7b9cc 100644 --- a/lib/silcclient/silcapi.h +++ b/lib/silcclient/silcapi.h @@ -344,10 +344,19 @@ typedef struct { silc_client_perform_key_agreement). If TRUE is returned also the `completion' and `context' arguments must be set by the application. */ int (*key_agreement)(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, char *hostname, - int port, - SilcKeyAgreementCallback *completion, + SilcClientEntry client_entry, const char *hostname, + uint16 port, SilcKeyAgreementCallback *completion, void **context); + + /* Notifies application that file transfer protocol session is being + requested by the remote client indicated by the `client_entry' from + the `hostname' and `port'. The `session_id' is the file transfer + session and it can be used to either accept or reject the file + transfer request, by calling the silc_client_file_receive or + silc_client_file_close, respectively. */ + void (*ftp)(SilcClient client, SilcClientConnection conn, + SilcClientEntry client_entry, uint32 session_id, + const char *hostname, uint16 port); } SilcClientOperations; /***/ @@ -1756,4 +1765,130 @@ silc_client_request_authentication_method(SilcClient client, SilcConnectionAuthRequest callback, void *context); +typedef enum { + SILC_CLIENT_FILE_MONITOR_SEND, + SILC_CLIENT_FILE_MONITOR_RECEIVE, + SILC_CLIENT_FILE_MONITOR_GET, + SILC_CLIENT_FILE_MONITOR_PUT, + SILC_CLIENT_FILE_MONITOR_CLOSE, +} SilcClientMonitorStatus; + +/****f* silcclient/SilcClientAPI/silc_client_file_receive + * + * SYNOPSIS + * + * typedef void (*SilcClientFileMonitor)(SilcClient client, + * SilcClientConnection conn, + * SilcClientMonitorStatus status, + * uint64 offset, + * uint64 filesize, + * SilcClientEntry client_entry, + * uint32 session_id, + * const char *filepath, + * void *context); + * + * DESCRIPTION + * + * Monitor callback that is called during the file transmission to + * monitor the transmission process. The `status' indicates the current + * monitoring process. The `offset' is the currently transmitted amount + * of total `filesize'. The `client_entry' indicates the remote client, + * and the transmission session ID is the `session_id'. The filename + * being transmitted is indicated by the `filepath'. + * + ***/ +typedef void (*SilcClientFileMonitor)(SilcClient client, + SilcClientConnection conn, + SilcClientMonitorStatus status, + uint64 offset, + uint64 filesize, + SilcClientEntry client_entry, + uint32 session_id, + const char *filepath, + void *context); + +/****f* silcclient/SilcClientAPI/silc_client_file_send + * + * SYNOPSIS + * + * void silc_client_file_send(SilcClient client, + * SilcClientConnection conn, + * SilcClientFileMonitor monitor, + * void *monitor_context, + * SilcClientEntry client_entry, + * const char *filepath); + * + * DESCRIPTION + * + * Sends a file indicated by the `filepath' to the remote client + * indicated by the `client_entry'. This will negotiate a secret key + * with the remote client before actually starting the transmission of + * the file. The `monitor' callback will be called to monitor the + * transmission of the file. + * + * This returns a file session ID for the file transmission. It can + * be used to close the session (and abort the file transmission) by + * calling the silc_client_file_close function. The session ID is + * also returned in the `monitor' callback. This returns 0 if the + * file indicated by the `filepath' is being transmitted to the remote + * client indicated by the `client_entry', already. + * + ***/ +uint32 silc_client_file_send(SilcClient client, + SilcClientConnection conn, + SilcClientFileMonitor monitor, + void *monitor_context, + SilcClientEntry client_entry, + const char *filepath); + +/****f* silcclient/SilcClientAPI/silc_client_file_receive + * + * SYNOPSIS + * + * bool silc_client_file_receive(SilcClient client, + * SilcClientConnection conn, + * SilcClientFileMonitor monitor, + * void *monitor_context, + * SilcClientEntry client_entry, + * uint32 session_id); + * + * DESCRIPTION + * + * Receives a file from a client indicated by the `client_entry'. The + * `session_id' indicates the file transmission session and it has been + * received in the `ftp' client operation function. This will actually + * perform the key agreement protocol with the remote client before + * actually starting the file transmission. The `monitor' callback + * will be called to monitor the transmission. + * + ***/ +bool silc_client_file_receive(SilcClient client, + SilcClientConnection conn, + SilcClientFileMonitor monitor, + void *monitor_context, + SilcClientEntry client_entry, + uint32 session_id); + +/****f* silcclient/SilcClientAPI/silc_client_file_close + * + * SYNOPSIS + * + * bool silc_client_file_close(SilcClient client, + * SilcClientConnection conn, + * uint32 session_id); + * + * DESCRIPTION + * + * Closes file transmission session indicated by the `session_id'. + * If file transmission is being conducted it will be aborted + * automatically. This function is also used to close the session + * after successful file transmission. This function can be used + * also to reject incoming file transmission request. Returns TRUE + * if the session was closed and FALSE if such session does not exist. + * + ***/ +bool silc_client_file_close(SilcClient client, + SilcClientConnection conn, + uint32 session_id); + #endif diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index cdf844d4..7674a030 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -442,6 +442,9 @@ static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer, /* Compare the HMAC's (buffer->tail has the packet's HMAC) */ if (memcmp(mac, buffer->tail, mac_len)) { SILC_LOG_ERROR(("MAC failed")); + + /* XXX Remove */ + assert(FALSE); return FALSE; } diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index d69ef230..fe0e1c65 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -882,7 +882,7 @@ static int silc_pkcs_save_public_key_internal(char *filename, SILC_STR_END); /* Save into file */ - if (silc_file_write(filename, buf->data, buf->len)) { + if (silc_file_writefile(filename, buf->data, buf->len)) { silc_buffer_free(buf); return FALSE; } @@ -945,7 +945,7 @@ static int silc_pkcs_save_private_key_internal(char *filename, SILC_STR_END); /* Save into a file */ - if (silc_file_write_mode(filename, buf->data, buf->len, 0600)) { + if (silc_file_writefile_mode(filename, buf->data, buf->len, 0600)) { silc_buffer_free(buf); return FALSE; } @@ -990,7 +990,7 @@ int silc_pkcs_load_public_key(char *filename, SilcPublicKey *public_key, unsigned char *cp, *old, *data, byte; uint32 i, data_len, len; - old = data = silc_file_read(filename, &data_len); + old = data = silc_file_readfile(filename, &data_len); if (!data) return FALSE; @@ -1043,7 +1043,7 @@ int silc_pkcs_load_private_key(char *filename, SilcPrivateKey *private_key, unsigned char *cp, *old, *data, byte; uint32 i, data_len, len; - old = data = silc_file_read(filename, &data_len); + old = data = silc_file_readfile(filename, &data_len); if (!data) return FALSE; diff --git a/lib/silcutil/silcconfig.c b/lib/silcutil/silcconfig.c index 56155372..19ae0b97 100644 --- a/lib/silcutil/silcconfig.c +++ b/lib/silcutil/silcconfig.c @@ -29,7 +29,7 @@ void silc_config_open(char *filename, SilcBuffer *ret_buffer) char *buffer; uint32 filelen; - buffer = silc_file_read(filename, &filelen); + buffer = silc_file_readfile(filename, &filelen); if (buffer == NULL) return; diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index 6bc8261b..9d1ab991 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -25,61 +25,42 @@ #include "silcincludes.h" -/* Reads a file to a buffer. The allocated buffer is returned. Length of - the file read is returned to the return_len argument. */ +/* Opens a file indicated by the filename `filename' with flags indicated + by the `flags'. */ -char *silc_file_read(const char *filename, uint32 *return_len) +int silc_file_open(const char *filename, int flags) { int fd; - char *buffer; - int filelen; - fd = open(filename, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) - return NULL; - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); - return NULL; - } + fd = open(filename, flags); - filelen = lseek(fd, (off_t)0L, SEEK_END); - if (filelen < 0) { - close(fd); - return NULL; - } - if (lseek(fd, (off_t)0L, SEEK_SET) < 0) { - close(fd); - return NULL; - } + return fd; +} - if (filelen < 0) { - SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); - close(fd); - return NULL; - } - - buffer = silc_calloc(filelen + 1, sizeof(char)); - - if ((read(fd, buffer, filelen)) == -1) { - memset(buffer, 0, sizeof(buffer)); - close(fd); - SILC_LOG_ERROR(("Cannot read from file %s: %s", filename, - strerror(errno))); - return NULL; - } +/* Reads data from file descriptor `fd' to `buf'. */ - close(fd); - buffer[filelen] = EOF; +int silc_file_read(int fd, unsigned char *buf, uint32 buf_len) +{ + return read(fd, (void *)buf, buf_len); +} - if (return_len) - *return_len = filelen; +/* Writes `buffer' of length of `len' to file descriptor `fd. */ - return buffer; +int silc_file_write(int fd, const char *buffer, uint32 len) +{ + return write(fd, (const void *)buffer, len); +} + +/* Closes file descriptor */ + +int silc_file_close(int fd) +{ + return close(fd); } /* Writes a buffer to the file. */ -int silc_file_write(const char *filename, const char *buffer, uint32 len) +int silc_file_writefile(const char *filename, const char *buffer, uint32 len) { int fd; @@ -103,8 +84,8 @@ int silc_file_write(const char *filename, const char *buffer, uint32 len) /* Writes a buffer to the file. If the file is created specific mode is set to the file. */ -int silc_file_write_mode(const char *filename, const char *buffer, - uint32 len, int mode) +int silc_file_writefile_mode(const char *filename, const char *buffer, + uint32 len, int mode) { int fd; @@ -125,6 +106,58 @@ int silc_file_write_mode(const char *filename, const char *buffer, return 0; } +/* Reads a file to a buffer. The allocated buffer is returned. Length of + the file read is returned to the return_len argument. */ + +char *silc_file_readfile(const char *filename, uint32 *return_len) +{ + int fd; + char *buffer; + int filelen; + + fd = silc_file_open(filename, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) + return NULL; + SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); + return NULL; + } + + filelen = lseek(fd, (off_t)0L, SEEK_END); + if (filelen < 0) { + close(fd); + return NULL; + } + if (lseek(fd, (off_t)0L, SEEK_SET) < 0) { + close(fd); + return NULL; + } + + if (filelen < 0) { + SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno))); + close(fd); + return NULL; + } + + buffer = silc_calloc(filelen + 1, sizeof(char)); + + if ((read(fd, buffer, filelen)) == -1) { + memset(buffer, 0, sizeof(buffer)); + close(fd); + SILC_LOG_ERROR(("Cannot read from file %s: %s", filename, + strerror(errno))); + return NULL; + } + + close(fd); + buffer[filelen] = EOF; + + if (return_len) + *return_len = filelen; + + return buffer; +} + /* Gets line from a buffer. Stops reading when a newline or EOF occurs. This doesn't remove the newline sign from the destination buffer. The argument begin is returned and should be passed again for the function. */ diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index 92742709..53226bbb 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -22,10 +22,14 @@ #define SILCUTIL_H /* Prototypes */ -char *silc_file_read(const char *filename, uint32 *return_len); -int silc_file_write(const char *filename, const char *buffer, uint32 len); -int silc_file_write_mode(const char *filename, const char *buffer, - uint32 len, int mode); +int silc_file_open(const char *filename, int flags); +int silc_file_read(int fd, unsigned char *buf, uint32 buf_len); +int silc_file_write(int fd, const char *buffer, uint32 len); +int silc_file_close(int fd); +char *silc_file_readfile(const char *filename, uint32 *return_len); +int silc_file_writefile(const char *filename, const char *buffer, uint32 len); +int silc_file_writefile_mode(const char *filename, const char *buffer, + uint32 len, int mode); int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin); int silc_check_line(char *buf); char *silc_get_time();