From: Sergey Vlasov Date: Mon, 30 Apr 2001 14:58:37 +0000 (+0000) Subject: New NNTP authentication code. X-Git-Tag: disposition-notification~12 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=06c798281094162e805ad365d6c07480f5b9d17d New NNTP authentication code. --- diff --git a/ChangeLog.claws b/ChangeLog.claws index 79dff9d7c..2616eb759 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,6 +1,31 @@ 2001-04-30 [sergey] - * src/news.c: reverted my previous changes (need to to NNTP + * src/nntp.h (NNTPSockInfo): new type. + + * src/nntp.c: all functions updated to use NNTPSockInfo instead of + SockInfo. + (nntp_open_auth, nntp_close): new functions. + (nntp_gen_command): new function to handle authentication; all + NNTP command functions updated to use it. + (nntp_authinfo_user, nntp_authinfo_pass): deleted. + (nntp_list): removed old useless code. + + * src/news.h (NNTPSession): new field nntp_sock. + + * src/news.c: all functions updated to use NNTPSockInfo instead of + SockInfo. + (news_session_new): new arguments (userid, passwd); made static; + use nntp_open_auth() if needed. + (news_session_destroy): use nntp_close() instead of sock_close(). + (news_query_password): changed arguments. + (news_session_new_for_folder): new function. + (news_session_get): use news_session_new_for_folder(). + (news_authenticate): deleted. + (news_get_uncached_articles): removed old authentication code. + +2001-04-30 [sergey] + + * src/news.c: reverted my previous changes (need to do NNTP authentication in a cleaner way). 2001-04-29 [sergey] diff --git a/src/news.c b/src/news.c index db631d285..60f4a54e8 100644 --- a/src/news.c +++ b/src/news.c @@ -68,23 +68,29 @@ static GSList *news_delete_old_article (GSList *alist, static void news_delete_all_article (FolderItem *item); -Session *news_session_new(const gchar *server, gushort port) +static Session *news_session_new(const gchar *server, gushort port, + const gchar *userid, const gchar *passwd) { gchar buf[NNTPBUFSIZE]; NNTPSession *session; - SockInfo *nntp_sock; + NNTPSockInfo *nntp_sock; g_return_val_if_fail(server != NULL, NULL); log_message(_("creating NNTP connection to %s:%d ...\n"), server, port); - if ((nntp_sock = nntp_open(server, port, buf)) < 0) + if (userid && passwd) + nntp_sock = nntp_open_auth(server, port, buf, userid, passwd); + else + nntp_sock = nntp_open(server, port, buf); + if (nntp_sock < 0) return NULL; session = g_new(NNTPSession, 1); SESSION(session)->type = SESSION_NEWS; SESSION(session)->server = g_strdup(server); - SESSION(session)->sock = nntp_sock; + session->nntp_sock = nntp_sock; + SESSION(session)->sock = nntp_sock->sock; SESSION(session)->connected = TRUE; SESSION(session)->phase = SESSION_READY; SESSION(session)->data = NULL; @@ -95,31 +101,72 @@ Session *news_session_new(const gchar *server, gushort port) void news_session_destroy(NNTPSession *session) { - sock_close(SESSION(session)->sock); + nntp_close(session->nntp_sock); + session->nntp_sock = NULL; SESSION(session)->sock = NULL; g_free(session->group); } +static gchar *news_query_password(const gchar *server, + const gchar *user) +{ + gchar *message; + gchar *pass; + + message = g_strdup_printf(_("Input password for %s on %s:"), + user, server); + + pass = input_dialog_with_invisible(_("Input password"), + message, NULL); + g_free(message); +/* manage_window_focus_in(inc_dialog->mainwin->window, */ +/* NULL, NULL); */ + return pass; +} + +static Session *news_session_new_for_folder(Folder *folder) +{ + Session *session; + PrefsAccount *ac; + const gchar *userid; + gchar *passwd; + + ac = folder->account; + if (ac->userid && ac->userid[0]) { + userid = ac->userid; + if (ac->passwd && ac->passwd[0]) + passwd = g_strdup(ac->passwd); + else + passwd = news_query_password(ac->nntp_server, userid); + } else { + userid = passwd = NULL; + } + session = news_session_new(ac->nntp_server, 119, userid, passwd); + g_free(passwd); + return session; +} + NNTPSession *news_session_get(Folder *folder) { + NNTPSession *session; + g_return_val_if_fail(folder != NULL, NULL); g_return_val_if_fail(folder->type == F_NEWS, NULL); g_return_val_if_fail(folder->account != NULL, NULL); if (!REMOTE_FOLDER(folder)->session) { REMOTE_FOLDER(folder)->session = - news_session_new(folder->account->nntp_server, 119); + news_session_new_for_folder(folder); } else { - if (nntp_mode(REMOTE_FOLDER(folder)->session->sock, FALSE) - != NN_SUCCESS) { + session = NNTP_SESSION(REMOTE_FOLDER(folder)->session); + if (nntp_mode(session->nntp_sock, FALSE) != NN_SUCCESS) { log_warning(_("NNTP connection to %s:%d has been" " disconnected. Reconnecting...\n"), folder->account->nntp_server, 119); session_destroy(REMOTE_FOLDER(folder)->session); REMOTE_FOLDER(folder)->session = - news_session_new(folder->account->nntp_server, - 119); + news_session_new_for_folder(folder); } } @@ -228,7 +275,7 @@ gint news_post(Folder *folder, const gchar *file) return -1; } - ok = nntp_post(SESSION(session)->sock, fp); + ok = nntp_post(session->nntp_sock, fp); if (ok != NN_SUCCESS) { log_warning(_("can't post article.\n")); return -1; @@ -246,14 +293,14 @@ static gint news_get_article_cmd(NNTPSession *session, const gchar *cmd, { gchar *msgid; - if (nntp_get_article(SESSION(session)->sock, cmd, num, &msgid) + if (nntp_get_article(session->nntp_sock, cmd, num, &msgid) != NN_SUCCESS) return -1; debug_print("Message-Id = %s, num = %d\n", msgid, num); g_free(msgid); - if (recv_write_to_file(SESSION(session)->sock, filename) < 0) { + if (recv_write_to_file(session->nntp_sock->sock, filename) < 0) { log_warning(_("can't retrieve article %d\n"), num); return -1; } @@ -271,58 +318,6 @@ static gint news_get_header(NNTPSession *session, gint num, gchar *filename) return news_get_article_cmd(session, "HEAD", num, filename); } -static gchar *news_query_password(NNTPSession *session, - const gchar *user) -{ - gchar *message; - gchar *pass; - - message = g_strdup_printf - (_("Input password for %s on %s:"), - user, - SESSION(session)->server); - - pass = input_dialog_with_invisible(_("Input password"), - message, NULL); - g_free(message); -/* manage_window_focus_in(inc_dialog->mainwin->window, */ -/* NULL, NULL); */ - return pass; -} - -static gint news_authenticate(NNTPSession *session, - FolderItem *item) -{ - gint ok; - const gchar *user; - gchar *pass; - gboolean need_free_pass = FALSE; - - debug_print(_("news server requested authentication\n")); - if (!item || !item->folder || !item->folder->account) - return NN_ERROR; - user = item->folder->account->userid; - if (!user) - return NN_ERROR; - ok = nntp_authinfo_user(SESSION(session)->sock, user); - if (ok == NN_AUTHCONT) { - pass = item->folder->account->passwd; - if (!pass || !pass[0]) { - pass = news_query_password(session, user); - need_free_pass = TRUE; - } - ok = nntp_authinfo_pass(SESSION(session)->sock, pass); - if (need_free_pass) - g_free(pass); - } - if (ok != NN_SUCCESS) { - log_warning(_("NNTP authentication failed\n")); - alertpanel_error(_("Authentication for %s on %s failed."), - user, SESSION(session)->server); - } - return ok; -} - static GSList *news_get_uncached_articles(NNTPSession *session, FolderItem *item, gint cache_last, gint *rfirst, gint *rlast) @@ -342,15 +337,8 @@ static GSList *news_get_uncached_articles(NNTPSession *session, g_return_val_if_fail(item->folder != NULL, NULL); g_return_val_if_fail(item->folder->type == F_NEWS, NULL); - ok = nntp_group(SESSION(session)->sock, item->path, + ok = nntp_group(session->nntp_sock, item->path, &num, &first, &last); - if (ok == NN_AUTHREQ) { - ok = news_authenticate(session, item); - if (ok != NN_SUCCESS) - return NULL; - ok = nntp_group(SESSION(session)->sock, item->path, - &num, &first, &last); - } if (ok != NN_SUCCESS) { log_warning(_("can't set group: %s\n"), item->path); return NULL; @@ -379,7 +367,7 @@ static GSList *news_get_uncached_articles(NNTPSession *session, log_message(_("getting xover %d - %d in %s...\n"), begin, end, item->path); - if (nntp_xover(SESSION(session)->sock, begin, end) != NN_SUCCESS) { + if (nntp_xover(session->nntp_sock, begin, end) != NN_SUCCESS) { log_warning(_("can't get xover\n")); return NULL; } @@ -586,7 +574,7 @@ GSList * news_get_group_list(FolderItem *item) debug_print(_("group list has been already cached.\n")); } else { - ok = nntp_list(SESSION(session)->sock); + ok = nntp_list(session->nntp_sock); if (ok != NN_SUCCESS) return NULL; diff --git a/src/news.h b/src/news.h index 0ea354760..8e9518066 100644 --- a/src/news.h +++ b/src/news.h @@ -24,6 +24,7 @@ #include "folder.h" #include "session.h" +#include "nntp.h" typedef struct _NNTPSession NNTPSession; @@ -33,12 +34,11 @@ struct _NNTPSession { Session session; + NNTPSockInfo *nntp_sock; gchar *group; }; -Session *news_session_new (const gchar *server, - gushort port); void news_session_destroy (NNTPSession *session); NNTPSession *news_session_get (Folder *folder); diff --git a/src/nntp.c b/src/nntp.c index 1dbca2197..c1b5162a1 100644 --- a/src/nntp.c +++ b/src/nntp.c @@ -32,37 +32,69 @@ static gint verbose = 1; -static void nntp_gen_send(SockInfo *sock, const gchar *format, ...); -static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size); +static void nntp_gen_send(NNTPSockInfo *sock, const gchar *format, ...); +static gint nntp_gen_recv(NNTPSockInfo *sock, gchar *buf, gint size); +static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf, + const gchar *format, ...); -SockInfo *nntp_open(const gchar *server, gushort port, gchar *buf) +NNTPSockInfo *nntp_open(const gchar *server, gushort port, gchar *buf) { SockInfo *sock; + NNTPSockInfo *nntp_sock; + nntp_sock = g_new0(NNTPSockInfo, 1); if ((sock = sock_connect(server, port)) == NULL) { log_warning(_("Can't connect to NNTP server: %s:%d\n"), server, port); + g_free(nntp_sock); return NULL; } + nntp_sock->sock = sock; - if (nntp_ok(sock, buf) == NN_SUCCESS) - return sock; + if (nntp_ok(nntp_sock, buf) == NN_SUCCESS) + return nntp_sock; else { sock_close(sock); + g_free(nntp_sock); return NULL; } } -gint nntp_group(SockInfo *sock, const gchar *group, +NNTPSockInfo *nntp_open_auth(const gchar *server, gushort port, gchar *buf, + const gchar *userid, const gchar *passwd) +{ + NNTPSockInfo *sock; + + sock = nntp_open(server, port, buf); + if (!sock) + return NULL; + sock->userid = g_strdup(userid); + sock->passwd = g_strdup(passwd); + return sock; +} + + +void nntp_close(NNTPSockInfo *sock) +{ + if (!sock) + return; + + sock_close(sock->sock); + g_free(sock->passwd); + g_free(sock->userid); + g_free(sock); +} + +gint nntp_group(NNTPSockInfo *sock, const gchar *group, gint *num, gint *first, gint *last) { gint ok; gint resp; gchar buf[NNTPBUFSIZE]; - nntp_gen_send(sock, "GROUP %s", group); + ok = nntp_gen_command(sock, buf, "GROUP %s", group); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) + if (ok != NN_SUCCESS) return ok; if (sscanf(buf, "%d %d %d %d", &resp, num, first, last) @@ -74,17 +106,17 @@ gint nntp_group(SockInfo *sock, const gchar *group, return NN_SUCCESS; } -gint nntp_get_article(SockInfo *sock, const gchar *cmd, gint num, gchar **msgid) +gint nntp_get_article(NNTPSockInfo *sock, const gchar *cmd, gint num, gchar **msgid) { gint ok; gchar buf[NNTPBUFSIZE]; if (num > 0) - nntp_gen_send(sock, "%s %d", cmd, num); + ok = nntp_gen_command(sock, buf, "%s %d", cmd, num); else - nntp_gen_send(sock, cmd); + ok = nntp_gen_command(sock, buf, cmd); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) + if (ok != NN_SUCCESS) return ok; extract_parenthesis(buf, '<', '>'); @@ -97,35 +129,35 @@ gint nntp_get_article(SockInfo *sock, const gchar *cmd, gint num, gchar **msgid) return NN_SUCCESS; } -gint nntp_article(SockInfo *sock, gint num, gchar **msgid) +gint nntp_article(NNTPSockInfo *sock, gint num, gchar **msgid) { return nntp_get_article(sock, "ARTICLE", num, msgid); } -gint nntp_body(SockInfo *sock, gint num, gchar **msgid) +gint nntp_body(NNTPSockInfo *sock, gint num, gchar **msgid) { return nntp_get_article(sock, "BODY", num, msgid); } -gint nntp_head(SockInfo *sock, gint num, gchar **msgid) +gint nntp_head(NNTPSockInfo *sock, gint num, gchar **msgid) { return nntp_get_article(sock, "HEAD", num, msgid); } -gint nntp_stat(SockInfo *sock, gint num, gchar **msgid) +gint nntp_stat(NNTPSockInfo *sock, gint num, gchar **msgid) { return nntp_get_article(sock, "STAT", num, msgid); } -gint nntp_next(SockInfo *sock, gint *num, gchar **msgid) +gint nntp_next(NNTPSockInfo *sock, gint *num, gchar **msgid) { gint ok; gint resp; gchar buf[NNTPBUFSIZE]; - nntp_gen_send(sock, "NEXT"); + ok = nntp_gen_command(sock, buf, "NEXT"); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) + if (ok != NN_SUCCESS) return ok; if (sscanf(buf, "%d %d", &resp, num) != 2) { @@ -143,92 +175,70 @@ gint nntp_next(SockInfo *sock, gint *num, gchar **msgid) return NN_SUCCESS; } -gint nntp_xover(SockInfo *sock, gint first, gint last) +gint nntp_xover(NNTPSockInfo *sock, gint first, gint last) { gint ok; gchar buf[NNTPBUFSIZE]; - nntp_gen_send(sock, "XOVER %d-%d", first, last); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) + ok = nntp_gen_command(sock, buf, "XOVER %d-%d", first, last); + if (ok != NN_SUCCESS) return ok; return NN_SUCCESS; } -gint nntp_post(SockInfo *sock, FILE *fp) +gint nntp_post(NNTPSockInfo *sock, FILE *fp) { gint ok; gchar buf[NNTPBUFSIZE]; - nntp_gen_send(sock, "POST"); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) + ok = nntp_gen_command(sock, buf, "POST"); + if (ok != NN_SUCCESS) return ok; while (fgets(buf, sizeof(buf), fp) != NULL) { strretchomp(buf); if (buf[0] == '.') { - if (sock_write(sock, ".", 1) < 0) { + if (sock_write(sock->sock, ".", 1) < 0) { log_warning(_("Error occurred while posting\n")); return NN_SOCKET; } } - if (sock_puts(sock, buf) < 0) { + if (sock_puts(sock->sock, buf) < 0) { log_warning(_("Error occurred while posting\n")); return NN_SOCKET; } } - sock_write(sock, ".\r\n", 3); + sock_write(sock->sock, ".\r\n", 3); if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) return ok; return NN_SUCCESS; } -gint nntp_newgroups(SockInfo *sock) +gint nntp_newgroups(NNTPSockInfo *sock) { return NN_SUCCESS; } -gint nntp_newnews(SockInfo *sock) +gint nntp_newnews(NNTPSockInfo *sock) { return NN_SUCCESS; } -gint nntp_mode(SockInfo *sock, gboolean stream) +gint nntp_mode(NNTPSockInfo *sock, gboolean stream) { gint ok; - nntp_gen_send(sock, "MODE %s", stream ? "STREAM" : "READER"); - ok = nntp_ok(sock, NULL); + ok = nntp_gen_command(sock, NULL, "MODE %s", + stream ? "STREAM" : "READER"); return ok; } -gint nntp_authinfo_user(SockInfo *sock, const gchar *user) -{ - gint ok; - gchar buf[NNTPBUFSIZE]; - - nntp_gen_send(sock, "AUTHINFO USER %s", user); - ok = nntp_ok(sock, buf); - - return ok; -} - -gint nntp_authinfo_pass(SockInfo *sock, const gchar *pass) -{ - gint ok; - gchar buf[NNTPBUFSIZE]; - - nntp_gen_send(sock, "AUTHINFO PASS %s", pass); - ok = nntp_ok(sock, buf); - - return ok; -} - -gint nntp_ok(SockInfo *sock, gchar *argbuf) +gint nntp_ok(NNTPSockInfo *sock, gchar *argbuf) { gint ok; gchar buf[NNTPBUFSIZE]; @@ -254,7 +264,7 @@ gint nntp_ok(SockInfo *sock, gchar *argbuf) return ok; } -static void nntp_gen_send(SockInfo *sock, const gchar *format, ...) +static void nntp_gen_send(NNTPSockInfo *sock, const gchar *format, ...) { gchar buf[NNTPBUFSIZE]; va_list args; @@ -271,12 +281,12 @@ static void nntp_gen_send(SockInfo *sock, const gchar *format, ...) } strcat(buf, "\r\n"); - sock_write(sock, buf, strlen(buf)); + sock_write(sock->sock, buf, strlen(buf)); } -static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size) +static gint nntp_gen_recv(NNTPSockInfo *sock, gchar *buf, gint size) { - if (sock_read(sock, buf, size) == -1) + if (sock_read(sock->sock, buf, size) == -1) return NN_SOCKET; strretchomp(buf); @@ -287,26 +297,40 @@ static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size) return NN_SUCCESS; } -/* - nntp_list sends the command "LIST" to the news server, - a function is needed to read the newsgroups list. - */ - -gint nntp_list(SockInfo *sock) +static gint nntp_gen_command(NNTPSockInfo *sock, gchar *argbuf, + const gchar *format, ...) { - GList * result = NULL; - - gint ok; - gint resp; gchar buf[NNTPBUFSIZE]; + va_list args; + gint ok; - nntp_gen_send(sock, "LIST"); + va_start(args, format); + g_vsnprintf(buf, sizeof(buf) - 2, format, args); + va_end(args); - if ((ok = nntp_ok(sock, buf)) != NN_SUCCESS) - return ok; + nntp_gen_send(sock, "%s", buf); + ok = nntp_ok(sock, argbuf); + if (ok == NN_AUTHREQ && sock->userid && sock->passwd) { + nntp_gen_send(sock, "AUTHINFO USER %s", sock->userid); + ok = nntp_ok(sock, NULL); + if (ok == NN_AUTHCONT) { + nntp_gen_send(sock, "AUTHINFO PASS %s", sock->passwd); + ok = nntp_ok(sock, NULL); + } + if (ok != NN_SUCCESS) + return ok; + nntp_gen_send(sock, "%s", buf); + ok = nntp_ok(sock, argbuf); + } + return ok; +} - if (verbose) - log_print("NNTP< %s\n", buf); +/* + nntp_list sends the command "LIST" to the news server, + a function is needed to read the newsgroups list. + */ - return NN_SUCCESS; +gint nntp_list(NNTPSockInfo *sock) +{ + return nntp_gen_command(sock, NULL, "LIST"); } diff --git a/src/nntp.h b/src/nntp.h index 941da3d64..db05a2273 100644 --- a/src/nntp.h +++ b/src/nntp.h @@ -22,6 +22,8 @@ #include "socket.h" +typedef struct _NNTPSockInfo NNTPSockInfo; + #define NN_SUCCESS 0 #define NN_SOCKET 2 #define NN_AUTHFAIL 3 @@ -30,27 +32,35 @@ #define NN_IOERR 6 #define NN_ERROR 7 #define NN_AUTHREQ 8 -#define NN_AUTHCONT 9 +#define NN_AUTHCONT 9 #define NNTPBUFSIZE 8192 -SockInfo *nntp_open(const gchar *server, gushort port, gchar *buf); -gint nntp_group(SockInfo *sock, const gchar *group, +struct _NNTPSockInfo +{ + SockInfo *sock; + gchar *userid; + gchar *passwd; +}; + +NNTPSockInfo *nntp_open(const gchar *server, gushort port, gchar *buf); +NNTPSockInfo *nntp_open_auth(const gchar *server, gushort port, gchar *buf, + const gchar *userid, const gchar *passwd); +void nntp_close(NNTPSockInfo *sock); +gint nntp_group(NNTPSockInfo *sock, const gchar *group, gint *num, gint *first, gint *last); -gint nntp_get_article(SockInfo *sock, const gchar *cmd, gint num, gchar **msgid); -gint nntp_article(SockInfo *sock, gint num, gchar **msgid); -gint nntp_body(SockInfo *sock, gint num, gchar **msgid); -gint nntp_head(SockInfo *sock, gint num, gchar **msgid); -gint nntp_stat(SockInfo *sock, gint num, gchar **msgid); -gint nntp_next(SockInfo *sock, gint *num, gchar **msgid); -gint nntp_xover(SockInfo *sock, gint first, gint last); -gint nntp_post(SockInfo *sock, FILE *fp); -gint nntp_newgroups(SockInfo *sock); -gint nntp_newnews(SockInfo *sock); -gint nntp_mode(SockInfo *sock, gboolean stream); -gint nntp_ok(SockInfo *sock, gchar *argbuf); -gint nntp_authinfo_user(SockInfo *sock, const gchar *user); -gint nntp_authinfo_pass(SockInfo *sock, const gchar *pass); -gint nntp_list(SockInfo *sock); +gint nntp_get_article(NNTPSockInfo *sock, const gchar *cmd, gint num, gchar **msgid); +gint nntp_article(NNTPSockInfo *sock, gint num, gchar **msgid); +gint nntp_body(NNTPSockInfo *sock, gint num, gchar **msgid); +gint nntp_head(NNTPSockInfo *sock, gint num, gchar **msgid); +gint nntp_stat(NNTPSockInfo *sock, gint num, gchar **msgid); +gint nntp_next(NNTPSockInfo *sock, gint *num, gchar **msgid); +gint nntp_xover(NNTPSockInfo *sock, gint first, gint last); +gint nntp_post(NNTPSockInfo *sock, FILE *fp); +gint nntp_newgroups(NNTPSockInfo *sock); +gint nntp_newnews(NNTPSockInfo *sock); +gint nntp_mode(NNTPSockInfo *sock, gboolean stream); +gint nntp_ok(NNTPSockInfo *sock, gchar *argbuf); +gint nntp_list(NNTPSockInfo *sock); #endif /* __NNTP_H__ */