comparison svr-session.c @ 1653:76189c9ffea2

External Public-Key Authentication API (#72) * Implemented dynamic loading of an external plug-in shared library to delegate public key authentication * Moved conditional compilation of the plugin infrastructure into the configure.ac script to be able to add -ldl to dropbear build only when the flag is enabled * Added tags file to the ignore list * Updated API to have the constructor to return function pointers in the pliugin instance. Added support for passing user name to the checkpubkey function. Added options to the session returned by the plugin and have dropbear to parse and process them * Added -rdynamic to the linker flags when EPKA is enabled * Changed the API to pass a previously created session to the checkPubKey function (created during preauth) * Added documentation to the API * Added parameter addrstring to plugin creation function * Modified the API to retrieve the auth options. Instead of having them as field of the EPKASession struct, they are stored internally (plugin-dependent) in the plugin/session and retrieved through a pointer to a function (in the session) * Changed option string to be a simple char * instead of unsigned char *
author fabriziobertocci <fabriziobertocci@gmail.com>
date Wed, 15 May 2019 09:43:57 -0400
parents 92c93b4a3646
children cc0fc5131c5c
comparison
equal deleted inserted replaced
1652:d2753238f35f 1653:76189c9ffea2
86 86
87 m_free(svr_ses.addrstring); 87 m_free(svr_ses.addrstring);
88 m_free(svr_ses.remotehost); 88 m_free(svr_ses.remotehost);
89 m_free(svr_ses.childpids); 89 m_free(svr_ses.childpids);
90 svr_ses.childpidsize = 0; 90 svr_ses.childpidsize = 0;
91
92 #if DROPBEAR_EPKA
93 if (svr_ses.epka_plugin_handle != NULL) {
94 if (svr_ses.epka_instance) {
95 svr_ses.epka_instance->delete_plugin(svr_ses.epka_instance);
96 svr_ses.epka_instance = NULL;
97 }
98
99 dlclose(svr_ses.epka_plugin_handle);
100 svr_ses.epka_plugin_handle = NULL;
101 }
102 #endif
91 } 103 }
92 104
93 void svr_session(int sock, int childpipe) { 105 void svr_session(int sock, int childpipe) {
94 char *host, *port; 106 char *host, *port;
95 size_t len; 107 size_t len;
99 /* Initialise server specific parts of the session */ 111 /* Initialise server specific parts of the session */
100 svr_ses.childpipe = childpipe; 112 svr_ses.childpipe = childpipe;
101 #if DROPBEAR_VFORK 113 #if DROPBEAR_VFORK
102 svr_ses.server_pid = getpid(); 114 svr_ses.server_pid = getpid();
103 #endif 115 #endif
104 svr_authinitialise();
105 chaninitialise(svr_chantypes);
106 svr_chansessinitialise();
107 svr_algos_initialise();
108 116
109 /* for logging the remote address */ 117 /* for logging the remote address */
110 get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0); 118 get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);
111 len = strlen(host) + strlen(port) + 2; 119 len = strlen(host) + strlen(port) + 2;
112 svr_ses.addrstring = m_malloc(len); 120 svr_ses.addrstring = m_malloc(len);
113 snprintf(svr_ses.addrstring, len, "%s:%s", host, port); 121 snprintf(svr_ses.addrstring, len, "%s:%s", host, port);
114 m_free(host); 122 m_free(host);
115 m_free(port); 123 m_free(port);
116 124
125 #if DROPBEAR_EPKA
126 /* Initializes the EPKA Plugin */
127 svr_ses.epka_plugin_handle = NULL;
128 svr_ses.epka_instance = NULL;
129 if (svr_opts.pubkey_plugin) {
130 #if DEBUG_TRACE
131 const int verbose = debug_trace;
132 #else
133 const int verbose = 0;
134 #endif
135 PubkeyExtPlugin_newFn pluginConstructor;
136
137 /* RTLD_NOW: fails if not all the symbols are resolved now. Better fail now than at run-time */
138 svr_ses.epka_plugin_handle = dlopen(svr_opts.pubkey_plugin, RTLD_NOW);
139 if (svr_ses.epka_plugin_handle == NULL) {
140 dropbear_exit("failed to load external pubkey plugin '%s': %s", svr_opts.pubkey_plugin, dlerror());
141 }
142 pluginConstructor = (PubkeyExtPlugin_newFn)dlsym(svr_ses.epka_plugin_handle, DROPBEAR_PUBKEY_PLUGIN_FNNAME_NEW);
143 if (!pluginConstructor) {
144 dropbear_exit("plugin constructor method not found in external pubkey plugin");
145 }
146
147 /* Create an instance of the plugin */
148 svr_ses.epka_instance = pluginConstructor(verbose, svr_opts.pubkey_plugin_options, svr_ses.addrstring);
149 if (svr_ses.epka_instance == NULL) {
150 dropbear_exit("external plugin initialization failed");
151 }
152 /* Check if the plugin is compatible */
153 if ( (svr_ses.epka_instance->api_version[0] != DROPBEAR_EPKA_VERSION_MAJOR) ||
154 (svr_ses.epka_instance->api_version[1] < DROPBEAR_EPKA_VERSION_MINOR) ) {
155 dropbear_exit("plugin version check failed: "
156 "Dropbear=%d.%d, plugin=%d.%d",
157 DROPBEAR_EPKA_VERSION_MAJOR, DROPBEAR_EPKA_VERSION_MINOR,
158 svr_ses.epka_instance->api_version[0], svr_ses.epka_instance->api_version[1]);
159 }
160 if (svr_ses.epka_instance->api_version[1] > DROPBEAR_EPKA_VERSION_MINOR) {
161 dropbear_log(LOG_WARNING, "plugin API newer than dropbear API: "
162 "Dropbear=%d.%d, plugin=%d.%d",
163 DROPBEAR_EPKA_VERSION_MAJOR, DROPBEAR_EPKA_VERSION_MINOR,
164 svr_ses.epka_instance->api_version[0], svr_ses.epka_instance->api_version[1]);
165 }
166 dropbear_log(LOG_INFO, "successfully loaded and initialized pubkey plugin '%s'", svr_opts.pubkey_plugin);
167 }
168 #endif
169
170 svr_authinitialise();
171 chaninitialise(svr_chantypes);
172 svr_chansessinitialise();
173 svr_algos_initialise();
174
117 get_socket_address(ses.sock_in, NULL, NULL, 175 get_socket_address(ses.sock_in, NULL, NULL,
118 &svr_ses.remotehost, NULL, 1); 176 &svr_ses.remotehost, NULL, 1);
119 177
120 /* set up messages etc */ 178 /* set up messages etc */
121 ses.remoteclosed = svr_remoteclosed; 179 ses.remoteclosed = svr_remoteclosed;
148 /* failure exit - format must be <= 100 chars */ 206 /* failure exit - format must be <= 100 chars */
149 void svr_dropbear_exit(int exitcode, const char* format, va_list param) { 207 void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
150 char exitmsg[150]; 208 char exitmsg[150];
151 char fullmsg[300]; 209 char fullmsg[300];
152 int i; 210 int i;
211
212 #if DROPBEAR_EPKA
213 if ((ses.epka_session != NULL)) {
214 svr_ses.epka_instance->delete_session(ses.epka_session);
215 }
216 ses.epka_session = NULL;
217 #endif
153 218
154 /* Render the formatted exit message */ 219 /* Render the formatted exit message */
155 vsnprintf(exitmsg, sizeof(exitmsg), format, param); 220 vsnprintf(exitmsg, sizeof(exitmsg), format, param);
156 221
157 /* Add the prefix depending on session/auth state */ 222 /* Add the prefix depending on session/auth state */