/[LeafOK_CVS]/lbbs/src/net_server.c
ViewVC logotype

Diff of /lbbs/src/net_server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.53 by sysadm, Thu Jun 5 09:04:55 2025 UTC Revision 1.55 by sysadm, Sat Jun 7 01:51:54 2025 UTC
# Line 20  Line 20 
20    
21  #include "net_server.h"  #include "net_server.h"
22  #include "common.h"  #include "common.h"
23    #include "bbs_main.h"
24    #include "bbs.h"
25  #include "log.h"  #include "log.h"
26  #include "io.h"  #include "io.h"
27  #include "init.h"  #include "init.h"
 #include "fork.h"  
28  #include "menu.h"  #include "menu.h"
29    #include "database.h"
30    #include "login.h"
31  #include "file_loader.h"  #include "file_loader.h"
32  #include "section_list_loader.h"  #include "section_list_loader.h"
33  #include <errno.h>  #include <errno.h>
# Line 40  Line 43 
43  #include <arpa/inet.h>  #include <arpa/inet.h>
44  #include <netinet/in.h>  #include <netinet/in.h>
45  #include <systemd/sd-daemon.h>  #include <systemd/sd-daemon.h>
46    #include <libssh/libssh.h>
47    #include <libssh/server.h>
48    #include <libssh/callbacks.h>
49    
50  struct process_sockaddr_t  struct process_sockaddr_t
51  {  {
# Line 50  typedef struct process_sockaddr_t PROCES Line 56  typedef struct process_sockaddr_t PROCES
56    
57  static PROCESS_SOCKADDR process_sockaddr_pool[MAX_CLIENT_LIMIT];  static PROCESS_SOCKADDR process_sockaddr_pool[MAX_CLIENT_LIMIT];
58    
59    #define SSH_AUTH_MAX_DURATION 60 // seconds
60    
61    struct ssl_server_cb_data_t
62    {
63            int tries;
64            int error;
65    };
66    
67    static int auth_password(ssh_session session, const char *user,
68                                                     const char *password, void *userdata)
69    {
70            MYSQL *db;
71            struct ssl_server_cb_data_t *p_data = userdata;
72            int ret;
73    
74            if ((db = db_open()) == NULL)
75            {
76                    return SSH_AUTH_ERROR;
77            }
78    
79            if (strcmp(user, "guest") == 0)
80            {
81                    ret = load_guest_info(db);
82            }
83            else
84            {
85                    ret = check_user(db, user, password);
86            }
87    
88            mysql_close(db);
89    
90            if (ret == 0)
91            {
92                    return SSH_AUTH_SUCCESS;
93            }
94    
95            if ((++(p_data->tries)) >= BBS_login_retry_times)
96            {
97                    p_data->error = 1;
98            }
99    
100            return SSH_AUTH_DENIED;
101    }
102    
103    static int pty_request(ssh_session session, ssh_channel channel, const char *term,
104                                               int x, int y, int px, int py, void *userdata)
105    {
106            return 0;
107    }
108    
109    static int shell_request(ssh_session session, ssh_channel channel, void *userdata)
110    {
111            return 0;
112    }
113    
114    static struct ssh_channel_callbacks_struct channel_cb = {
115            .channel_pty_request_function = pty_request,
116            .channel_shell_request_function = shell_request};
117    
118    static ssh_channel new_session_channel(ssh_session session, void *userdata)
119    {
120            if (SSH_channel != NULL)
121            {
122                    return NULL;
123            }
124    
125            SSH_channel = ssh_channel_new(session);
126            ssh_callbacks_init(&channel_cb);
127            ssh_set_channel_callbacks(SSH_channel, &channel_cb);
128    
129            return SSH_channel;
130    }
131    
132    int fork_server(void)
133    {
134            ssh_event event;
135            int pid;
136            int i;
137            int ret;
138    
139            struct ssl_server_cb_data_t cb_data = {
140                    .tries = 0,
141                    .error = 0,
142            };
143    
144            struct ssh_server_callbacks_struct cb = {
145                    .userdata = &cb_data,
146                    .auth_password_function = auth_password,
147                    .channel_open_request_session_function = new_session_channel,
148            };
149    
150            pid = fork();
151    
152            if (pid > 0) // Parent process
153            {
154                    SYS_child_process_count++;
155                    log_common("Child process (%d) start\n", pid);
156                    return pid;
157            }
158            else if (pid < 0) // Error
159            {
160                    log_error("fork() error (%d)\n", errno);
161                    return -1;
162            }
163    
164            // Child process
165    
166            if (close(socket_server[0]) == -1 || close(socket_server[1]) == -1)
167            {
168                    log_error("Close server socket failed\n");
169            }
170    
171            SSH_session = ssh_new();
172    
173            if (SSH_v2)
174            {
175                    if (ssh_bind_accept_fd(sshbind, SSH_session, socket_client) != SSH_OK)
176                    {
177                            log_error("ssh_bind_accept_fd() error: %s\n", ssh_get_error(SSH_session));
178                            goto cleanup;
179                    }
180    
181                    ssh_bind_free(sshbind);
182    
183                    ssh_callbacks_init(&cb);
184                    ssh_set_server_callbacks(SSH_session, &cb);
185    
186                    if (ssh_handle_key_exchange(SSH_session))
187                    {
188                            log_error("ssh_handle_key_exchange() error: %s\n", ssh_get_error(SSH_session));
189                            goto cleanup;
190                    }
191                    ssh_set_auth_methods(SSH_session, SSH_AUTH_METHOD_PASSWORD);
192    
193                    event = ssh_event_new();
194                    ssh_event_add_session(event, SSH_session);
195    
196                    for (i = 0; i < SSH_AUTH_MAX_DURATION && !SYS_server_exit && !cb_data.error && SSH_channel == NULL; i++)
197                    {
198                            ret = ssh_event_dopoll(event, 1000); // 1 second
199                            if (ret == SSH_ERROR)
200                            {
201                                    log_error("ssh_event_dopoll() error: %s\n", ssh_get_error(SSH_session));
202                                    goto cleanup;
203                            }
204                    }
205    
206                    if (cb_data.error)
207                    {
208                            log_error("SSH auth error, tried %d times\n", cb_data.tries);
209                            goto cleanup;
210                    }
211            }
212    
213            // Redirect Input
214            close(STDIN_FILENO);
215            if (dup2(socket_client, STDIN_FILENO) == -1)
216            {
217                    log_error("Redirect stdin to client socket failed\n");
218                    goto cleanup;
219            }
220    
221            // Redirect Output
222            close(STDOUT_FILENO);
223            if (dup2(socket_client, STDOUT_FILENO) == -1)
224            {
225                    log_error("Redirect stdout to client socket failed\n");
226                    goto cleanup;
227            }
228    
229            SYS_child_process_count = 0;
230    
231            bbs_main();
232    
233    cleanup:
234            // Child process exit
235            SYS_server_exit = 1;
236    
237            if (SSH_v2)
238            {
239                    ssh_channel_free(SSH_channel);
240                    ssh_disconnect(SSH_session);
241            }
242            else if (close(socket_client) == -1)
243            {
244                    log_error("Close client socket failed\n");
245            }
246    
247            ssh_free(SSH_session);
248            ssh_finalize();
249    
250            // Close Input and Output for client
251            close(STDIN_FILENO);
252            close(STDOUT_FILENO);
253    
254            log_common("Process exit normally\n");
255            log_end();
256    
257            _exit(0);
258    
259            return 0;
260    }
261    
262  int net_server(const char *hostaddr, in_port_t port[])  int net_server(const char *hostaddr, in_port_t port[])
263  {  {
264          unsigned int addrlen;          unsigned int addrlen;
# Line 324  int net_server(const char *hostaddr, in_ Line 533  int net_server(const char *hostaddr, in_
533    
534                                          port_client = ntohs(sin.sin_port);                                          port_client = ntohs(sin.sin_port);
535    
536                                          log_common("Accept connection from %s:%d\n", hostaddr_client, port_client);                                          log_common("Accept %sconnection from %s:%d\n", (SSH_v2 ? "" : "SSH2 "), hostaddr_client, port_client);
537    
538                                          if (SYS_child_process_count - 1 < BBS_max_client)                                          if (SYS_child_process_count - 1 < BBS_max_client)
539                                          {                                          {


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1