]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - client_common.c
Revert "Makefile: Fix compilation after header removal."
[paraslash.git] / client_common.c
index dc24a6280acc068bd2cb7cbc0fb178bd8586ca54..f8ee80c9d7a01956769284eaa117f1606c59cd76 100644 (file)
@@ -50,13 +50,12 @@ void client_close(struct client_task *ct)
 }
 
 /*
- * The preselect hook for server commands.
+ * This function asks the scheduler to monitor a file descriptor which
+ * corresponds to an active connection. The descriptor is monitored for either
+ * reading or writing, depending on the state of the connection.
  *
- * The task pointer must contain a pointer to the initialized client data
- * structure as it is returned by client_open().
- *
- * This function checks the state of the connection and adds the file descriptor
- * of the connection to the read or write fd set of s accordingly.
+ * The context pointer is assumed to refer to a client task structure that was
+ * initialized earlier by client_open().
  */
 static void client_pre_select(struct sched *s, void *context)
 {
@@ -259,13 +258,21 @@ static int send_sb_command(struct client_task *ct)
        return send_sb(ct, 0, command, len, SBD_COMMAND, false);
 }
 
+static bool has_feature(const char *feature, struct client_task *ct)
+{
+       return find_arg(feature, ct->features) >= 0? true : false;
+}
+
 /*
- * The post select hook for client commands.
+ * This function reads or writes to the socket file descriptor which
+ * corresponds to an established connection between the client and the server.
+ * It depends on the current state of the connection and on the readiness of
+ * the socket file descriptor which type of I/O is going to be performed.
+ * Besides the initial handshake and authentication, the function sends the
+ * server command and receives the output from the server, if any.
  *
- * Depending on the current state of the connection and the status of the read
- * and write fd sets of s, this function performs the necessary steps to
- * authenticate the connection, to send the command given by t->private_data
- * and to receive para_server's output, if any.
+ * The context pointer refers to a client task structure that was initialized
+ * earlier by client_open().
  */
 static int client_post_select(struct sched *s, void *context)
 {
@@ -288,16 +295,25 @@ static int client_post_select(struct sched *s, void *context)
                ct->status = CL_RECEIVED_WELCOME;
                return 0;
        case CL_RECEIVED_WELCOME: /* send auth command */
+               {
+               /*
+                * Use sha256 iff the server announced the feature. After 0.7.0
+                * we may request and use the feature unconditionally. After
+                * 0.8.0 we no longer need to request the feature.
+                */
+               bool has_sha256;
                if (!FD_ISSET(ct->scc.fd, &s->wfds))
                        return 0;
-               sprintf(buf, AUTH_REQUEST_MSG "%s sideband,aes_ctr128",
-                       ct->user);
+               has_sha256 = has_feature("sha256", ct);
+               sprintf(buf, AUTH_REQUEST_MSG "%s%s", ct->user, has_sha256?
+                       " sha256" : "");
                PARA_INFO_LOG("--> %s\n", buf);
                ret = write_buffer(ct->scc.fd, buf);
                if (ret < 0)
                        goto out;
                ct->status = CL_SENT_AUTH;
                return 0;
+               }
        case CL_SENT_AUTH:
                /*
                 * Receive challenge and session keys, decrypt the challenge and
@@ -323,19 +339,29 @@ static int client_post_select(struct sched *s, void *context)
                free(sbb.iov.iov_base);
                if (ret < 0)
                        goto out;
-               ct->challenge_hash = para_malloc(HASH_SIZE);
-               hash_function((char *)crypt_buf, APC_CHALLENGE_SIZE, ct->challenge_hash);
+               ct->challenge_hash = para_malloc(HASH2_SIZE);
+
+               if (has_feature("sha256", ct)) {
+                       hash2_function((char *)crypt_buf, APC_CHALLENGE_SIZE, ct->challenge_hash);
+                       hash2_to_asc(ct->challenge_hash, buf);
+               } else {
+                       hash_function((char *)crypt_buf, APC_CHALLENGE_SIZE, ct->challenge_hash);
+                       hash_to_asc(ct->challenge_hash, buf);
+               }
                ct->scc.send = sc_new(crypt_buf + APC_CHALLENGE_SIZE, SESSION_KEY_LEN);
                ct->scc.recv = sc_new(crypt_buf + APC_CHALLENGE_SIZE + SESSION_KEY_LEN,
                        SESSION_KEY_LEN);
-               hash_to_asc(ct->challenge_hash, buf);
                PARA_INFO_LOG("--> %s\n", buf);
                ct->status = CL_RECEIVED_CHALLENGE;
                return 0;
                }
        case CL_RECEIVED_CHALLENGE:
-               ret = send_sb(ct, 0, ct->challenge_hash, HASH_SIZE,
-                       SBD_CHALLENGE_RESPONSE, false);
+               if (has_feature("sha256", ct))
+                       ret = send_sb(ct, 0, ct->challenge_hash, HASH2_SIZE,
+                               SBD_CHALLENGE_RESPONSE, false);
+               else
+                       ret = send_sb(ct, 0, ct->challenge_hash, HASH_SIZE,
+                               SBD_CHALLENGE_RESPONSE, false);
                if (ret != 0)
                        ct->challenge_hash = NULL;
                if (ret <= 0)
@@ -426,8 +452,7 @@ out:
                return 0;
        btr_remove_node(&ct->btrn[0]);
        btr_remove_node(&ct->btrn[1]);
-       if (ret != -E_SERVER_CMD_SUCCESS && ret != -E_SERVER_CMD_FAILURE)
-               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
+       PARA_NOTICE_LOG("closing connection (%s)\n", para_strerror(-ret));
        if (ct->scc.fd >= 0) {
                close(ct->scc.fd);
                ct->scc.fd = -1;